Styling It

Topics covered in this tutorial:

After watching this video, you should be able to discuss the following topics:

  • Gluing classnames with “&”

  • Mods with boolean and non-boolean modifiers

  • Using mix prop to combine classes

  • Root and non-root declarations of CSS custom properties

Adding style files (.css)

Add a new style file style.css in your theme’s src folder:

After adding style.css you need to import it in index.js by adding:

This tutorial builds on the previous one. If you haven’t completed it, you can just copy the following contents and add them to src/index.js.

Using CSS properties without a prefix

It is recommended to stick to styling by classes, as it’ll make your life easier in the long run:

A REM unit is equal to computed value of font-size for the root element. So, if your font default is 12px, 1 REM unit will be 12px as well and 0,25 REM units will be 3px.

In order to make the styles work, we need to add class names to the render methods found in index.js.

First, let’s edit the class Button:

Next, the same for class Wrapper:

For now, ESlint rules won’t let you use className, so for the sake of this tutorial, disable this rule for the whole file.

Now the style should change accordingly. If we use ‘Inspect element’ on a button in the browser, we should see in the Styles tab that a previously unknown property webkit-appearance has been added. This happened due to the fact that the compilator automatically adds vendor prefixes to the properties.

Here you can see browser specific examples:

Using CSS variables

Instead of writing out the color references directly, we should use CSS variables or CSS custom properties. They are declared in the root element and later referenced using var().

In order to showcase the differences in these approaches more clearly, we can define a new className in the Button component.

Now, let’s style the button-wrapper:

Now, the background color of the button in <div className="button-wrapper"> should be green. This happens because a CSS custom property has inheritance - it takes the topmost parent and goes downwards, looking for re-definition of the variable. If the property finds a re-definition, it’ll use the one closest to it.

This comes in handy when changing hover colors:

Switching to SCSS to build classnames

In order to improve the readability of the style file we can switch to SCSS - rename style.css to style.scss and change the name of import in index.js as well.

Now, instead of repeating .button over and over again, we can, for example, add the :hover pseudo-class by nesting the properties.

The & works like glue that allows us to place our className and any selector or different className together.

Organizing classnames with BEM

We can use BEM to further organize our style files.

Notice that blocks are named using PascalCase - each word in a compound word is capitalized. A block’s declaration usually is preceded by a dot, for example, .MyElement.

An element always follows a block and is defined using a dash and PascalCase, for example, .Heading-Strong where Heading is the block and -Strong is the element.

If, we’re using SCSS, we can use glue or & for BEM elements as well, for example:

Modifiers are the state definitions of an element or a block, these are usually preceded by an underscore and named using camelCase. Note that you can use either one-part or two-part modifiers.

One-part modifier is a boolean modifier that should start with is and non-boolean modifiers should be split in two parts, where the first part defines the type of the modification and the second part defines a value.

The next example uses the gluing method to define .Heading_isLarge, .Heading-Key_isHuge and .Heading_type_icon:

Let’s rearrange our style file to follow the BEM standards:

We should apply the same rules for className in index.js. For the Button class:

And for the Wrapper class:

Since it’s not exactly convenient to concatenate strings, in order to have multiple elements or modifiers, we should use the BEM HTML helpers. Let’s also add a modifier:

Add the same modifier to the style file:

If you’re using the ScandiPWA ESlint rules, you can re-enable the no classNames rule, since we’re using BEM props now.

If you want to write something that previously consisted of two classNames, you can still use BEM. This can be done with mix, for example:

We can see what happens in CSS by inspecting the button:

If you want to add a third block, you can mix it in the first mix:

And by inspection we’ll see three class names:

Last updated