Earlier this year I found myself looking at a stylesheet that had become harder to maintain than it needed to be. The site itself was not especially complicated, however the same colours, spacing values and small interface decisions were appearing in several different places. Changing one brand colour meant searching through the CSS and hoping I had found every version of it. That kind of work is not difficult, but it is exactly the sort of work where mistakes quietly enter a project.
Preprocessors such as Sass had already helped with this problem, and I had been using variables there for a while. The interesting part about CSS custom properties was that the browser itself was starting to understand the idea. Instead of variables only existing during the build step, values could exist in the final CSS and respond to the cascade like normal CSS. That made them feel less like a convenience and more like a proper styling primitive.
Why Repetition Became Expensive
A small amount of repeated CSS is easy to ignore. The problem appears after a few rounds of design changes. A grey used for borders becomes slightly darker. A button colour changes because the brand direction shifts. A spacing value that worked on one template needs to be adjusted across several cards, forms and content blocks. If those values have been copied directly throughout the stylesheet, the cost of changing them grows every time the site evolves.
That cost is not only time. It also affects confidence. If I am not completely sure whether a value is reused intentionally, I have to change it carefully and test more places afterwards. A project starts to feel fragile when nobody knows whether two identical values are meant to stay connected or whether they only happen to match. Variables help because they make that relationship explicit.
What Custom Properties Changed
The thing I liked about CSS custom properties was that they kept the decision inside CSS. A simple example explains the idea well:
:root {
--brand-color: #2f5f8f;
--section-spacing: 48px;
}
.button {
background: var(--brand-color);
}
.section {
padding: var(--section-spacing) 0;
}
That might not look dramatic, but it changes how the file reads. The button is no longer using a random hex value that may or may not be connected to the rest of the project. It is using the brand colour. The section spacing is not just a number copied from a design file. It is a named decision that can be adjusted in one place.
The other useful part is that custom properties can change in different scopes. A component can inherit the global values or override them when it has a genuine reason. That fits naturally with how CSS already works. Rather than fighting the cascade, custom properties make the cascade more useful.
Where I Would Be Careful
I would not use custom properties as an excuse to create a huge list of names at the top of a stylesheet before the design has settled. That can become another form of noise. The useful values are the ones that actually repeat and carry meaning across the project. Colours, spacing, type sizes and component-level states are usually good candidates. One-off values often do not need a variable at all.
Browser support also needs to be considered depending on the audience. In 2016, this is still not something I would use blindly on every client project without checking the support requirements. If a site still needs to behave carefully in older browsers, I would either provide a fallback or keep some values in the preprocessor layer instead. The practical decision depends on who is using the site, not just on what the latest browser can do.
Retrospective Thoughts
Retrospectively, the most interesting thing about CSS custom properties is not that they reduce typing. It is that they make design decisions easier to keep visible in the code. A colour, spacing value or interface state can have a name that explains why it exists. That makes the stylesheet easier to read when the project is revisited later.
I still think Sass variables have their place, especially when values only need to exist at build time. CSS custom properties solve a slightly different problem because they continue to exist in the browser. That gives them room to support themes, component variations and runtime changes in a way traditional preprocessor variables cannot. For me, that makes them worth watching closely.