DEV Community

SnippFlow
SnippFlow

Posted on • Edited on • Originally published at snippflow.com

1

Flexbox button with 3 styles and variations

The button, styled using CSS Flexbox, includes primary, secondary, and tertiary styles, all structured within nested CSS for clarity and maintainability, with variations such as:

  • with text
  • with text and icon (left / right / left & right)
  • with only icon
  • with status
  • for full-width
  • for disabled type

Image description

HTML code:

<a href="#" class="sf-button is-primary">Link</a>
<input class="sf-button is-primary" type="submit" value="Submit">
<button class="sf-button is-primary">Button</button>

<h4>Primary</h4>

<a href="#" class="sf-button is-primary">Button text</a>
<a href="#" class="sf-button is-primary"><i class="fa-regular fa-file"></i>Button text</a>
<a href="#" class="sf-button is-primary">Button text<i class="fa-solid fa-angle-right"></i></a>
<a href="#" class="sf-button is-primary"><i class="fa-solid fa-grip"></i>Button text<i class="fa-solid fa-arrow-right"></i></a>
<a href="#" class="sf-button is-primary has-only-icon"><i class="fa-solid fa-grip"></i></a>

<h4>Secondary</h4>

<a href="#" class="sf-button is-secondary">Button text</a>
<a href="#" class="sf-button is-secondary"><i class="fa-regular fa-file"></i>Button text</a>
<a href="#" class="sf-button is-secondary">Button text<i class="fa-solid fa-angle-right"></i></a>
<a href="#" class="sf-button is-secondary"><i class="fa-solid fa-grip"></i>Button text<i class="fa-solid fa-arrow-right"></i></a>
<a href="#" class="sf-button is-secondary has-only-icon"><i class="fa-solid fa-grip"></i></a>

<h4>Tertiary</h4>

<a href="#" class="sf-button is-tertiary">Button text</a>
<a href="#" class="sf-button is-tertiary"><i class="fa-regular fa-file"></i>Button text</a>
<a href="#" class="sf-button is-tertiary">Button text<i class="fa-solid fa-angle-right"></i></a>
<a href="#" class="sf-button is-tertiary"><i class="fa-solid fa-grip"></i>Button text<i class="fa-solid fa-arrow-right"></i></a>
<a href="#" class="sf-button is-tertiary has-only-icon"><i class="fa-solid fa-grip"></i></a>

<h3>Width modifier</h3>
<a href="#" class="sf-button is-fit is-primary"><i class="fa-solid fa-grip"></i>Categories</a>
<a href="#" class="sf-button is-fit is-secondary"><i class="fa-solid fa-grip"></i>Categories</a>
<a href="#" class="sf-button is-fit is-tertiary"><i class="fa-solid fa-grip"></i>Categories</a>

<h3>Disabled</h3>
<a href="#" class="sf-button is-primary disabled"><i class="fa-solid fa-grip"></i>Button text</a>
<a href="#" class="sf-button is-secondary disabled"><i class="fa-solid fa-grip"></i>Button text</a>
<a href="#" class="sf-button is-tertiary disabled"><i class="fa-solid fa-grip"></i>Button text</a>

<h3>Status</h3>
<a href="#" class="sf-button is-primary has-only-icon has-status"><i class="fa-solid fa-gear"></i></a>
<a href="#" class="sf-button is-secondary has-only-icon has-status"><i class="fa-solid fa-grip"></i></a>
<a href="#" class="sf-button is-tertiary has-only-icon has-status"><i class="fa-solid fa-grip"></i></a>
Enter fullscreen mode Exit fullscreen mode

CSS code:

/* ---------------------------------------------------------- */
/*                     Snippflow Button                       */
/* ---------------------------------------------------------- */

