Skip to content

Styles

General

Storefront provides a number of styles to help you create a more visually appealing website. Under the hood, these styles are implemented using LESS. We are using BEM (Block Element Modifier) naming convention.

LESS files structure

Each block has a corresponding .less file. Styling for each block should only be in one place. Let's take btn block (element) for example. It consists of three files:

  • buttons_mixins.less
  • buttons_variables.less
  • buttons.less
@btnBorderWidth: 1;
@btnBorderStyle: solid;
@btnBorderColor: transparent;
@btnBorderRadius: @globalBorderRadius;
@btnLineHeight: 18;

@btnIconGutter: @buttonsGutter * 0.625;

@btnFontSizeInPxL: @fontSizeInPxL;
@btnPaddingTopL: 9;
@btnPaddingRightL: 24;
@btnPaddingBottomL: 9;
@btnPaddingLeftL: 24;

@btnFontSizeInPxM: @fontSizeInPxM;
@btnPaddingTopM: 7;
@btnPaddingRightM: 20;
@btnPaddingBottomM: 7;
@btnPaddingLeftM: 20;

@btnFontSizeInPxS: @fontSizeInPxS;
@btnPaddingTopS: 7;
@btnPaddingRightS: 16;
@btnPaddingBottomS: 7;
@btnPaddingLeftS: 16;

@btnFontSizeInPxXS: @fontSizeInPxXS;
@btnPaddingTopXS: 5;
@btnPaddingRightXS: 10;
@btnPaddingBottomXS: 5;
@btnPaddingLeftXS: 10;

@btnPaddingIcon: 9;
@btnFontSizeInPxIcon: @btnFontSizeInPxL;

@btnBgColorPrimary: @primaryColor;
@btnColorPrimary: @neutralColors0;
@btnBgColorPrimaryHover: darken(@btnBgColorPrimary, 14.5%);
@btnColorPrimaryHover: @btnColorPrimary;
@btnBgColorPrimaryDisabled: @primaryColors300;
@btnColorPrimaryDisabled: @neutralColors0;

@btnBgColorSecondary: @primaryColors50;
@btnColorSecondary: @primaryColor;
@btnBgColorSecondaryHover: darken(@btnBgColorSecondary, 14.5%);
@btnColorSecondaryHover: @btnColorSecondary;
@btnBgColorSecondaryDisabled: @primaryColors50;
@btnColorSecondaryDisabled: @primaryColors200;

@btnBgColorSpecial: @primaryColors900;
@btnColorSpecial: @neutralColors0;
@btnBgColorSpecialHover: lighten(@btnBgColorSpecial, 7.4%);
@btnColorSpecialHover: @btnColorSpecial;
@btnBgColorSpecialDisabled: @neutralColors400;
@btnColorSpecialDisabled: @btnColorSpecial;

@btnOutlineColor: @neutralColors300;
@btnBgColorOutline: inherit;
@btnColorOutline: @neutralColors700;
@btnBgColorOutlineHover: fade(@btnBorderColorOutline, 30%);
@btnColorOutlineHover: @neutralColors900;
@btnBorderWidthOutline: @btnBorderWidth;
@btnBorderColorOutline: @btnOutlineColor;
@btnBgColorOutlineDisabled: transparent;
@btnColorOutlineDisabled: @btnOutlineColor;
@btnBorderColorOutlineHover: @neutralColors500;

@btnBgColorGhost: transparent;
@btnColorGhost: @primaryColor;
@btnColorGhostHover: darken(@btnColorGhost, 14.5%);
@btnBgColorGhostHover: transparent;
@btnBgColorGhostDisabled: transparent;
@btnColorGhostDisabled: @neutralColors300;

@btnBgColorIcon: @neutralColors50;
@btnColorIcon: @globalFontColorSecondary;
@btnBgColorIconHover: @neutralColors100;

@btnIconPaddingL: 15;
@btnIconPaddingM: 11;
@btnIconPaddingS: 9;
@btnIconPaddingXs: 7;
.btn-decorate-appearance (@bgColor: transparent, @color: @btnColorPrimary, @borderColor:  transparent) {
    background-color: @bgColor;
    color: @color;
    border-color: @borderColor;
    fill: @color;
    stroke: @color;
}

.btn-decorate-size (@fontSize, @paddingT, @paddingR, @paddingB, @paddingL, @lineHeight) {
    .font-size(@fontSize);
    .line-height(@lineHeight);
    .padding-to-unit(@paddingT, @paddingR, @paddingB, @paddingL);
}
.btn {
    transition: background-color 0.3s, color 0.3s, box-shadow 0.3s;

    display: inline-flex;
    align-items: center;
    justify-content: center;

    font-family: @baseFontFamilyName;
    text-decoration: none;
    text-align: center;

    background-color: transparent;
    border: ~'@{btnBorderWidth}px' @btnBorderStyle @btnBorderColor;
    border-radius: ~'@{btnBorderRadius}px';

    user-select: none;
    cursor: pointer;
    min-height: 40px;
    min-width: 40px;

    .weight-semibold();
    .line-height(@btnLineHeight);
    .btn-decorate-size(@btnFontSizeInPxM, @btnPaddingTopM, @btnPaddingRightM, @btnPaddingBottomM, @btnPaddingLeftM, @lineHeightInPxM);

    &_l {
        .btn-decorate-size(@btnFontSizeInPxL, @btnPaddingTopL, @btnPaddingRightL, @btnPaddingBottomL, @btnPaddingLeftL, @lineHeightInPxL);
    }

    &_s {
        .btn-decorate-size(@btnFontSizeInPxS, @btnPaddingTopS, @btnPaddingRightS, @btnPaddingBottomS, @btnPaddingLeftS, @lineHeightInPxS);
    }

    &_xs {
        .btn-decorate-size(@btnFontSizeInPxXS, @btnPaddingTopXS, @btnPaddingRightXS, @btnPaddingBottomXS, @btnPaddingLeftXS, @lineHeightInPxXS);
    }

    &_full-width {
        min-width: fit-content;
        width: 100%;
    }

    &_primary {
        .btn-decorate-appearance(@btnBgColorPrimary, @btnColorPrimary);

        &:hover {
            background-color: @btnBgColorPrimaryHover;
            color: @btnColorPrimaryHover;
        }

        &-disabled {
            .btn-decorate-appearance(@btnBgColorPrimaryDisabled, @btnColorPrimaryDisabled);
            pointer-events: none;
        }
    }

    &_secondary {
        .btn-decorate-appearance(@btnBgColorSecondary, @btnColorSecondary);

        &:hover {
            background-color: @btnBgColorSecondaryHover;
            color: @btnColorSecondaryHover;
        }

        &-disabled {
            .btn-decorate-appearance(@btnBgColorSecondaryDisabled, @btnColorSecondaryDisabled);
            pointer-events: none;
        }
    }

    &_special {
        .btn-decorate-appearance(@btnBgColorSpecial, @btnColorSpecial);

        &:hover {
            background-color: @btnBgColorSpecialHover;
            color: @btnColorSpecialHover;
        }

        &-disabled {
            .btn-decorate-appearance(@btnBgColorSpecialDisabled, @btnColorSpecialDisabled);
            pointer-events: none;
        }
    }

    &_outline {
        .btn-decorate-appearance(@btnBgColorOutline, @btnColorOutline, @btnBorderColorOutline);
        border-width: ~'@{btnBorderWidthOutline}px';

        &:hover {
            color: @btnColorOutlineHover;
            border-color: @btnBorderColorOutlineHover;
        }

        &-disabled {
            .btn-decorate-appearance(@btnBgColorOutlineDisabled, @btnColorOutlineDisabled, @btnBorderColorOutline);
            pointer-events: none;
        }
    }

    &_ghost {
        .btn-decorate-appearance(@btnBgColorGhost, @btnColorGhost);

        &:hover {
            color: @btnColorGhostHover;
            background-color: @btnBgColorGhostHover;
        }

        &-disabled {
            .btn-decorate-appearance(@btnBgColorGhostDisabled, @btnColorGhostDisabled);
            pointer-events: none;
        }
    }

    &_icon {
        .btn-decorate-size(@btnFontSizeInPxIcon, @btnPaddingIcon, @btnPaddingIcon, @btnPaddingIcon, @btnPaddingIcon, @lineHeightInPxL);
        .btn-decorate-appearance(@btnBgColorIcon, @btnColorIcon);

        border-radius: 50%;

        &:hover {
            background-color: @btnBgColorIconHover;
        }
    }

    &_join-right {
        border-right: 0;
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }

    &_join-left {
        border-left: 0;
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    &__icon {
        .icon-m();
        stroke: inherit;

        &_left {
            margin-right: @btnIconGutter;
        }

        &_right {
            margin-left: @btnIconGutter;
        }

        &_filled {
            fill: inherit;
        }
    }
}

@media (max-width: (@breakPointSm - 1)) {
    .btn {
        &_full-width {
            &-mobile {
                width: 100%;
            }
        }
    }
}

buy-button {
    display: inline-flex;
}

As you can see, in many cases there is no need to write your own styles to modify button element. Instead you can change the values of variables. For example if you want to alter the primary button color:

@btnBgColorPrimary: #006699;
@btnBgColorPrimaryHover: lighten(@btnBgColorPrimary);

That's all. Also, we are not creating any new styles (optimization says "yay!"). We are just changing values of variables that will be compiled into CSS. As you may have noticed button variables use some other variables. Those are global variables that can also be modified. We will discuss this in next section. Changing global variables will lead to modifications in the styling of many different elements.

Theme colors

Each theme consists of seven main colors, forming a complete palette. These are:

  • Primary color
  • Secondary color
  • Neutral color
  • Success color
  • Warning color
  • Error color
  • Shade light color
  • Shade dark color

By lightening and darkening these colors, we get the entire palette. For the default theme, the palette looks like this: Image title

Where main colors are those with number 500 and others are automatically calculated based on the main colors. Read more in the Theme Colors section.