At the community summit, we discussed a core CSS roadmap, initially a discussion about preprocessors in regard to their role in WordPress, both in the admin and in bundled themes. Recently, there has been significant discussion about the initial use of a preprocessor in the development of Twenty Fifteen that was not included when it landed in core. We discussed what role preprocessors may play with our default theme development and core WordPress for the long term.
In this post, you will find some history, some observations, and an outline of where we can go next to bring some sanity to our admin CSS as well as move into the future.
A little wp-admin.css history
What we’re gonna do right here is go back, way back, back into time.
While some sort of admin CSS has existed from the beginning, the wp-admin.css file we know and love has existed since r313, when it was renamed from b2.css. Through tweaks and redesigns, like in 2.0 and 2.5, and the initial merge of crazyhorse in 2.7, it began to resemble what we have today. Other redesigns have since followed, but much of our CSS has stayed the same in terms of the code itself – selectors, patterns, etc. As you can imagine, eleven years of iterated CSS (that began with another project’s CSS) can become quite tangled.
Also very interesting to trace is the history of structural changes. In 2.1, we began to see other CSS files introduced. In 2.3, all other CSS files were moved into a subfolder (wp-admin.css and its RTL counterpart were not moved until 3.0), where we still find our CSS today. In 2.9, minification was introduced – at that time, wp-admin.css was the minified version, and wp-admin.dev.css was the unminified working copy. We switched to the more common .min.* convention in 3.5, with wp-admin.css once again becoming the working copy.
In 3.3, most of the individual admin CSS files were merged into one – the behemoth wp-admin.css that existed for a few years. This was done for a few reasons: for admin CSS to be cacheable (due to concatenation and dependencies, it was different on nearly every screen and therefore not browser-cached), to de-duplicate selectors and rulesets, and to avoid cascade issues that would crop up due to dependencies and load order.
Some files were still separate – notably color schemes, which were all separate, including the default. In 3.8, along with the redesign, more non-default color schemes were introduced, built with Sass, marking our first (and currently only) usage of a preprocessor in core. Using a preprocessor was enabled by the start of more modern tooling in 3.7. We also moved to auto-generated RTL stylesheets using CSSJanus in 3.8 and use a postprocessor in the form of Autoprefixer for browser prefix management as of 3.9.
Also in 3.9, we began taking steps toward long-term health and maintenance of our admin CSS. We began by merging the default color scheme into wp-admin.css, followed by the splitting of wp-admin.css back out into modular files. Unlike pre-3.3, however, CSS files are not loaded conditionally and with dependencies based on where you are in the admin; they are still all loaded everywhere. In fact, wp-admin.min.css remains the same as before, which is what the vast majority of sites use. For more on how that’s accomplished, see this comment on #26669.
So where do we go next?
With smaller files, the hope is that over time we can clean them up — without even getting into the preprocessor side of things. We’d like to make these styles more modular and think about how tooling can help impact and maintain the structure of these moving forward. The goal is to positively affect many groups: maintainers, developers who build with WordPress, and newer contributors who are often put off by issues such as the sheer volume of styling or the potential for uncaught side effects.
The proposed route:
Start with documentation. Just as the PHP Code Reference is parsed and generated, we can do the same with CSS. We also need to clearly document when values are co-dependent (e.g. z-index) or specific techniques are employed for a specific reason.
Establish a pattern library. This will begin by documenting what components we currently have, particularly reusable ones. Ideally, this would be largely supported by inline documentation and generation. We will need to set goals for what our pattern library should accomplish and support.
Create tooling and automated testing. We should implement tooling for syntax and style checking (#29792). We may also want to implement a task like CSSComb for tidying. The pattern library should be able to serve as a base for automated visual regression testing. As discovered in 4.1, even Grunt task dependency updates need to be checked for adverse effects.
Collect metrics / statistics on styles in use. It is important that as we implement more and more front-end processing that we understand the impact our changes have on the user. Not every user gets to use the latest and greatest software and hardware, and we need to keep that in mind. By collecting performance data (such as rendering time, repaints, and selector performance), we can keep track of our overall trends and identify any specific problem areas.
Decide on CSS naming conventions. There are a few commonly used conventions – what would make the most sense for a project like WordPress? Our pattern library goals will likely heavily inform this.
Clean up existing styles. Through tooling and testing, we stand a better chance of cleaning up our CSS with minimal adverse effects. As a part of this we should also extend the CSS coding standards to Sass and use it for existing Sass files.
Revisit the topic of preprocessors as related to core admin CSS. In our discussion at the community summit, it was agreed that our current state of CSS does not lend itself to wholesale adopting a preprocessor. That is not to say that we don’t stand to gain anything, but rather that we would do better with a preprocessor were we to take other steps first before making such a decision.
It’s important to note that this is not a set series of events – some tasks can be worked on concurrently, and some items will be ongoing through multiple releases.
With thanks to @krogsgard for collating the original notes from which this post began.