.sf-button {
    --sf-button-gap: 8px;
    --sf-button-padding-top: 12px;
    --sf-button-padding-bottom: 12px;
    --sf-button-padding-left: 16px;
    --sf-button-padding-right: 16px;
    --sf-button-border-radius: 8px;
    --sf-button-box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);

    --sf-button-primary-color: #fff;
    --sf-button-primary-bg: #46a787;
    --sf-button-primary-border: #3f9b7d;
    --sf-button-primary-hover-color: #fff;
    --sf-button-primary-hover-bg: #3c9376;
    --sf-button-primary-hover-border: #378c70;

    --sf-button-secondary-color: #121924;
    --sf-button-secondary-bg: #F8F8F9;
    --sf-button-secondary-border: #cbd5e1;
    --sf-button-secondary-hover-color: #121924;
    --sf-button-secondary-hover-bg: #fff;
    --sf-button-secondary-hover-border: #cbd5e1;

    --sf-button-tertiary-color: #121924;
    --sf-button-tertiary-bg: transparent;
    --sf-button-tertiary-border: transparent;
    --sf-button-tertiary-hover-color: #121924;
    --sf-button-tertiary-hover-bg: #e0e5ea;
    --sf-button-tertiary-hover-border: transparent;

    --sf-button-tertiary-status: #c82020;
}

a.sf-button,
input[type="submit"].sf-button,
input[type="reset"].sf-button,
input[type="button"].sf-button,
button.sf-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sf-button-gap);
    position: relative;
    box-sizing: border-box;
    font-size: inherit;
    font-weight: 500;
    line-height: 1;
    padding: var(--sf-button-padding-top) var(--sf-button-padding-right) var(--sf-button-padding-bottom) var(--sf-button-padding-left);
    border: 1px solid;
    border-radius: var(--sf-button-border-radius);
    white-space: nowrap;
    outline: unset;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.3s ease-in-out;

    &[aria-expanded="true"],
    &:hover {
        text-decoration: none;
    }

    /* Is fit  (100%)*/
    &.is-fit {
        width: 100%;
    }

    /* + Is fit margin */
    & + .is-fit {
        margin-top: 10px; /* btn under other is-fit btm */
    }

    /* Has status */
    &.has-status {
        :after {
            content: "";
            display: block;
            width: 8px;
            height: 8px;
            border-radius: 100%;
            background-color: var(--sf-button-tertiary-status);
            position: absolute;
            right: 5px;
            top: 5px;
            animation: sp-status-pulse 1s infinite ease-in-out alternate;
        }
    }

    /* Is disabled */
    &.disabled,
    &:disabled,
    &[aria-disabled="true"] {
        cursor: default;
        filter: saturate(0%);
        opacity: .7;
        background: transparent;
        transform: none;
        box-shadow: none;
        outline: none;

        &:hover {
            color: initial;
            pointer-events: none;
        }
    }

    /*  Icon */
     & > i {
        min-width: 18px;
        font-style: normal;
        text-align: center;
    }

    /* Has only icon */
    &.has-only-icon {
        padding: var(--sf-button-padding-top);
    }

    /* Primary button */
    &.is-primary {
        color: var(--sf-button-primary-color);
        background-color: var(--sf-button-primary-bg);
        border-color: var(--sf-button-primary-border);
        box-shadow: var(--sf-button-box-shadow);

        &:hover:not(:disabled) {
            color: var(--sf-button-primary-color);
            background-color: var(--sf-button-primary-hover-bg);
            border-color: var(--sf-button-primary-hover-border);
        }
    }

    /* Secondary button */
    &.is-secondary {
        color: var(--sf-button-secondary-color);
        background-color: var(--sf-button-secondary-bg);
        border-color: var(--sf-button-secondary-border);
        box-shadow: var(--sf-button-box-shadow);

        &:hover:not(:disabled) {
            color: var(--sf-button-secondary-color);
            background-color: var(--sf-button-secondary-hover-bg);
            border-color: var(--sf-button-secondary-hover-border);
        }
    }

    /* Tertiary button */
    &.is-tertiary {
        color: var(--sf-button-tertiary-color);
        background-color: var(--sf-button-tertiary-bg);
        border-color: var(--sf-button-tertiary-border);

        &:hover:not(:disabled) {
            color: var(--sf-button-tertiary-color);
            background-color: var(--sf-button-tertiary-hover-bg);
            border-color: var(--sf-button-tertiary-hover-border);
        }
    }

}

@keyframes sp-status-pulse {
    from { transform: scale(0.8); }
    to { transform: scale(1.1); }
}
Enter fullscreen mode Exit fullscreen mode

See the following Codepen for a demo:

PS. I hope it will be useful ;)

Full article: Flexbox button with 3 styles and variations
CSS Snippets

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay