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:
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:
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.