What I Was Never Told About CSS

Going Deeper with CSS: Tips and Tricks for Better Performance

Pavel Pogosov
JavaScript in Plain English

--

CSS is a beautiful and complex technology that we use every day at work. However, many developers, including myself overlook a number of its essential aspects.

And it’s clear why, as it is really difficult to find something new or advanced about CSS on the internet. That’s because the majority of content creators only write about hype topics like new languages, frameworks, and libraries.

Personally, I’ve only learned enough about CSS to get things to work. And it is particularly sad as I’ve never attempted to delve deeper into the subject. Recognizing this fact, I did a bit of research and made a list of new things for me.

In this article, I’d like to share this list with you. Hopefully, you will find it useful as well. So let’s get started!

Table of Contents

CSS Performance

CSS performance is rather an important topic to keep in mind as it directly affects the efficiency of a website. Because modern applications contain a large amount of CSS code, even minor errors can cause significant slowdowns.

Child selectors

To begin, I’d like to show you something that surprised me the most. Simply look at the example below and try to figure out what can be potentially wrong with it.

As you can see, this example isn’t sophisticated at all. This CSS snippet removes the text-decoration from all links within paragraphs in our header. Isn’t it just a regular CSS?

But did you know that using selectors like this causes the browser to perform a lot of extra work? This issue applies to all similar cases involving child selectors in our code.

This is because the browser reads selectors from right to left when parsing CSS. With that newfound knowledge, let’s break down this process into steps.

  • Browser finds all <a> tags on a page
  • Then it finds all the anchors that are contained within the paragraphs
  • Finally, it narrows the found set to those that are only contained within the #header element

By using more specific selectors, we can help the browser avoid all of that extra work. We can apply the class .header__link to anchor elements and use it to replace the selector #header p a. In that case, the browser will find the required elements faster.

Expensive CSS properties

By calling CSS properties expensive, I mean that can they cost a lot of performance in our application. But It doesn’t mean, that you shouldn’t use them at all. You just need to understand that if the element uses these properties and renders frequently — it will definitely influence the performance.

One tricky thing to keep in mind is that changing some CSS properties requires updating the entire layout. Geometric properties such as width, height, top, and others can result in a complete redraw of the tree.

There are also some properties that are difficult to render. There is a short list of such properties, but you can learn more about them here.

  • border-radius
  • box-shadow
  • filter
  • :nth-child
  • position: fixed

Repaint and Reflow

Repaint and Reflow are two important concepts in the process of rendering a web page in the browser. When a page is loaded or updated the browser goes through a series of steps to display the content on the screen. And Repaint and Reflow play a significant role in this process.

We should break it down into precise steps to understand it better:

  • The HTML document downloaded from the server is used to construct the Document Object Model (DOM)
  • Styles are loaded and recognized, creating the CSS Object Model (CSSOM)
  • Based on the DOM and CSSOM, a rendering tree is formed, which is a set of rendering objects. The rendering tree duplicates the structure of the DOM, but invisible elements (such as <head> or elements with the style display: none) are not included. In other words, the rendering tree describes the visual representation of the DOM
  • For each element in the rendering tree, its position on the page is calculated, and layout occurs. Browsers use a flow method, in which one operation is usually enough to place all of the elements. Tables, for example, need more operations
  • Finally, all of the elements are rendered in the browser, and painting occurs

When a page is first loaded, if it’s not empty, at least one reflow and repaint are always executed. But also, they continue to happen in the following cases:

  • When a part of the tree needs to be recalculated caused by the change of the width, height, or other coordinates of a node. This results in a reflow event
  • When due to the changes, some of the displayed content must be updated. This primarily applies to style properties like background color, radius, and so on. This results in a repaint event

Also when a reflow event occurs, it is always followed by a repaint event. Repaint, on the other hand, can be triggered independently of reflow.

About Reflow

