A better, faster approach to CSS in WordPress themes
![](https://yoast.com/cdn-cgi/image/width=400%2Cheight=210%2Cfit=scale-down%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2016/01/Site_speed_FI.png)
In our ongoing quest to make yoast.com lightning fast, we’ve reached a bottleneck when it comes to optimising our CSS. The ways in which WordPress themes manage, handle and output stylesheets just aren’t good enough. Technology has changed, the web has evolved, and the tools we have are out of date. We think we can come up with something better.
The importance of speed
At Yoast, we understand that improving the speed of your site can have a big impact on your SEO. More importantly, we understand that a fast, responsive website provides a better user experience – which impacts your reputation, and the likelihood of your visitors to engage with your content. Speed matters. We’ve written about this a lot.
That’s why we’ve become a bit obsessed with optimising the yoast.com ecosystem. We’re trying to make our own website as fast as possible, and we’re continually working to shave bytes and milliseconds from every page, script, style and more.
![](https://yoast.com/app/uploads/developer-images/2019/01/yoast-lighthouse.png)
A Lighthouse report for yoast.com
Over recent months, we’ve been working to improve all aspects of our site. We’ve refined our hosting setup, managed our plugins and scripts, refactored our custom font handling, and much more.
We’ve made the site really fast. But we want to go faster. And increasingly, we’re finding that the slowest part of our site is the CSS we use to display our theme – in particular, how it’s structured and loaded.
Our current approach
One of the slowest things our site does is load lots of CSS on each page, in a big style.min.css
file. This takes a lot of time for your browser to download, and then to parse and render.
Even though we’re minifying that file, serving it via a CDN, and instructing the browser to ‘preload’ it, it’s still relatively big. And, even though we’ve applied all of the performance tricks in the book, there’s no escaping that your browser stalls whilst it has to process all of those bytes.
What’s even worse is that, on most pages, we only use a tiny fraction of that CSS. You can see from the image below that, on the homepage, we load 117kb of CSS – but over 90% of that isn’t used or needed on the page. That’s a lot of wasted time and bandwidth.
![](https://yoast.com/app/uploads/developer-images/2019/01/yoast-homepage-css.jpg)
Yoast.com’s homepage loading 117kb of CSS, but only using 11kb
Even more significantly, the way in which browsers work requires all of the CSS to be downloaded and parsed before anything can happen on the screen. So those large, chunky files will hold up everything else on the page – and will often continue to do so, regardless of how much ‘optimisation’ is done elsewhere.
Put simply, if we can load less CSS, we reduce the bytes transferred, and the processing/rendering time the browser spends painting the screen. Everything gets faster.
But, even with so much waste, this approach comes with some benefits. Though the initial download is slow, the file gets cached by the browser when it’s done. That means that if you navigate to other pages, you don’t have to get the file again – so it loads instantly. And because we’ve already loaded all of the CSS you’ll ever need, the rest of your experience is really fast. But that initial load is still slow, and inefficient.
This kind of setup is still incredibly common on the web, because this approach used to be best practice. That’s not the case any more.
A history lesson on CSS best practice
Once upon a time, browsing the internet was much slower. This wasn’t just due to limited bandwidth and slower connections, but, the also way in which your computer negotiates with the servers you request pages and content from.
The web was, originally, designed primarily for displaying text documents, and simple pages. The underlying technologies didn’t anticipate the media-rich, complex environment the web would become. And they hadn’t changed much since – until recently.
One of the main things that legacy technology failed to anticipate was how many things a modern webpage would try and make a user download. A complex page with many scripts, styles, resources, images, frames and external assets would put those assets into a queue, grind to a halt. That’s because browsers only really let users download a few things at once, and this was a hard-coded restriction into the way that the underlying systems worked.
That meant that best practice was to include fewer files. Sending 6 small, individual script files, for example, could take a lot longer than sending one big script – even if that meant using more bandwidth, and the browser taking more time to process that file. This kind of combination of assets, and minification, became best practice.
WordPress is oldschool
WordPress, for the most part, still operates this way. Most themes and plugins consolidate, combine, and send a few, big resources. Many plugins still ‘optimise’ their CSS (and JavaScript) in this way, mostly because they don’t know better.
If we want WordPress to be fast, it’s not enough to rely on theme and plugin developers to own and embrace this transition. Theme developers have the tools to make fast websites, today, but are still making slow sites, using outdated techniques. What they lack isn’t in tooling, but rather, is in education, experience, or design/development patterns.
To speed up our platform, we need to define frameworks and constraints to enable people to get it right, as close to ‘out of the box’ as possible. We have to design a better approach to CSS authoring and serving, and bake it deep into WordPress.
The web has changed
Now, the web has matured. Technologies, frameworks and best practice have evolved. Performance optimisation is no longer an art, but a science.
Of the changes we’ve seen, I can see five key factors which, when combined, provide us with the tools to explore better approaches to managing CSS in WordPress, and, to better serve the needs and browsing behaviours of our users.
- As individuals, our browsing habits have shifted to include huge amounts of mobile consumption – where data is precious, and connectivity is often limited. That means that optimising for speed requires us to focus on efficiency and flexibility of serving. Every byte and every millisecond counts.
- There’s been a broad adoption of HTTP/2, which allows us to send multiple files in parallel. Now we can send lots of small files, in specific ‘bundles’ for the page/view in question – allowing us to send individual shared/cacheable and page-specific files.
- CSS pre/post-processors (like LESS/SASS, and PostCSS) are increasingly part of most authoring workflows. These let us abstract and better manage the CSS we write. Now we can manage those ‘bundles’ without enormous overhead and micromanagement.
- We have best practices for loading ‘non-critical’ CSS asynchronously via JavaScript. Now we can defer the loading of CSS for elements which aren’t immediately visible on a page, so that we can prioritise the initial view.
- There’s strong browser support for CSS media queries, which allow us to target specific viewports and device capabilities. Now we can build mobile-first, and only ‘unlock’ the additional CSS required for larger viewports on appropriate devices.
More broadly, we also have some really solid standards and definitions for what ‘best practice’ looks like, in particular, the approached outlined and championed by Google, Illya Grigorik and team.
Together, these trends and tools enable us to re-write the rule book. We have the flexibility and capability to redefine how CSS is handled in WordPress, and to define a performant, flexible, universal approach pattern for all themes, plugins and sites.
Our objective – a better approach
Our goal, then, is to create a general approach to CSS authoring and loading, which makes sense for any and every site, and which is as future-proof, scalable and flexible as it can possibly be.
In particular, we want to:
- Only include the CSS necessary for the specific scenario the user has loaded, but also;
- Ensure that shared and global stylesheets are cached by the browser and re-used between requests.
- Limit the total requests to a ‘sensible’ number, as even over HTTP/2, each individual request comes with an overhead. There’s a balance to be struck where loading many small, ultra-specific files might be slower than fewer, slightly more generic files.
- Future-proof against and support current and emerging patterns, as much as possible (i.e., critical path management, inlining, HTTP/2 server push).
- Make it as easy as possible to style/CSS authors/designers to contribute to and manage a theme’s styling without knowing or touching the PHP.
We should also consider how we:
- Minimise the overhead on authoring and managing CSS (in LESS/SASS).
- Stick to established WP patterns where possible.
- Ensure backwards-compatibility, so that the new system can gracefully replace the old – in particular;
- Respect the current wp_enqueue_style() function, which is perfectly suitable for the act of ‘enqueuing’, and critically, used by themes/plugins to transform output, and;
- Avoid ‘hacks’ like CSS tree-shaking, which paper over bad foundations, and make it hard to achieve some of the benefits which a stronger foundation delivers.
- Be platform-agnostic. Whilst we’re primarily focused on WordPress, we should try and define an approach which works, conceptually, on/for any platform.
Let’s create a CSS template hierarchy
Conveniently, WordPress already has a system which ensures that the right assets are loaded for a user for any given request, and any given state. The PHP templating system, and WordPress template hierarchy, is designed to do precisely this, and works well.
Conceptually, we can do something similar with stylesheets. With some adaptation, we can define a hierarchy for CSS requirements, and create a system which loads the right assets based on the requested template/state.
The way in which we need to manage and load CSS is a little more complex, however, as we need to manage specificity and inheritance – which means loading multiple files, rather than just the most specific match.
We also want to maintain a component-first approach, where CSS mostly lives in / is associated with specific components and modular, re-usable blocks. We want to be able to ‘bundle’ those components to create the backbone of the specific template/view/page files we’ll be conditionally loading.
These are some challenging requirements! But, if we’re clever, we might be able to create a CSS system which marries elegantly to the PHP template system.
Here’s the approach
- We should load structural CSS and utility classes on all requests, as separate CSS files (
header.css
,footer.css
,utils.css
etc). - We should define and manage all of the components which the site uses separately from the views/pages they’re loading in/on, and, whenever possible, adopt a ‘component-based’ approach to authoring.
- For each request, we should determine the template type (e.g.,
is_single()
, oris_archive()
) being returned / selected by the query. - We should detect the most precise existing match from the template hierarchy, and enqueue the appropriate stylesheet.E.g., if the request is for a
Post
with an ID of 12345, we should loadsingle-post-12345.css
(if it exists). - We should enqueue all of the less specific files which are matched, if they exist, in order of least-to-most specific, using a dependency chain to manage ordering.E.g., a request to a specific recipe (a custom post type) should load
singular.css
>single.css
>single-recipe.css
>single-recipe-12345.css
. - In our example, the specificity of styling increases as we progress down that chain. E.g.,
singular.css
contains generic CSS, like structure, typography and colours – attributes and components shared by all ‘single’ pages/posts, like a sidebar.single.css
contains components shared only by all posts, like a comments form.single-recipe.css
contains CSS used by all recipe posts, like a recipe card.single-recipe-12345.css
contains only ~10 lines of very specific CSS, intended for only that post.
It’s assumed that this ‘bundling’ of stylesheets, where, e.g., single.css
is a composite of components like sidebars and cards, is achieved via SCSS/LESS, but a simpler/partial implementation could feasibly work with ‘raw’ CSS.
In most scenarios, we recognise that websites won’t vary greatly between ‘views’. A ‘post’ will likely be very similar to a ‘page’, and, individual post types won’t vary greatly. However, this structure provides us with the framework to write component-based CSS which focuses the composition on tackling the most common scenarios, and seperates out the most specific / rarer ones.
It does so in a way which removes duplication, and reduces the management of view-types to little more than selecting which components to bundle.
My site might only require a small number of generic, ‘high level’ styles (like single.css
) in addition to global styles (like footer.css
), and a few ultra-specific stylesheets for certain pages/posts. Those stylesheets are mostly comprised of components I’ve defined and manage centrally, and the whole thing becomes a joy to manage.
Some of the hard work has already done
Personally, I’m a huge fan of the Query Monitor plugin for WordPress. It’s a great tool for assessing and diagnosing performance issues in themes and plugins.
Helpfully for us, it also contains a series of functions which assesses the requested template, and, output a priority-ordered list of all the templates (and partials) which are loaded on the request. See https://github.com/johnbillion/query-monitor/blob/master/collectors/theme.php, (get_query_template_names()
and action_template_redirect()
in particular).
This feels like a great shortcut and a starting point for us – we can learn a lot from the work which has already been done.
Registering styles
In our example, we explored how a request to a post with an ID of 12345 should load single-post-12345.css
, but only if it exists.
For performance reasons, we want to avoid relying on ‘sniffing’ to see if the file exists at the point when it’s requested. Given that we’re looking for multiple files and potentially traversing folders, this could get slow, quickly.
We also don’t want to place hard definitions on where stylesheets should live in a theme; that’s a strong architectural constraint and has impact/implications beyond the scope of this challenge (that said, consideration should be given to a sensible file/folder hierarchy).
Instead, we’re proposing a method for registering all of the stylesheets available in a theme, so that they can be enqueued on demand without needing to go through a detection process.
I suggest we the ability for themes to register an array of styles (which should, if/when possible, be auto-built, e.g., via PostCSS), which looks something like:
$styles = array(
'front-page' => array(
'file' => '/example/path/front-page.css',
'dependencies' => array()
),
'single-1234' => array(
'file' => '/example/path/single-1234.css',
'dependencies' => array()
),
'archive-cats' => array(
'file' => '/other-example/other-path/cats-archive.css',
'dependencies' => array()
),
'logged-in' => array(
'file' => '/example/conditions/logged-in.css',
'dependencies' => array(),
'function' => 'user_is_logged_in',
'critical' => true
),
[...]
);
Then rather than sniffing for files, we can check our pre-registered styles to see if we have the CSS available (“This looks like a request for Post 1234
; do we have a single-1234
entry in the styles array?”). Positive matches pass the file, and any additional properties (e.g., dependencies
) to wp_enqueue_style()
.
It’s assumed that this array/function is managed manually for small/simple sites, or built automatically via PostCSS processes in more sophisticated workflows.
Future-proofing
I’ve anticipated a requirement for function
, so that future iterations might also register CSS for conditionals which might impact the page’s CSS requirements, but which don’t map to the template hierarchy (e.g., user is logged in). When specified, the file should be enqueued if the function returns true
.
I’ve also anticipated a requirement for specifying whether a stylesheet should be considered part of the critical
path; this might feasibly alter how a theme goes about enqueuing
such an asset (e.g., methods like inlining, rewriting the hostname, preloading, HTTP/2 server push, etc), and should map neatly to any existing filters/hooks which intercept wp_enqueue_style()
.
Media queries
To maximise performance, not only do we want to load only the specific CSS required for the current page/view/state, but also to load only the CSS required for the current viewport size or device capabilities.
To achieve this, we want to take advantage of the fact that wp_enqueue_style
supports specify a media
property, (e.g., media="screen and (min-width:500px)"
), which dictates under what conditions a stylesheet should be loaded.
However, with our workflow and current model, using this approach presents a challenge:
- In terms of authoring and management, we want to define the media queries for, e.g., a
.card
component incard.scss
. It’s impractical to split media queries into seperate source files, as they’re often intertwined with nested classes, mixins, etc. card.scss
, along with other components, is included insingle.scss
and therefore compiled into, e.g.,single.css
.- In this world,
single.css
is now bloated with un-used media queries, for users on all screen sizes.
So we need a solution – we need to manage our media queries ‘centrally’, but split them out in production.
To achieve this, I suggest we use a PostCSS package like https://www.npmjs.com/package/postcss-extract-media-query. This, or similar/alternate approaches, can extract media query code from compiled CSS files (e.g., single.css
), and splinter them into viewport-specific variants.
In this example, that gives us single.css
as a mobile-first stylesheet, but also produces single-sm.css
, single-md.css
, single-lg.css
, etc (depending on which queries exist / are used in the ‘base’ version).
This also provides future support for other media scenarios, like print
stylesheets, DPI constrained sheets, colour-constrained sheets, device orientation specifics, etc. See https://www.w3schools.com/tags/att_link_media.asp.
I propose that, to register these variations, we add an optional media
property to each of the styles we register, structured as follows:
'media' => array(
array(
'query' => 'only screen and (min-width: 600px)',
'file' => /example/path/front-page_md.css'
),
array(
'query' => 'only screen and (min-width: 968px)',
'file' => /example/path/front-page_lg.css'
)
);
Now our enqueue methods can output each of these variants, and let the browser do the heavy lifting on deciding what to ship to the user.
Challenges/Issues
The world is a complex, messy place, and nothing exists in isolation – especially in the WordPress world. Here are some headaches I’m anticipating us needing to solve.
“We can already enqueue assets selectively based on template”
This is absolutely true – what I’m describing could be achieved today, by any conscientious theme developer, without the need for a new framework or approach.
What’s missing, however, is a generally accepted standard for ‘the right way’ to approach the selective/conditional enqueing of resources based on the template/view, which anticipates the complexity of the real world, and the differences between sites with wildy varying structures, approaches and needs. People can do this manually, but don’t know how, or don’t know that they should.
By the same logic, people could hard-code their websites in raw PHP. They don’t – they use content management systems which come with handy abstractions and wrappers.
More significantly, perhaps, this approach is designed to allow non-developers (e.g., CSS authors) to control the front-end – even to make radical structural changes to the CSS template hierarchy – without ever opening a PHP file. If the styles array can be auto-built by post-processing systems, designers can add to/remove from/edit bits of the hierarchy without needing the kind of (relatively) deep understanding they’d need to enqueue stylesheets in today’s ecosystem.
This post is the beginning of us exploring what the need, and documentation, for those kinds of abstractions might look like in the case of supporting performant CSS in WordPress. Managing the complexities of cache optimisation, front-end vs back-end processing speeds, and ‘future-proofing’ against the need for functionality like media queries, inlining and JS-based loading is hard to juggle. We want to abstract that away, and give people a framework which they can use to get it right, out of the box.
Bootstrap, and other generic frameworks
Many sites build their stylesheets ‘on top of’ third party frameworks like Bootstrap. These come with their own design patterns, but often ship as a single, monolithic file which stores all of their ‘reset’ code and utility classes. Most of the time, that’s where we see the biggest chunks of unutilised CSS on websites.
For now, that means that our system is only really suitable for people who’re developing their own solutions, or heavily modifying (and paring back) the frameworks they use.
In the future, it’d be great to see these kinds of frameworks and libraries do more to encourage their users to modularise their offerings. I’d like to see more people disabling the components they don’t need to use globally, or, improve how/where/when they’re imported.
Gutenberg, blocks and in-content styles
Historically, many plugins have supported shortcodes which resulted in additional styles being loaded into a page. That’s typically been handled inconsistently, with a mix of inline styles, output buffering, and enqueing ‘surprise’ styles in the footer (which often cause repaint/reflow issues as the browser parses, incorporates and updates those styles).
All of these approaches create different performance issues, and, there’s never been a ‘good’ way of handling these kinds of requirements.
Now, Gutenberg blocks are proliferating this pattern. Blocks often ship with their own CSS, and, it’s unclear where this ‘lives’. To incorporate blocks into our design pattern, pages need to know about what’s in their content, before the <head> is output. That’s a performance and architecture challenge.
Given the scope of this challenge, I’m conveniently ignoring Gutenberg blocks for now – but at some point, we’ll need better answers to how blocks store, manage and declare style dependencies.
It may be that the up-and-coming browser behaviour described here by Jake Archibald could help, where it becomes easier and safer to load newly discovered stylesheets inline, as they’re discovered. In that case, blocks (and other in-content elements) could output their own stylesheets, without disrupting rendering or making a mess.
At this stage, it’s still unclear how different browsers will handle those scenarios, and how the nuances of things like stylesheet duplication (e.g., if you have two of the same block on a page), and load jank (where styles conflict with / overwrite existing styles) will be handled.
If the spec is robust, this might be a great addition to our approach – where our templating system handles everything around the content, and individual content blocks manage and output their own styles in the flow, as they’re needed. We’ll wait and see!
What’s next?
As you might have guessed, we’re well-underway on exploring and implementing this approach on yoast.com. We’ll no doubt encounter challenges as we go, and we’ll keep you updated.
More broadly, we think that this approach is a much better design pattern for WordPress sites, themes and plugins – and if it goes well for us, we’ll be keen to explore how we might make a case for broader adoption.
It’s possible that some of this thinking might also apply to how JavaScript is used in WordPress, but that’s a much messier ecosystem. We might explore that if/when we see how our CSS approach plays out in the real world.
We’d love to hear your thoughts on this direction, potential improvements, issues, and your own experiences. Let’s speed up WordPress!
Coming up next!
-
BFCM Prepathon by Cloudways
September 10 - 12, 2024 Team Yoast is at Attending, Speaking BFCM Prepathon by Cloudways! Click through to see who will be there, what we will do, and more! See where you can find us next » -
Webinar: How to start with SEO (September 11, 2024)
11 September 2024 Learn how to start your SEO journey the right way with our free webinar. Get practical tips and answers to all your questions in the live Q&A! All Yoast SEO webinars »
Jono, i’m waiting to hear a good news!
Whatever it’s like a plugin, or whatever, i’m waiting here with curious.
Hope that awesome is able to implemented on my websites.
Hi Jono, you mentioned that you’ve set your CSS file to preload, and I can see from this webpage’s source that you’ve got most of your CSS and JS files set to preload at the top of the section.
I’m curious to know how exactly you accomplish that. Do you use a particular plugin, or a function, to have those files automagically added as preload links? Care to share? And would you recommend adding every single CSS and JS file as a preload link, or just the most important ones? I’ve read elsewhere that if too many files are preloaded, it can actually have a negative impact.
Ah, that’s some custom logic which we’re running in our theme. It needs some refinement, too – it was a temporary fudge, and we’ll revisit it and improve it at some point. We might move some of those to HTTP headers, and/or HTTP2 push, depending on various factors. Indeed, it’s generally not a good idea to preload and force *everything*, if they’re not all needed for the initial page load.
If you want a quick way to DIY it, most caching and performance plugins (e.g., WP Rocket, W3 Total Cache) have options to add DNS preload tags, etc!
If there was something simple to speed up my website I would love to buy it Something called Yoast speed maybe!
I hope Yoast has been intelligent enough to brief copyright lawyers in relation to this stuninngly promising development: WordPress would be a formidable corporation – but one which certainly needs turbocharging.
So lokiing forward to enjoying the results of this magnificent strategic thinking and courageous commitment.
And to a parallel development with JS.
Good article! I just want to recommend a couple of tools that can help in this Critical Rendering Path optimization journey.
An alternative to: https://www.npmjs.com/package/postcss-extract-media-query
Are:
https://www.npmjs.com/package/media-query-plugin
https://www.npmjs.com/package/media-query-splitting-plugin
Also, this is an amazing tool to automatically detect, extract and inline the Critical CSS of our website.
https://www.npmjs.com/package/webpack-conditional-loader
Sounds complicated. Just come up with a plugin for it…lol
Good writeup! ;) This is almost exactly what I did for most of my “big” customers during the last years. Unfortunately only the ones that are good on budget can go with this approach while 99% of all WordPress users can not afford to pay someone doing this and/or do not have the technical understanding to it themselves. But we’ll see what the future brings.
Keep up the good posts!
Oh man I’ve had thoughts for a while of only loading componentized CSS chunks like you describe. Have you seen this approach from Jake Archibald?
https://jakearchibald.com/2016/link-in-body/
It’s a real interesting idea. I look forward to seeing how this turns out.
Morning! Spent some time pondering this approach, and updating the ‘Gutenberg’ section of the post with some thoughts!
Although the ideea is good, the real benefit would be fairly small.
That 117kb is actually 23kb gzipped. Wich is acceptable. If anything, this would affect the rendering performance, not the transfer performance. Furthermore, having more than 50kb of uncompressed CSS for a blog theme is a problem by itself.
Instead of breaking the CSS in pieces scoped to pages, it would be way more efficient to break media queries into separate files and load each variant for appropriate media query.
Thanks for the comment! Yeah, our 23kb gzipped isn’t nearly as bad, but there’s still room for improvement – and as you say, it’ll definitely still hurt rendering performance.
I think we can take both approaches – break out the files, *and* separate out the media queries. I cover this in a section at the end of the post :)
Great stuff, I very much like where this is going!
We’ve been experimenting with more granular CSS files in WP Rig (https://github.com/wprig/wprig), however it’s not quite as granular. Plus, a more standardized approach like what you’re suggesting makes a lot more sense to enable any theme developer to easily support it.
Regardless of the approach, we’ve also been thinking about tree-shaking: While I agree with you that it is a hack, for as long as there is a lack of a better standardized approach, this can still be valuable. And while I’m positive the CSS hierarchy approach can be easy to implement once available, tree-shaking would require hardly any setup if done by a plugin (like it is integrated in the AMP plugin currently). It’s certainly not a great solution, but better than none.
One specific minor concern about your suggestion, I don’t think a specific file (like `styles.php`) should be required by themes. Similarly to what you’re mentioning for CSS, no specific file location should be assumed for PHP. I rather think there could be a function to register the available assets that the theme developer has to explicitly call from wherever fits their code organization.
All in all, I’m excited to see this move forward!
Adding to what Felix said, take a look at what WP Rig does to load styles inside the element at component level. This is a new and mostly unknown feature of the web platform which enables the developer to associate styles with corresponding HTML for modularization and less the browser render styles as it encounters them.
More details: https://jakearchibald.com/2016/link-in-body/
Yeah, this is super-interesting!
I’m a little nervous about embracing it as an approach, however, until we get a bit more clarity on how various browsers handle it, and in particular, how they handle jank/duplication/reflow.
In an ideal world, this could be an extension of the approach I’ve outlined, where we just have an additional component for inline sheets loaded by their various components.
Ah, I’m definitely keen to layer tree-shaking on top of this – it’s unrealistic, I think, to get to 100% CSS utilisation for a given state (especially if we’re bundling utility classes), so stripping some of the extras out at view-level feels like a good additional pass.
Good shout on not needing styles.php; I’ll update the post to remove that!
Super-interesting ideas! Thanks for sharing.
I’ve been looking into using external style sheets in the body to load ‘block’ specific styles as they’re loaded. This has been talked about recently by Harry Roberts and looks like it would fit nicely with Gutenberg’s block-based approach.
I appreciate what you are suggesting and think it is super interesting. Currently, most optimized themes are loading a ccs.min for the theme and whatever the plugins are loading which you pointed out is heavy-handed. Super interested in where this lands.
1. I think Gutenberg will fall into line when the sass or less is compiled on the backend on post-save; this includes seperate files for different viewports. I have no idea if this is possible, but if this system can ‘read’ media-queries and bundle queries within certain ranges into their own files that would be ideal…
2. Bringing in bootstrap and other frameworks is only possible if you bring it in on the sass or less-level. There you’d still be able to cherry-pick. Maybe we would need a node / php hybrid plugin or application to facilitate this.
Anyway, I’d love to discuss this in further detail :)
Ah, SASS/LESS compilation on save would be awesome, but it’s *such* a monemental shift from how WP works at the moment. Worth exploring, but I don’t think it’d land any time soon. That’s why I’m suggesting we rely on post-processing (e.g., PostCSS) in the build process – but obviously that rules out a lot of ‘casual’ developers and smaller outfits who don’t have build/release processes.