When working with WordPress blocks, you will often want to load specific CSS for individual blocks—whether they are core blocks or custom ones.
From a performance perspective, the most efficient approach is to only load that CSS when the relevant block is actually present on the page, rather than loading styles globally that may never be used.
Thankfully, when using the WordPress block editor, this is fairly straightforward to achieve using core WordPress APIs.
Our setup
In our active theme, we use the following file and folder structure to organise block-specific styles.
- assets
- blocks
- core-paragraph.css
- core-button.css
- acf-cta.css
- blocks
Each CSS file is named after its corresponding block, with slashes replaced by dashes. For example, the core/paragraph block maps to core-paragraph.css.
We then run the following custom code in the theme’s functions.php file to automatically enqueue stylesheets for any blocks that have a matching CSS file.
<?php
/**
* Enqueue block stylesheets for blocks that have a stylesheet
* placed in the assets/blocks directory.
*
* Stylesheets should be named using the block name with dashes
* replacing slashes. e.g. core-paragraph.css
*/
function hd_enqueue_block_stylesheets() {
// Get all block stylesheets.
$stylesheets = glob( get_theme_file_path( 'assets/blocks/*.css' ) );
// Bail early if no stylesheets are found.
if ( empty( $stylesheets ) ) {
return;
}
foreach ( $stylesheets as $stylesheet_path ) {
// Extract the base filename (e.g. core-paragraph).
$filename = basename( $stylesheet_path, '.css' );
/**
* Map filename prefixes to block namespaces.
* Add additional prefixes here as required.
*/
$block_prefixes = [
'core-' => 'core/',
'acf-' => 'acf/',
];
$block_name = $filename;
// Convert filename into a valid block name.
foreach ( $block_prefixes as $file_prefix => $block_prefix ) {
if ( str_starts_with( $block_name, $file_prefix ) ) {
$block_name = str_replace( $file_prefix, $block_prefix, $block_name );
break;
}
}
// Skip if the block is not registered.
if ( ! WP_Block_Type_Registry::get_instance()->is_registered( $block_name ) ) {
continue;
}
wp_enqueue_block_style(
$block_name,
[
'style_handle' => 'hd-block-' . $filename,
'src' => get_theme_file_uri( "assets/blocks/{$filename}.css" ),
'path' => $stylesheet_path,
]
);
}
}
add_action( 'init', 'hd_enqueue_block_stylesheets' );
Code explanation
The code begins by locating all CSS files within the assets/blocks directory. Each file represents styles for a specific block.
The filename is then converted into a block name. For example:
core-paragraphcore-buttonacf-cta
Because wp_enqueue_block_style() requires a valid block name (such as core/paragraph or acf/cta), we map filename prefixes like core- and acf- back to their respective block namespaces.
Before enqueueing the stylesheet, we perform a defensive check to ensure the block is actually registered. This prevents unnecessary processing and avoids potential issues if a stylesheet exists for a block that is no longer in use.
Finally, we enqueue the stylesheet using the core wp_enqueue_block_style() function. This provides several benefits out of the box:
- Registers the stylesheet with WordPress
- Only loads the CSS when the corresponding block is present on the page
- Automatically inlines small stylesheets when appropriate