Reflow is the process of calculating the layout of elements on a web page. It determines the size and position of each element by its content and styles.

It can quickly become a resource-consuming operation, especially in modern applications with thousands of elements on the page and frequent layout updates. Even reflowing a single element in the document may require reflowing its parent elements and any others which follow it.

As it is a user-blocking operation, it’s quite useful to understand how to improve reflow and the effects of various document properties on its duration. The typical things which evoke a reflow process are usually:

  • Different manipulations with the DOM. For example, adding, deleting, and changing nodes
  • Change in the element’s content, even including text in form fields
  • Calculation (getComputedStyle) or modification of CSS properties
  • Manipulations with the element classes
  • Actions with the browser window (resizing, scrolling)
  • Activation of pseudo-classes. :hover is a great example of that

About Repaint

Repaint is the simple process of drawing pixels on the screen. After the layout is determined during the reflow, the browser paints each element onto the screen.

Repaint is usually less resource-consuming than reflow, but it can still have an impact on the performance of the web page.

The most typical case when it occurs is the change of the element styles that do not affect its size or position on the screen. For example, when background-color is changed, the browser simply redraws (or repaints) the node with the new style.

Here are some examples of actions that will trigger a repaint:

  • Changing the visibility of an element
  • Changing the outline of the element
  • Changing background

Where CSS can substitute JS

JavaScript and CSS are fantastic technologies, especially when used together. Each of these technologies has unique strengths, and when combined, they can create incredible things.

However, I am confident enough to say that the more CSS is used for UI control, the more fault-tolerant and reliable web applications become. My points are quite simple:

  • CSS, by definition, is a fail-safe technology. When a CSS parser encounters an invalid property, it simply ignores it and moves on
  • JavaScript is not a fail-safe technology. A single syntax error in JS code can cause an entire application to fail. In other words, when using JS to control styling, it is critical to ensure that the functionality of the corresponding constructions works

Now let’s consider cases where you can easily substitute js with CSS.

Smooth Scroll

Earlier, to implement smooth scrolling, it was necessary to use a few lines of JavaScript. But now, this task can be solved entirely by the power of CSS.

Isn’t that wonderful? Now you can use smooth scrolling by using the CSS property scroll-behavior.

Text manipulation

CSS gives the ability to use two great properties: text-overflow and line-clamp. They allow us to trim texts while also relieving us from JavaScript code or other complex ways to perform such tasks. Both properties are not new, but extremely helpful.

Text-overflow property

This property controls how text is displayed in situations where it does not fit one line. The perfect example of such a situation is shown in the image above, at the title of the card. text-overflow: ellipsis construction results in a Unicode character at the end of the trimmed text.

Please, keep in mind that text-overflow: ellipsis only works in a couple with such properties as: white-space: nowrap and overflow: hidden.

Line-camp property

line-camp property comes in handy where we need to work not with single-line but with multi-line text. The card description in the example above, illustrates how it performs.

This property is a part of the CSS Overflow Module Level 3 standard which is currently considered as the draft. Nevertheless, it is already supported by about 95% of browsers, but with the -webkit- prefix.

Before using it, it is important to mention that it does not allow control over the number of displayed characters. But it is still incredibly useful.

In order to use line-camp property we need to combine it with display: -webkit-box and -webkit-box-orient: vertical. Here’s what it looks like:

Conclusion

The modern world of front-end development is rapidly changing, and we are constantly given new opportunities to help us do our jobs faster and way better. Experimenting with CSS can be really interesting and helpful. Please, Consider using CSS instead of JS if you can achieve the same result without using JS.

Thanks for reading!

I hope you found this article useful. If you have any questions or suggestions, please leave comments. Your feedback helps me to become better.

Don’t forget to subscribe⭐

More content at PlainEnglish.io.

Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.

Interested in scaling your software startup? Check out Circuit.

--

--

Senior Frontend Dev, sharing my knowlege about frontend. 100% original content, 0% AI