loading...
Cover image for Utilizing the “C in CSS

Utilizing the “C in CSS

azinasili profile image Azin Asili ・7 min read

This article was originally posted on the Graphite GTC blog.

For a lot of developers CSS is a tricky beast to handle. Developers always tack on rules to the end of their styles sheets, causing some unintended consequences. After some raging and cursing at why CSS exists, an !important is added and voilà , it all works. Most of the time, these issues are caused by the cascading nature of CSS. Because of the deep seeded hatred for the “C in CSS, many smart people developed methodologies to help reduce this feature or to completely remove it. These methodologies include OOCSS, SMACSS, and, BEM.

The point of this post is not to argue against these methodologies; they’re really useful in managing your style sheets and also to keep your CSS uniform. What if we were able to use the cascading feature of CSS to our benefit? Imagine if we could write one CSS rule and have it propagate to the descending elements.

To truly utilize the cascading nature of style sheets we will need to use some lesser known CSS units and keywords. We will employ the following:

  • EM (and sometimes REM) units
  • inherit
  • currentColor

EMs and REMs

You’re probably familiar with using PX units for sizing elements, margin, padding, borders, etc. We can do the same with EMs and REMs but with the added benefit that these units are relative rather than absolute values. MDN defines EMs as:

This unit represents the calculated font-size of the element. If used on the font-size property itself, it represents the inherited font-size of the element.

MDN also gives this tidbit about EMs

This unit is often used to create scalable layouts, which keep the vertical rhythm of the page, even when the user changes the size of the fonts. The CSS properties line-height, font-size, margin-bottom and margin-top often have values expressed in em.

Note that MDN says that EMs “represents the inherited font-size of the element” and are “used to create scalable layouts”. This is the exact thing we are looking for! Here is what MDN says about REMs:

This unit represents the font-size of the root element (e.g. the font-size of the element). When used on the font-size on this root element, it represents its initial value.

The biggest difference between the two is REMs always references it’s value based on the root element’s font-size, while EMs inherits it’s unit from the element’s font-size. If this seems confusing, don’t worry, take a look at the following CSS to get a better understanding:

.element {
  font-size: 20px;
  padding: .5em;
}

In the example above the element’s padding would equate to 10px. Remember EM units are relative to the element’s font-size, this means our padding equation is 20 * .5 = 10.

.element {
  font-size: 20px;
  padding: .5em;
}

.element-child {
  font-size: .25em;
  padding: 1em;
}

Imagine this scenario: we know that .element padding is equal to 10px, but what about the values for .element-child? Well because EMs compound our math, things can get a little tricky. The font-size for .element-child will equate to 5px (20 * .25 = 5). Since the parent element has a font-size of 20px and we defined the child element as .25em of the parent’s, our compounded value is equal to 5px. The padding is a lot easier in this case, because EMs look at the font-size value, our padding equates to 5px.

Hopefully that wasn’t too much to handle. The tricky part with EMs is managing how to calculate the output values. Since it’s a hassle I’ve created a set of functions and mixins for Sass to make our lives easier! You can find the Github Gist here.

Inherit Keyword

Another tool in our arsenal is the inherit keyword, this value allows us to get the style that is defined on a parent element and apply it to the child. We can do this without having the same rule defined twice. MDN defines inherit as the following:

The inherit CSS-value causes the element for which it is specified to take the computed value of the property from its parent element. It is allowed on every CSS property.

Imagine the following scenario using the inherit keyword:

.element {
  background: coral;
  padding: 1em;
}

.element-child {
  color: white;
  padding: inherit;
}

Our .element-child would get the value for padding from .element and apply it to itself. This is nice because if the padding on .element changes, so will the padding for .element-child! This is perfect if we are trying to avoid writing the same styles multiple times. The one downside of this technique is the keyword only looks at the parent elements value; we are unable to move up in the DOM tree and get the value of an ancestor element.

CurrentColor Keyword

This keyword acts like inherit with one big difference, currentColor can be used to inherit the color of properties that normally do not inherit that value. MDN defines currentColor as the following:

The currentColor keyword represents the calculated value of the element's color property. It allows to make the color properties inherited by properties or child's element properties that do not inherit it by default.

Now that we have some knowledge of the techniques we can use to manage how our values cascade, let’s put it into action.

Examples of our new techniques

See the Pen Utilizing the 'C' in CSS - Button Example by Azin Asili (@azinasili) on CodePen.

The above example is just getting our feet wet. Although it’s simple, it perfectly shows how EMs can be used to scale our elements. You will notice two buttons, both look the same except .btn--large is, well larger. Even though the button is larger, we never adjusted the padding for the button or even reset it’s border-radius, instead we only adjusted the font-size. Neat!

Because EMs inherit the font-size value, any property that is also using EMs will scale. Since our .btn--large is 1.25x larger than the initial .btn, that means the other values will also be 1.25x larger. This is exactly what we want with our cascade. The compounding of values may cause issues if you’re not careful, but when deliberately used it can be the best way to create alternative sized elements with minimum effort.

See the Pen Utilizing the 'C' in CSS - Cards by Azin Asili (@azinasili) on CodePen.

This card example expands on some of the principals for cascading. Again, we are using EMs to size our elements but now we are also using the currentColor and inherit keywords to style certain elements. Rather than hard-coding colors and other values, we can use our handy keywords to have the styles cascade down to the element we want.

See the Pen Utilizing the 'C' in CSS - Pricing Table by Azin Asili (@azinasili) on CodePen.

Our last example will demonstrate our new found cascading knowledge and apply it to a more real-world scenario. Much like the other examples we will continue to use EMs to size our elements, but with one exception, the margin on .price will use REMs instead. This is because we do not want our margins to scale with any changes to font-size. Notice the middle table is larger than the other two? We not only use color to highlight that specific option but we also resized the whole table to be larger than the other two. Both the color and the increase in size is to draw attention to our customers. Normally with the larger sized element we would have to resize every padding and font-size properties. Instead we use the power of EM and the cascade to do this for us.

Final Thoughts

The above techniques are a fantastic way to take back control of your CSS, however, it does take a little extra brainpower. Using EMs for unit values can cause issues when you have nested elements. This can be solved with some simple math or with functions/mixins if you’re using Sass or any other pre/post processor. Either way, a little bit of extra effort can go a long way, making your style sheets more flexible and scalable for your projects. Let me know what you guys think!

Discussion

pic
Editor guide
Collapse
leandritgo profile image
Leandrit Ferizi

Thanks for this good article :D

Collapse
maccabee profile image
Maccabee

This is great! I'm surprised not there aren't many comments.

Collapse
plixe profile image
Plixe

Great article thx !
Personnaly I use REM units in all my css and with the root font-size I switch between vh/vw units. It's more easy for responsive !