Most design sets style elements at the ID level. Frames, on the other hand, use BEM classes to style everything. This makes styling more efficient and ensures the maintainability of your website.
BEM is a class naming and organization methodology standing for Block, Element, and Modifier. The convention is block__element--modifier
.
If you aren’t familiar with BEM, make sure you watch this BEM tutorial before proceeding with Frames.
Frames-specific classes
All Frames classes start with the fr-
prefix, and every Frame you import will have at least one class on every element. This primary class contains the name of the Frame you imported (e.g. fr-section-alpha
), so it’s easy to identify.
When using a Frame for the first time, you should default to adding your styles to this primary class. This will ensure that if you use the frame again, all subsequent instances will match automatically.
This is beneficial. Imagine you’re styling an icon card. In most cases, icon cards should look the same across the site. Styling the icon card using the attached classes will ensure this happens.
If you deactivate or remove the class and add styles at the ID level, those styles will only apply to that one unique instance of the Frame. Furthermore, you won’t be able to override those styles with classes in the future because ID styling takes priority.
Thus, adding your initial styling to the default classes is safer and more efficient.
Block classes vs Element classes
Block classes are assigned to Blocks (unique parents), and Element classes are assigned to child Elements of a Block.
They’re easy to tell apart just by looking at them:
.block-name
.block-name__element-name
Notice that a Block class is a single stem, while Element classes use the __
to join two names together. The first name is the name of the parent Block, and the second is the element’s name.
Here’s what you need to know:
- Not all Blocks have child Elements.
- Parent Blocks can have Block children.
- Elements can’t exist without a Block parent.
Remember, when something is a Block element, it can be used anywhere, independent of its current context. Even though it may be a child in one context, it could be used by itself in another.
When something is an Element, it means it belongs to a unique parent Block and can only be used as a child of that parent Block.
Not all Blocks have child elements: fr-icon-link-alpha
is a styled link. It’s an example of a Block element with a unique class but no children.
Parent Blocks can have Block children: If a grid, for example, exists within a section, it may very well be a parent Block in itself. For example, fr-feature-section-bravo
contains fr-intro-charlie
as well as fr-feature-grid-bravo
.
Why? Because Intro Charlie and Feature Grid Bravo can both be used independently of Feature Section Bravo. Their existence and value have no reliance on Feature Section Bravo.
Hero Sierra on the other hand, which is also a section, has a child container fr-hero-sierra__inner.
This child container is a true child that only makes sense within the context of Hero Sierra, thus it has an Element class instead of a Block class.
The distinction is based on Atomic Design principles and whether or not an atom, molecule, etc. has relevant use outside of its current context.
Elements can’t exist without a Block parent: You will never find an Element outside of its parent Block in Frames, and you should never use an Element or move an Element outside of its parent.
Frames global classes
There are a few classes in Frames that are considered global classes. For example, fr-accent-heading
and fr-lede
.
These are just Block classes, but they’re used often and can be applied to different elements.
To understand these classes, we’ll use fr-accent-heading
as an example.
Every Frame with an accent heading will use fr-accent-heading
on the accent heading element. This is because websites look best when they’re consistent. Therefore, all accent headings tend to share the same styles.
When you consider HTML5 specifications, both a true <h>
heading (usually h1
, h2
, or h3
) or a <p>
paragraph could serve as an accent heading.
Assigning accent heading styles to a class lets you make any element look like an accent heading in seconds and gives you global control over the styling of all accent headings.
Elements with multiple classes
Let’s keep using accent headings as an example. In many Frames, accent headings will have two classes. For example: fr-accent-heading
and fr-intro-echo__accent-heading
.
This is done for maximum flexibility, giving you three styling options.
fr-accent-heading
gives the heading your global accent heading style by default.
fr-intro-echo__accent-heading
gives you the ability to modify the accent heading style within the context of Intro Echo, so that all instances of Intro Echo will use the modified accent heading style by default. While this may not be of value to you on every site, or ever, it’s valuable to other users in specific cases.
The third option is to apply a unique style to a specific instance of an accent heading by applying the styles at the ID level. For example, let’s say you want to add some bottom margin to a specific accent heading, but you don’t want that bottom margin added to any other accent headings. That’s a perfect time to use ID styling.
The BEM learning curve
Thankfully, the learning curve for BEM is not very steep. And the benefits BEM provides are well worth the short time it takes to wrap your head around it. This is especially true when you consider alternatives. Other methodologies for naming and organizing classes in web design are more complex, and the most popular approach of “winging it with no methodology” creates chaos.
Once you get the hang of BEM, you’ll appreciate and love that Frames uses this methodology. And you’ll enjoy the maintainability it brings to your sites, saving you hours and hours of manual labor when styling needs to change during development or in the future.