CSS Cascade Layers and Why Our Page Builder Depends on Them
Our visual page builder lets people style content with simple utility classes: make this heading white, make this text larger, give this section a green background. Those classes come from a utility-first CSS framework. Our platform also applies theme styles to every page: default fonts, colors and spacing for headings, paragraphs and links.
For a while, those two sources of styling fought each other. A heading styled white in the editor would appear dark on the live page, because a theme rule for all headings won the argument. The fix taught us something worth sharing about how CSS decides who wins.
How the cascade usually works
When two CSS rules target the same element, the browser picks a winner using a set of rules called the cascade. Broadly, more specific selectors beat less specific ones, and later rules beat earlier ones. A rule for "h1" is less specific than a rule for a class on that h1, so in theory the class should win.
But modern CSS adds another, stronger factor: cascade layers.
What cascade layers change
Cascade layers let stylesheet authors group rules into named layers and decide which layer takes priority, regardless of specificity. A utility framework typically places its own styles in layers: a base layer for element defaults, a components layer and a utilities layer, with utilities taking the highest priority among them.
Here is the surprise: any CSS that is not inside a layer beats every layered rule. An unlayered "h1 { color: dark }" will override a layered utility class like "text-white," even though the class looks more specific.
That was exactly our bug. Our theme's heading rules were unlayered, so they quietly beat the utility classes people chose in the builder.
Our rule for theme styles
The fix is a clear rule in our main page layout: any theme CSS that targets bare HTML elements, such as body, headings, paragraphs and links, must live inside the base layer. Element defaults then sit below the utilities, as they should, and a utility class chosen in the builder always wins.
Rules that use our own custom class names can stay unlayered safely, because they only apply where those classes are used. The rule is specifically about broad element selectors, which apply everywhere and therefore cause the most surprises.
Making the rule stick
Rules like this are easy to break by accident months later. So the layout file contains a large comment explaining the rule, why it exists and how to test changes. Our engineering standards repeat it, and our page-saving code includes safeguards against losing the styles that pages depend on.
The test is simple and worth copying:
- Open the visual builder for any page.
- Add a section with a heading styled white on a dark background.
- Save and view the live page.
- The heading must look the same as in the editor.
If it does not, the cascade is broken somewhere.
The same thinking for our own sites
When we built this website inside our platform, we applied similar care. Base styles for our design were written with low-specificity selectors so they set sensible defaults without fighting anything more specific. Buttons, cards and sections use their own class names. The result is a design that can be edited in the builder without mysterious overrides.
Why this matters to people who never write CSS
Most people using our page builder will never think about cascade layers. They just expect that when they make a heading white, it stays white. Getting the cascade right is how we meet that expectation, and it is part of why VoVo can promise that the editor and the live page match.
Frequently asked questions
What are CSS cascade layers?
Cascade layers are a CSS feature that groups rules into named layers with a defined priority order, which takes precedence over selector specificity.
Why does unlayered CSS override utility classes?
Rules outside any layer have higher priority than all layered rules, so an unlayered element rule can beat a layered utility class.
How do I keep theme styles from overriding builder styles?
Put theme rules that target bare elements, like headings and paragraphs, inside the base layer so utility classes take priority.
Comments (0)
No comments yet. Be the first to share your thoughts!