Styling Components
ScandiPWA uses the BEM methodology and SCSS
To style components, ScandiPWA uses the Block-Element-Modifier (BEM) methodology. BEM is based on assigning meaningful and unique class names to each HTML element we want to style while ensuring that we never need to use any CSS nesting in selectors.
We strive to follow this methodology in the core ScandiPWA theme, and we strongly encourage you to use it when overriding this theme as well.
Benefits of folowing our BEM guidelines:
The codebase is consistent
Styles are maintainable and can be re-used by composition with mixes
Styles can be overriden easily in child themes
The BEM Methodology
This section should serve as a quick introduction to how BEM is used in ScandiPWA. You can read the official BEM Guide. ScandiPWA uses the React variation.
All primary BEM classes are composed of these 2 parts:
<Block>
- in UpperCamelCase, the name of the component this element belongs to-<Element>
(can be left out) - in UpperCamelCase, a meaningful name of this element (e.g.Container
,Button
,Divider
,Image
... whatever identifies the purpose of this element)
Blocks indicate which component owns this element and preserves uniqueness accross all components. By keeping it the same as the component name, you don't need to worry about name-clashes with other components.
The "main" HTML element of each block may be left without a BEM Element. All other elements should have one to indicate their function.
In addition to its primary <Block[-Element]>
class, a block or element may have any number of modifiers of the form:
<Block[-Element]>_<booleanModifier>
- for boolean modifiers such asisActive
,isVisible
,isBold
, etc. The presence of this modifier indicates that it is "true", and it's absence indicates that it is "false".<Block[-Element]>_<modifierName>_<someValue>
- for boolean modifiers with values such ascolor_red
,type_primary
,size_thumbnail
BEM modifiers can be used to indicate state, available actions, or to distinguish between similar instances of the same element.
BEM in JavaScript
Formatting BEM classes manually with className
would get repetitive, so ScandiPWA uses rebem-jsx
to be able to use block
and elem
to specify the class. As an example, look at the render
method of ProductCard
:
Note that the block is always the same as the name of the component. This ensures consistency and prevents name clashes.
To add modifiers, pass an object with modifiers to the mods
prop. Boolean modifiers will be automatically detected and treated as such.
Styling Components in SCSS
Selecting BEM
We can take advantage of SCSS amperstand operator to reduce the repetitiveness of selecting BEM classes:
Breakpoints
ScandiPWA defines certain breakpoints that enable you to write viewport width-specific styles. These can be found in the global style directory. To select a specific device, simply use the @include
directive:
CSS Variables
CSS variables are useful when:
You want to reuse the same value multiple times
You want to be able to override a value based on the context
You want to make it more clear what a value represents by naming it
CSS variables are always defined in :root
. That way, re-defining them anywhere else is an easy way to override them. Example:
ScandiPWA uses an auto-prefixer. When compiling, vendor-specific versions of rules are added to make sure they work on most browsers.
Mixes
Sometimes, you may want to allow other components to add additional style rules to a component. For example, the Image component needs to define some styles, but can't predict ahead of time the exact styling features that will be needed for Images in parent components.
The solution is to allow other components to add their own styles to the Image component. The BEM methodology allows this by "mixing" 2 BEM classes together. For example, in the CategoryDetails component, in addition to the regular Image
block, the CategoryDetails-Picture
class will be added. Since the element will now have both of these classes, the parent component can additionally style the element with new rules.
Note: to allow a component's styles to be mixed, you need to pass the mix
prop to an element in the Component β this won't happen automatically. For example, consider how the Image component passes on the mix
prop:
Last updated