{"id":551,"date":"2026-02-27T18:01:03","date_gmt":"2026-02-27T18:01:03","guid":{"rendered":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/2026\/02\/27\/gutenberg-times-14-ways-to-add-custom-css-in-wordpress-block-editor\/"},"modified":"2026-02-27T18:01:03","modified_gmt":"2026-02-27T18:01:03","slug":"gutenberg-times-14-ways-to-add-custom-css-in-wordpress-block-editor","status":"publish","type":"post","link":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/2026\/02\/27\/gutenberg-times-14-ways-to-add-custom-css-in-wordpress-block-editor\/","title":{"rendered":"Gutenberg Times: 14 ways to add Custom CSS in WordPress Block Editor"},"content":{"rendered":"<p class=\"wp-block-paragraph\">With the new Custom CSS on a block and post\/page level, I was wondering if I would know where to look if something needs to be changed that was modified by a Custom CSS setting. Turns out there are 14 different ways to skin WordPress. I am a fan of keeping one source of truth, but it might not always be possible to keep it in theme.json. So I also wanted to figure out what decisions making process goes into selecting a method in the first place.<\/p>\n<p class=\"wp-block-paragraph\">Below is a comprehensive reference for users, site builders, designers and developers covering all methods from no-code to full theme development.<\/p>\n<p class=\"wp-block-paragraph\">These methods only apply to Block themes, though. Classic theme methods (like the Customizer\u2019s Additional CSS panel etc.) are excluded.<\/p>\n<div class=\"wp-block-group\">\n<div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"wp-block-paragraph\"><strong>Table of contents<\/strong><\/p>\n<nav class=\"wp-block-table-of-contents\">\n<ul>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#the-specificity-cascade\">The specificity cascade<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#1-theme-json-structured-style-properties\">1. theme.json \u2014 structured style properties<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#2-theme-json-the-css-property\">2. theme.json \u2014 The css Property <\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#3-custom-css-properties-variables-via-theme-json-settings\">3. Custom CSS Properties (Variables) via theme.json Settings<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#4-child-theme-s-theme-json\">4. Child Theme\u2019s theme.json<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#5-global-styles-ui\">5. Global Styles UI <\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#6-additional-css\">6. Additional CSS <\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#7-per-block-additional-css\">7. Per-Block Additional CSS <\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#8-additional-css-class-es-on-individual-block-instances\">8. Additional CSS Class(es) on individual block instances<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#9-global-style-variations-theme-level-style-presets\">9. Global Style Variations (Theme-Level Style Presets)<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#10-block-style-variations-json-php-and-javascript\">10. Block Style Variations (JSON, PHP, and JavaScript)<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#11-section-styles\">11. Section Styles <\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#12-block-stylesheets-via-wp-enqueue-block-style\">12. Block Stylesheets via wp_enqueue_block_style()<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#13-enqueuing-stylesheets-via-wp-enqueue-style-in-php\">13. Enqueuing Stylesheets via wp_enqueue_style() in PHP<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#14-the-theme-s-style-css\">14. The Theme\u2019s style.css<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#summary-table\">Summary Table<\/a><\/li>\n<li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/gutenbergtimes.com\/14-ways-to-add-custom-css-in-wordpress-block-editor\/#decision-guide\">Decision Guide<\/a><\/li>\n<\/ul>\n<\/nav>\n<\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">The specificity cascade<\/h2>\n<p class=\"wp-block-paragraph\">Before diving in, it helps to understand WordPress\u2019s style hierarchy for block themes. Styles resolve in this order, with later layers overriding earlier ones on four levels.<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Default <\/strong>mostly the styling and layouts of WordPress Core.<\/li>\n<li><strong>Block-level<\/strong> styling can be altered with plugins and overwrites the Default styling.<\/li>\n<li><strong>Theme-level <\/strong>styling is the whole suite of design tools controlled by the active Theme. It overwrites Default and block-level styles and layouts for instance (e.g. template and template parts).<\/li>\n<li><strong>User-level<\/strong> styling uses the Design tools within the Site Editor to modify styles and layouts. These changes are stored in the database and overwrite the theme-level styling.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Within each layer, more specific targets (per block, per element) override more general ones. This cascade is central to how all the methods below interact.<\/p>\n<h2 class=\"wp-block-heading\">1. theme.json \u2014 structured style properties<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers, child theme authors<br \/><strong>Where:<\/strong> <code>theme.json<\/code> (root of your theme) \u2192 <code>styles<\/code> section<\/p>\n<p class=\"wp-block-paragraph\">This is the <strong>recommended first choice<\/strong> for styling in block themes. Rather than writing raw CSS, you define styles as structured JSON properties \u2014 colors, typography, spacing, borders, shadows, and more \u2014 at the global, element, or per-block level.<\/p>\n<p class=\"wp-block-paragraph\">You can use hardcoded values directly in <code>styles<\/code>, and they work just fine:<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>{\n  \"version\": 3,\n  \"styles\": {\n    \"color\": {\n      \"background\": \"#ffffff\",\n      \"text\": \"#333333\"\n    },\n    \"elements\": {\n      \"link\": {\n        \"color\": { \"text\": \"#0073aa\" }\n      }\n    },\n    \"blocks\": {\n      \"core\/button\": {\n        \"color\": { \"background\": \"#0073aa\" }\n      }\n    }\n  }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>styles<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>background<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#ffffff\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>text<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#333333\"<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>elements<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>link<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>text<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#0073aa\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>blocks<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>core\/button<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>background<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#0073aa\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\">As your theme grows, hardcoded values become harder to manage. If you decide to change your primary color, you\u2019d need to find and update every instance of <code>#0073aa<\/code> across styles. A more maintainable approach is to define your values as presets in the <code>settings<\/code> part of theme.json and then reference them in <code>styles<\/code> using the <code>var:preset||<\/code> syntax. WordPress converts these presets into CSS custom properties (e.g., <code>--wp--preset--color--primary<\/code>), keeping everything connected:<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>{\n  \"version\": 3,\n  \"settings\": {\n    \"color\": {\n      \"palette\": [\n        { \"slug\": \"primary\", \"color\": \"#0073aa\", \"name\": \"Primary\" },\n        { \"slug\": \"base\", \"color\": \"#ffffff\", \"name\": \"Base\" },\n        { \"slug\": \"contrast\", \"color\": \"#333333\", \"name\": \"Contrast\" }\n      ]\n    },\n    \"typography\": {\n      \"fontSizes\": [\n        { \"slug\": \"medium\", \"size\": \"18px\", \"name\": \"Medium\" }\n      ]\n    }\n  },\n  \"styles\": {\n    \"color\": {\n      \"background\": \"var:preset|color|base\",\n      \"text\": \"var:preset|color|contrast\"\n    },\n    \"typography\": {\n      \"fontSize\": \"var:preset|font-size|medium\",\n      \"lineHeight\": \"1.6\"\n    },\n    \"elements\": {\n      \"link\": {\n        \"color\": { \"text\": \"var:preset|color|primary\" }\n      },\n      \"heading\": {\n        \"typography\": { \"fontWeight\": \"700\" }\n      }\n    },\n    \"blocks\": {\n      \"core\/button\": {\n        \"border\": { \"radius\": \"4px\" },\n        \"color\": { \"background\": \"var:preset|color|primary\" }\n      },\n      \"core\/quote\": {\n        \"typography\": { \"fontStyle\": \"italic\" }\n      }\n    }\n  }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>settings<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>palette<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>[<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"primary\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#0073aa\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Primary\"<\/span><span> <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"base\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#ffffff\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Base\"<\/span><span> <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"contrast\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#333333\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Contrast\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>]<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>typography<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>fontSizes<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>[<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"medium\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>size<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"18px\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Medium\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>]<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>styles<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>background<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"var:preset|color|base\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>text<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"var:preset|color|contrast\"<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>typography<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>fontSize<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"var:preset|font-size|medium\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>lineHeight<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"1.6\"<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>elements<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>link<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>text<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"var:preset|color|primary\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>heading<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>typography<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>fontWeight<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"700\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>blocks<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>core\/button<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>border<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>radius<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"4px\"<\/span><span> <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>background<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"var:preset|color|primary\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>core\/quote<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>typography<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>fontStyle<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"italic\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\">This token-based approach pays off in a few ways. When a user changes \u201cPrimary\u201d in the Global Styles UI, every element referencing that token updates automatically. It keeps your theme internally consistent \u2014 no risk of one button being <code>#0073aa<\/code> while another drifted to <code>#0074ab<\/code>. And it makes global style variations far simpler to create: a dark mode variation only needs to redefine the palette, not hunt down every color reference in styles. Either approach is valid, but tokens tend to save time as a theme matures.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Automatic integration with the Global Styles UI:<\/strong> Users can view and override your styles in the Site Editor without writing CSS.<\/li>\n<li><strong>WordPress manages specificity for you:<\/strong> the \u201cbase \u2192 theme \u2192 user\u201d cascade works correctly.<\/li>\n<li><strong>Generates CSS custom properties automatically<\/strong> (e.g. <code>--wp--preset--color--primary<\/code>).<\/li>\n<li><strong>Visual parity<\/strong> between editor and front end.<\/li>\n<li><strong>Machine-readable: <\/strong>other tools and plugins can consume and extend these styles.<\/li>\n<li><strong>Reduces the amount of CSS<\/strong> enqueued overall.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Can only express what <a href=\"https:\/\/schemas.wp.org\/trunk\/theme.json.\">theme.json\u2019s schema<\/a> supports (growing with each release, but not yet comprehensive).<\/li>\n<li>Pseudo-classes like <code>:hover<\/code>, <code>:focus<\/code>, <code>:active<\/code>, and <code>:visited<\/code> are supported for elements such as links and buttons (e.g., <code>\"elements\": { \"link\": { \":hover\": { \"color\": { \"text\": \"var:preset|color|contrast\" } } } }<\/code>), but pseudo-elements like <code>::before<\/code> and <code>::after<\/code>, media queries, and more complex selectors are not available in the structured properties \u2014 use the <code>css<\/code> property (#2) or block stylesheets (#3) for those.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/global-settings-and-styles\/\">Global Settings and Styles (theme.json)<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/news\/2024\/10\/mastering-theme-json-you-might-not-need-css\/\">Mastering theme.json: You might not need CSS<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/global-settings-and-styles\/styles\/using-presets\/\">Using Presets<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/global-settings-and-styles\/styles\/styles-reference\/\">Styles Reference<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">2. theme.json \u2014 The <code>css<\/code> Property <\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> <code>theme.json<\/code> \u2192 <code>styles.css<\/code> (global) or <code>styles.blocks.[blockname].css<\/code> (per-block)<\/p>\n<p class=\"wp-block-paragraph\">When theme.json\u2019s structured properties aren\u2019t enough, you can drop to raw CSS strings within theme.json itself. Available since WordPress 6.2.<\/p>\n<h3 class=\"wp-block-heading\">Global custom CSS<\/h3>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>{\n  \"version\": 3,\n  \"styles\": {\n    \"css\": \".my-custom-class { opacity: 0.8; } body { scroll-behavior: smooth; }\"\n  }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>styles<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>css<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\".my-custom-class { opacity: 0.8; } body { scroll-behavior: smooth; }\"<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<h3 class=\"wp-block-heading\">Per-block custom CSS<\/h3>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>{\n  \"version\": 3,\n    \"styles\": {    \n       \"blocks\": {\n          \"core\/image\": {\n              \"css\": \"&amp; img { border-radius: 8px; transition: transform 0.3s; } &amp;:hover img { transform: scale(1.02); }\"\n              },     \n          \"core\/post-title\": {\n              \"css\": \"letter-spacing: 1px;\"\n             },\n         \"core\/paragraph\": {       \n              \"css\": \"&amp;.has-background { padding: .5rem .8rem; }\"\n           }\n        }\n    }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>styles<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span>    <\/span><\/span>\n<span class=\"line\"><span>       <\/span><span>\"<\/span><span>blocks<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>          <\/span><span>\"<\/span><span>core\/image<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>              <\/span><span>\"<\/span><span>css<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"&amp; img { border-radius: 8px; transition: transform 0.3s; } &amp;:hover img { transform: scale(1.02); }\"<\/span><\/span>\n<span class=\"line\"><span>              <\/span><span>},<\/span><span>     <\/span><\/span>\n<span class=\"line\"><span>          <\/span><span>\"<\/span><span>core\/post-title<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>              <\/span><span>\"<\/span><span>css<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"letter-spacing: 1px;\"<\/span><\/span>\n<span class=\"line\"><span>             <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>         <\/span><span>\"<\/span><span>core\/paragraph<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><span>       <\/span><\/span>\n<span class=\"line\"><span>              <\/span><span>\"<\/span><span>css<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"&amp;.has-background { padding: .5rem .8rem; }\"<\/span><\/span>\n<span class=\"line\"><span>           <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\">WordPress auto-generates the selector for per-block CSS\u2014you don\u2019t need to know the block\u2019s class name. The <code>&amp;<\/code> selector is supported for targeting nested elements and pseudo-selectors (<code>:before<\/code>, <code>:after<\/code>, <code>:hover<\/code>, <code>:not()<\/code>, etc.).<\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Integrates with the Styles interface in the Site Editor \u2014 users can see and modify your per-block CSS under Styles \u2192 Blocks \u2192 [Block] \u2192 Advanced \u2192 Additional CSS.<\/li>\n<li>WordPress handles the selector, so you avoid specificity conflicts.<\/li>\n<li>CSS from elements and variations is also supported (from WordPress 6.6).<\/li>\n<li>Provides a bridge between structured theme.json properties and full CSS freedom.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>JSON doesn\u2019t support line breaks, so everything must be on one line \u2014 cumbersome for large blocks of CSS.<\/li>\n<li>No syntax highlighting in JSON files.<\/li>\n<li>Best for small, targeted additions \u2014 for anything extensive, use block stylesheets instead.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/make.wordpress.org\/core\/2023\/03\/06\/custom-css-for-global-styles-and-per-block\/\">Custom CSS for global styles and per block<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">3. Custom CSS Properties (Variables) via theme.json Settings<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> <code>theme.json<\/code> \u2192 <code>settings.custom<\/code><\/p>\n<p class=\"wp-block-paragraph\">Create your own CSS custom properties that can be used anywhere in your CSS\u2014in stylesheets, block stylesheets, or even within the <code>css<\/code> property.<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>{\n  \"version\": 3,\n  \"settings\": {\n    \"custom\": {\n      \"contentMaxWidth\": \"800px\",\n      \"spacing\": {\n        \"gutter\": \"2rem\"\n      },\n      \"transition\": \"all 0.3s ease\"\n    }\n  }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>settings<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>custom<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>contentMaxWidth<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"800px\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>spacing<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>\"<\/span><span>gutter<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"2rem\"<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>transition<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"all 0.3s ease\"<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\">This generates:<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>body {\n  --wp--custom--content-max-width: 800px;\n  --wp--custom--spacing--gutter: 2rem;\n  --wp--custom--transition: all 0.3s ease;\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>body <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>--wp--custom--content-max-width<\/span><span>:<\/span><span> <\/span><span>800<\/span><span>px;<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>--wp--custom--spacing--gutter:<\/span><span> <\/span><span>2<\/span><span>rem;<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>--wp--custom--transition:<\/span><span> <\/span><span>all<\/span><span> <\/span><span>0.3<\/span><span>s<\/span><span> <\/span><span>ease;<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Centralized design tokens accessible from any CSS source.<\/li>\n<li>Automatic generation of CSS custom properties following WordPress naming conventions.<\/li>\n<li>Changes propagate everywhere the variable is used.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Only generates the variables \u2014 you still need to reference them in your CSS.<\/li>\n<li>Not directly editable by users in the Site Editor UI (unlike presets for colors or font sizes).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/news\/2023\/08\/adding-and-using-custom-settings-in-theme-json\/\">Adding and using custom settings in theme.json<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">4. Child Theme\u2019s <code>theme.json<\/code><\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Developers customizing a parent theme<br \/><strong>Where:<\/strong> <code>theme.json<\/code> in the child theme root<\/p>\n<p class=\"wp-block-paragraph\">Override or extend the parent theme\u2019s <code>theme.json<\/code> with a child theme. WordPress merges both files automatically.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>All changes survive parent theme updates.<\/li>\n<li>Full access to every theme.json capability \u2014 structured properties, css property, presets, and settings.<\/li>\n<li>Combined with block stylesheets and style.css, it provides a complete override system.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Requires maintaining a child theme.<\/li>\n<li>Merging behavior can be tricky: child values override parent values at the same path but won\u2019t remove parent values at other paths.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Theme Handbook: <a href=\"https:\/\/developer.wordpress.org\/themes\/advanced-topics\/child-themes\/\">Child Themes<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">5. Global Styles UI <\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Site owners, content editors (no code required)<br \/><strong>Where:<\/strong> <strong>Appearance \u2192 Editor \u2192 Styles<\/strong><\/p>\n<p class=\"wp-block-paragraph\">The visual interface for customizing your site\u2019s appearance. Users can adjust typography, colors, spacing, and layout for the entire site, individual elements, or specific block types \u2014 all without writing any code.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"wp-image-44500\" height=\"569\" src=\"https:\/\/i0.wp.com\/gutenbergtimes.com\/wp-content\/uploads\/2026\/02\/Screenshot-2026-02-24-at-18.40.45.png?resize=652%2C569&amp;ssl=1\" width=\"652\" \/><\/figure>\n<p class=\"wp-block-paragraph\">The <strong>Style Book<\/strong> helps you keep the overall context for your styles and you and double-check on how blocks behave when Styles change. <\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"wp-image-44499\" height=\"334\" src=\"https:\/\/i0.wp.com\/gutenbergtimes.com\/wp-content\/uploads\/2026\/02\/Screenshot-2026-02-24-at-18.38.39.png?resize=652%2C334&amp;ssl=1\" width=\"652\" \/><\/figure>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>No code required \u2014 fully visual.<\/li>\n<li>Highest specificity: user styles override theme defaults.<\/li>\n<li>Changes are stored in the database (<code>wp_global_styles<\/code> post type), separate from theme files, so they survive theme updates.<\/li>\n<li>Supports global style variations \u2014 users can switch between whole-site style presets.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Limited to what the UI controls expose (which grows with each WordPress release).<\/li>\n<li>For anything the UI can\u2019t handle, users fall back to the Additional CSS options below.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">6. Additional CSS <\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Site owners with CSS knowledge<br \/><strong>Where:<\/strong> Appearance \u2192 Editor \u2192 Styles \u2192 three-dot menu (\u22ee) \u2192 Additional CSS<\/p>\n<p class=\"wp-block-paragraph\">This is the block theme replacement for the classic Customizer\u2019s Additional CSS panel. A free-form CSS editor for site-wide custom styles.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Free-form CSS handles any valid CSS.<\/li>\n<li>Stored in the database as part of Global Styles (not in theme files), so it\u2019s theme-specific but survives code deployments.<\/li>\n<li>Preview changes before saving.<\/li>\n<li>Revision history (last 25 versions).<\/li>\n<li>Higher specificity than theme styles.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Not scoped to blocks \u2014 loads globally.<\/li>\n<li>No syntax highlighting or code formatting.<\/li>\n<li>Intended as a last resort for styles that can\u2019t be achieved through theme.json or the visual Styles interface.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">7. Per-Block Additional CSS <\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Site owners with CSS knowledge<br \/><strong>Where:<\/strong> Appearance \u2192 Editor \u2192 Styles \u2192 Blocks \u2192 select a block \u2192 scroll to Advanced \u2192 Additional CSS<\/p>\n<p class=\"wp-block-paragraph\">Target CSS to a specific block type site-wide. WordPress auto-generates the selector \u2014 you just write the CSS properties.<\/p>\n<figure class=\"wp-block-video wp-block-embed is-type-video is-provider-videopress\">\n<div class=\"wp-block-embed__wrapper\">\n<\/div>\n<\/figure>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>CSS<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>\/* Example: added to Styles \u2192 Blocks \u2192 Quote \u2192 Additional CSS *\/\nfont-style: italic;\nborder-left: 4px solid currentColor;\npadding-left: 1.5em;<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>\/*<\/span><span> Example: added to Styles \u2192 Blocks \u2192 Quote \u2192 Additional CSS <\/span><span>*\/<\/span><\/span>\n<span class=\"line\"><span>font-style<\/span><span>: italic;<\/span><\/span>\n<span class=\"line\"><span>border-left<\/span><span>: 4px solid currentColor;<\/span><\/span>\n<span class=\"line\"><span>padding-left<\/span><span>: 1.5em;<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\">The <code>&amp;<\/code> selector works here for nested elements and pseudo-selectors.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Scoped to a specific block type \u2014 only loads when that block is present on a page.<\/li>\n<li>No need to know CSS selectors \u2014 WordPress handles them.<\/li>\n<li>User-level styles (highest priority in the cascade).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Media queries may not work reliably (as of 2025). Use CSS functions like <code>clamp()<\/code>, <code>min()<\/code>, and <code>max()<\/code> for responsive behavior, or put responsive styles in theme-level CSS.<\/li>\n<li>Small text area with no code formatting.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">8. Additional CSS Class(es) on individual block instances<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Content editors with CSS knowledge<br \/><strong>Where:<\/strong> Select any block in the editor \u2192 Settings sidebar \u2192 Advanced \u2192 Additional CSS Class(es)<\/p>\n<p class=\"wp-block-paragraph\">Add custom class names to a specific block instance. The CSS itself must be defined elsewhere (style.css, block stylesheets, Additional CSS, etc.). As a user the global Additional CSS is probably the most practical place. <\/p>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Precision targeting of individual block instances rather than all blocks of a type.<\/li>\n<li>Perfect for one-off styling: a highlighted paragraph, a special call to action, etc.<\/li>\n<li>Multiple classes can be added, separated by spaces.<\/li>\n<li>Works with any CSS source \u2014 just define the class styles somewhere.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Only adds class names \u2014 you still need to write the CSS elsewhere.<\/li>\n<li>Per-instance, which means it doesn\u2019t scale well for repeated patterns (use block style variations for those).<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">9. Global Style Variations (Theme-Level Style Presets)<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> JSON files in the theme\u2019s <code>\/styles<\/code> directory (at the top level, not in a <code>\/blocks<\/code> subfolder)<\/p>\n<p class=\"wp-block-paragraph\">Provide entire alternative site-wide style schemes. Each variation is a JSON partial that can override settings and styles from the main theme.json. <\/p>\n<p class=\"wp-block-paragraph\">Since WordPress 6.6, style variations are further classified into three subtypes based on their content. <\/p>\n<p class=\"wp-block-paragraph\">A variation file that defines only <code>settings.color<\/code> or <code>styles.color<\/code> is automatically recognized as a <strong>color variation<\/strong>, appearing under <strong>Styles \u2192 Colors \u2192 Palette. <\/strong><\/p>\n<p class=\"wp-block-paragraph\">One that defines only <code>settings.typography<\/code> or <code>styles.typography<\/code> becomes a <strong>typography variation<\/strong>, appearing under <strong>Styles \u2192 Typography \u2192 Presets. <\/strong><\/p>\n<p class=\"wp-block-paragraph\">Files that touch other properties remain full <strong>theme style variations<\/strong>. <\/p>\n<p class=\"wp-block-paragraph\">Color and typography variations can be mixed and matched with each other and with theme variations. <\/p>\n<p class=\"wp-block-paragraph\">To keep the <code>\/styles<\/code> folder organized, it\u2019s recommended to use subfolders (e.g., <code>\/styles\/color<\/code>, <code>\/styles\/typography<\/code>, <code>\/styles\/global<\/code>). <\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>\/\/ \/styles\/dark-mode.json\n{\n  \"$schema\": \"https:\/\/schemas.wp.org\/trunk\/theme.json\",\n  \"version\": 3,\n  \"title\": \"Dark Mode\",\n  \"settings\": {\n    \"color\": {\n      \"palette\": [\n        { \"slug\": \"base\", \"color\": \"#1a1a2e\", \"name\": \"Base\" },\n        { \"slug\": \"contrast\", \"color\": \"#e0e0e0\", \"name\": \"Contrast\" }\n      ]\n    }\n  },\n  \"styles\": {\n    \"color\": {\n      \"background\": \"#1a1a2e\",\n      \"text\": \"#e0e0e0\"\n    }\n  }\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>\/\/<\/span><span> \/styles\/dark-mode.json<\/span><\/span>\n<span class=\"line\"><span>{<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>$schema<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"https:\/\/schemas.wp.org\/trunk\/theme.json\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>version<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>3<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>title<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Dark Mode\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>settings<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>palette<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>[<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"base\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#1a1a2e\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Base\"<\/span><span> <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>{<\/span><span> <\/span><span>\"<\/span><span>slug<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"contrast\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#e0e0e0\"<\/span><span>,<\/span><span> <\/span><span>\"<\/span><span>name<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"Contrast\"<\/span><span> <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>]<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>},<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>\"<\/span><span>styles<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>\"<\/span><span>color<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>background<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#1a1a2e\"<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>      <\/span><span>\"<\/span><span>text<\/span><span>\"<\/span><span>:<\/span><span> <\/span><span>\"#e0e0e0\"<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>  <\/span><span>}<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Users can switch between entire style schemes (light\/dark, color themes, typographic variations) from the Styles panel.<\/li>\n<li>Makes one theme feel like many \u2014 more versatile without requiring separate themes.<\/li>\n<li>Fully declarative (no PHP).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Only affects settings and styles \u2014 not templates or patterns.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/global-settings-and-styles\/style-variations\/\">Style Variations<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/news\/2024\/07\/mixing-and-matching-styles-colors-and-typography-in-wordpress-6-6\/\">Mixing and matching styles, colors, and typography in WordPress 6.6<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">10. Block Style Variations (JSON, PHP, and JavaScript)<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers, plugin developers<br \/><strong>Where:<\/strong> JSON files in <code>\/styles<\/code>, PHP via <code>register_block_style()<\/code>, or JavaScript via <code>wp.blocks.registerBlockStyle()<\/code><\/p>\n<p class=\"wp-block-paragraph\">Block style variations give content creators pre-made styling options in the Styles panel \u2014 like \u201cRounded\u201d or \u201cOutline\u201d on core blocks. You can register them via JSON files in <code>\/styles<\/code> (WordPress 6.6+, no PHP needed), PHP with <code>register_block_style()<\/code>, or JavaScript. The JSON-based methods integrate with Global Styles so users can customize them in the Site Editor; <code>inline_style<\/code>, <code>style_handle<\/code>, and JavaScript methods do not.<\/p>\n<p class=\"wp-block-paragraph\">For a thorough walkthrough of all six registration methods \u2014 with code examples, a companion theme and plugin on GitHub, and a comparison table showing which methods support Global Styles \u2014 see the comprehensive guide <strong><a href=\"https:\/\/wordpress.com\/blog\/2025\/05\/07\/custom-block-styles\/\">Mastering Custom Block Styles in WordPress: 6 Methods for Theme and Plugin Developers<\/a>.<\/strong><\/p>\n<h2 class=\"wp-block-heading\">11. Section Styles <\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> JSON files in <code>\/styles<\/code> directory, targeting mostly group or column blocks. <\/p>\n<p class=\"wp-block-paragraph\">Section styles are more of a convention than a separate feature. They are essentially Block Style Variations. The difference is naming the variation slug: <code>style-1<\/code>, <code>style-2<\/code>, etc. so that they can be reused across themes.<\/p>\n<p class=\"wp-block-paragraph\">Since WordPress 6.6, block style variations can style nested inner blocks and elements, enabling \u201csection styling\u201d \u2014 where a Group block\u2019s style variation changes the appearance of all blocks within it.<\/p>\n<p class=\"wp-block-paragraph\">The Twenty Twenty Five theme showcases this convention quite nicely. <\/p>\n<figure class=\"wp-block-jetpack-videopress jetpack-videopress-player\">\n<div class=\"jetpack-videopress-player__wrapper\"> <\/div>\n<\/figure>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Apply coordinated styles to entire sections (background, text color, button colors, link colors) with a single click.<\/li>\n<li>Users select the section style in the block\u2019s Styles panel.<\/li>\n<li>Powerful for creating consistent design sections (hero areas, dark sections, testimonials).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Easy to overwhelm users with too many section style options \u2014 restraint is needed.<\/li>\n<li>Requires careful design token architecture (using base\/contrast\/primary\/secondary color naming).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/make.wordpress.org\/core\/2024\/06\/24\/section-styles\/\">Section Styles<\/a> (WordPress 6.6)<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">12. Block Stylesheets via <code>wp_enqueue_block_style()<\/code><\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> Separate <code>.css<\/code> files in your theme (e.g., <code>\/assets\/blocks\/core-image.css<\/code>), registered in <code>functions.php<\/code><\/p>\n<p class=\"wp-block-paragraph\">This is the recommended approach when you have more CSS than what\u2019s comfortable in theme.json\u2019s <code>css<\/code> property.<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>\/* \/assets\/blocks\/core-image.css *\/\n.wp-block-image img {\n    padding: 1rem;\n    background: linear-gradient(-60deg, #ff5858, #f09819);\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>\/*<\/span><span> \/assets\/blocks\/core-image.css <\/span><span>*\/<\/span><\/span>\n<span class=\"line\"><span>.wp-block-image img <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>padding<\/span><span>:<\/span><span> <\/span><span>1<\/span><span>rem;<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>background:<\/span><span> <\/span><span>linear-gradient(<\/span><span>-60<\/span><span>deg<\/span><span>,<\/span><span> <\/span><span>#ff5858,<\/span><span> <\/span><span>#f09819);<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>JSON<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>\/\/ functions.php\nadd_action( 'init', function() {\n    wp_enqueue_block_style( 'core\/image', array(\n        'handle' =&gt; 'my-theme-image-styles',\n        'src'    =&gt; get_theme_file_uri( 'assets\/blocks\/core-image.css' ),\n        'path'   =&gt; get_theme_file_path( 'assets\/blocks\/core-image.css' ),\n    ) );\n});<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>\/\/<\/span><span> functions.php<\/span><\/span>\n<span class=\"line\"><span>add_action( 'init', function() <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>wp_enqueue_block_style(<\/span><span> <\/span><span>'core\/image',<\/span><span> <\/span><span>array(<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'handle'<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>'my-theme-image-styles',<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'src'<\/span><span>    <\/span><span>=&gt;<\/span><span> <\/span><span>get_theme_file_uri(<\/span><span> <\/span><span>'assets\/blocks\/core-image.css'<\/span><span> <\/span><span>),<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'path'<\/span><span>   <\/span><span>=&gt;<\/span><span> <\/span><span>get_theme_file_path(<\/span><span> <\/span><span>'assets\/blocks\/core-image.css'<\/span><span> <\/span><span>),<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>)<\/span><span> <\/span><span>);<\/span><\/span>\n<span class=\"line\"><span>}<\/span><span>);<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Performance:<\/strong> CSS only loads when the block is actually present on the page. WordPress inlines it in the <code>&lt;head&gt;<\/code> section<\/li>\n<li>Full CSS syntax with syntax highlighting, multi-line formatting, and preprocessor support (Sass\/SCSS).<\/li>\n<li>Clean code organization \u2014 one file per block.<\/li>\n<li>Works for any CSS, including media queries, animations, complex selectors, and pseudo-elements.<\/li>\n<li>Applies in both the editor and front end.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Requires PHP registration in functions.php.<\/li>\n<li>These styles aren\u2019t exposed in the Global Styles UI for user editing.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/features\/block-stylesheets\/\">Block Stylesheets<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/news\/2022\/12\/leveraging-theme-json-and-per-block-styles-for-more-performant-themes\/\">Leveraging theme.json and per-block styles for more performant themes<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">13. Enqueuing Stylesheets via <code>wp_enqueue_style()<\/code> in PHP<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme and plugin developers<br \/><strong>Where:<\/strong> <code>functions.php<\/code> using the <code>wp_enqueue_scripts<\/code> (front end) and <code>enqueue_block_editor_assets<\/code> (editor) hooks<\/p>\n<p class=\"wp-block-paragraph\">The traditional WordPress approach still works and is useful for loading third-party CSS libraries, fonts, or complex stylesheets. <\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>PHP<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>add_action( 'wp_enqueue_scripts', function() {\n    wp_enqueue_style(\n        'my-theme-custom',\n        get_theme_file_uri( 'assets\/css\/custom.css' ),\n        array(),\n        '1.0.0'\n    );\n});\n\n\/\/ For editor-only styles:\nadd_action( 'enqueue_block_editor_assets', function() {\n    wp_enqueue_style(\n        'my-theme-editor',\n        get_theme_file_uri( 'assets\/css\/editor.css' ),\n        array(),\n        '1.0.0'\n    );\n});<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>add_action<\/span><span>(<\/span><span> <\/span><span>'wp_enqueue_scripts'<\/span><span>,<\/span><span> <\/span><span>function<\/span><span>()<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>wp_enqueue_style<\/span><span>(<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'my-theme-custom'<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>get_theme_file_uri<\/span><span>(<\/span><span> <\/span><span>'assets\/css\/custom.css'<\/span><span> <\/span><span>),<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>array<\/span><span>(),<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'1.0.0'<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>);<\/span><\/span>\n<span class=\"line\"><span>});<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span>\/\/<\/span><span> For editor-only styles:<\/span><\/span>\n<span class=\"line\"><span>add_action<\/span><span>(<\/span><span> <\/span><span>'enqueue_block_editor_assets'<\/span><span>,<\/span><span> <\/span><span>function<\/span><span>()<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>wp_enqueue_style<\/span><span>(<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'my-theme-editor'<\/span><span>,<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>get_theme_file_uri<\/span><span>(<\/span><span> <\/span><span>'assets\/css\/editor.css'<\/span><span> <\/span><span>),<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>array<\/span><span>(),<\/span><\/span>\n<span class=\"line\"><span>        <\/span><span>'1.0.0'<\/span><\/span>\n<span class=\"line\"><span>    <\/span><span>);<\/span><\/span>\n<span class=\"line\"><span>});<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Full control over loading conditions (you can conditionally enqueue based on page, template, user role, etc.).<\/li>\n<li>Familiar to all WordPress developers.<\/li>\n<li>Can load external stylesheets, Google Fonts, icon libraries, etc.<\/li>\n<li>Supports dependencies, versioning, and media attributes.<\/li>\n<li>Can target editor-only or front-end-only.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Loads on every page (unless you add conditional logic).<\/li>\n<li>No integration with the Global Styles UI.<\/li>\n<li>Doesn\u2019t benefit from the block stylesheet system\u2019s per-block inlining.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/enqueueing-assets-in-the-editor\/#editor-scripts-and-styles\">Enqueueing assets in the Editor<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/core-concepts\/including-assets\/#editor-stylesheets\" rel=\"noreferrer noopener\" target=\"_blank\">Editor Stylesheets<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/hooks\/wp_enqueue_scripts\/\">do_action( \u2018wp_enqueue_scripts\u2019 )<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_enqueue_style\/\">wp_enqueue_style( string $handle, string $src, string[] $deps = array(), string|bool|null $ver = false, string $media )<\/a><\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">What\u2019s the difference between wp_enqueue_style and add_editor_style?<\/h3>\n<p class=\"wp-block-paragraph\"><code>wp_enqueue_style()<\/code> is the general-purpose function for loading stylesheets \u2014 you choose where it loads by picking your hook (<code>wp_enqueue_scripts<\/code> for the frontend, <code>enqueue_block_editor_assets<\/code> for the editor). When you use it on the editor hook, the stylesheet loads into the entire editor page, including the UI chrome (sidebar, toolbar, etc.).<\/p>\n<p class=\"wp-block-paragraph\"><code>add_editor_style()<\/code> is specifically designed for visual parity between the editor and the frontend. WordPress takes the stylesheet you pass it and automatically scopes every selector to <code>.editor-styles-wrapper<\/code>, so your styles only affect the content canvas and don\u2019t bleed into the editor UI. In block themes it\u2019s typically called from an <code>after_setup_theme<\/code> hook \u2014 this is how themes get their <code>style.css<\/code> to apply inside the editor.<\/p>\n<p class=\"wp-block-paragraph\">The practical upshot: if you want your theme\u2019s frontend styles to look the same in the editor, use <code>add_editor_style()<\/code>. If you need to style the editor UI itself (like a custom sidebar panel) or need fine-grained control over loading conditions, dependencies, and versioning, use <code>wp_enqueue_style()<\/code> on the appropriate hook.<\/p>\n<h2 class=\"wp-block-heading\">14. The Theme\u2019s <code>style.css<\/code><\/h2>\n<p class=\"wp-block-paragraph\"><strong>Who:<\/strong> Theme developers<br \/><strong>Where:<\/strong> <code>style.css<\/code> in the theme root<\/p>\n<p class=\"wp-block-paragraph\">The traditional main stylesheet still works in block themes, but its role has changed significantly. It now primarily holds theme metadata (name, version, description) and is loaded globally. <\/p>\n<p class=\"wp-block-paragraph\">In block themes it\u2019s typically called from an <code>after_setup_theme<\/code> hook \u2014 this is how themes get their <code>style.css<\/code> to apply inside the editor.<\/p>\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\"><span>PHP<\/span><span class=\"code-block-pro-copy-button\">\n<pre class=\"code-block-pro-copy-button-pre\"><textarea class=\"code-block-pro-copy-button-textarea\" readonly>add_action( 'after_setup_theme', 'theme_slug_setup' );\n\nfunction theme_slug_setup() {\n\tadd_editor_style( get_stylesheet_uri() );\n}<\/textarea><\/pre>\n<p><\/p><\/span>\n<pre class=\"shiki rose-pine-dawn\"><code><span class=\"line\"><span>add_action<\/span><span>(<\/span><span> <\/span><span>'after_setup_theme'<\/span><span>,<\/span><span> <\/span><span>'theme_slug_setup'<\/span><span> <\/span><span>);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span>function<\/span><span> <\/span><span>theme_slug_setup<\/span><span>()<\/span><span> <\/span><span>{<\/span><\/span>\n<span class=\"line\"><span>\t<\/span><span>add_editor_style<\/span><span>(<\/span><span> <\/span><span>get_stylesheet_uri<\/span><span>()<\/span><span> <\/span><span>);<\/span><\/span>\n<span class=\"line\"><span>}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"wp-block-paragraph\"><strong>Advantages:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Familiar workflow for developers with classic theme experience.<\/li>\n<li>Good for truly global CSS that should always be available (e.g., custom utility classes, print styles, CSS resets beyond what theme.json handles).<\/li>\n<li>Full CSS syntax, syntax highlighting, and preprocessor support.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Limitations:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Needs to be enqueued like any other stylesheet file (see #13)  <\/li>\n<li>Loads on every page, even if the styles aren\u2019t needed \u2014 no per-block performance optimization.<\/li>\n<li>Not integrated with the Global Styles UI.<\/li>\n<li>Not the recommended approach for block-specific styling; use block stylesheets instead (#12)<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\"><strong>Documentation<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.wordpress.org\/themes\/core-concepts\/main-stylesheet\/\">Main Stylesheet (style.css)<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Summary Table<\/h2>\n<figure class=\"wp-block-table alignwide is-style-stripes\">\n<table>\n<thead>\n<tr>\n<th>#<\/th>\n<th>Method<\/th>\n<th>Who<\/th>\n<th>Scope<\/th>\n<th>Loads When<\/th>\n<th>Editable by Users<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>theme.json structured properties<\/td>\n<td>Developer<\/td>\n<td>Global \/ block \/ element<\/td>\n<td>Always (inlined)<\/td>\n<td>Yes, via Global Styles UI<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>theme.json <code>css<\/code> property<\/td>\n<td>Developer<\/td>\n<td>Global or per-block<\/td>\n<td>Always (inlined)<\/td>\n<td>Yes, per-block CSS is visible in Styles<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>Custom CSS properties (<code>settings.custom<\/code>)<\/td>\n<td>Developer<\/td>\n<td>Global (variables)<\/td>\n<td>Always<\/td>\n<td>No (indirectly via tokens)<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Child theme.json<\/td>\n<td>Developer<\/td>\n<td>Inherits parent<\/td>\n<td>Same as parent<\/td>\n<td>Same as parent<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>Global Styles UI (visual)<\/td>\n<td>User<\/td>\n<td>Global \/ block \/ element<\/td>\n<td>Always (inlined)<\/td>\n<td>It <em>is<\/em> the user editing<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>Additional CSS (site-wide)<\/td>\n<td>User<\/td>\n<td>Global<\/td>\n<td>Every page<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>Per-block Additional CSS<\/td>\n<td>User<\/td>\n<td>Per-block type<\/td>\n<td>When block present<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>Additional CSS Class(es)<\/td>\n<td>User<\/td>\n<td>Single block instance<\/td>\n<td>When that block is present<\/td>\n<td>N\/A (class only)<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>Global style variations<\/td>\n<td>Developer<\/td>\n<td>Whole site preset<\/td>\n<td>When active<\/td>\n<td>Users switch presets<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>Block style variations (JSON, PHP, JS)<\/td>\n<td>Developer<\/td>\n<td>Per-block variation<\/td>\n<td>Only when block + variation is used<\/td>\n<td>JSON\/<code>style_data<\/code> methods: yes; <code>inline_style<\/code>\/JS: no<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>Section styles<\/td>\n<td>Developer<\/td>\n<td>container blocks <\/td>\n<td>When block + variation is used<\/td>\n<td>Yes, via Styles panel<\/td>\n<\/tr>\n<tr>\n<td>12 <\/td>\n<td>Block stylesheets (<code>wp_enqueue_block_style<\/code>)<\/td>\n<td>Developer<\/td>\n<td>Per-block<\/td>\n<td>Only when block is present<\/td>\n<td>No<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td><code>wp_enqueue_style()<\/code><\/td>\n<td>Developer<\/td>\n<td>Configurable<\/td>\n<td>Configurable<\/td>\n<td>No<\/td>\n<\/tr>\n<tr>\n<td>14<\/td>\n<td><code>style.css<\/code><\/td>\n<td>Developer<\/td>\n<td>Global<\/td>\n<td>Every page<\/td>\n<td>No<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2 class=\"wp-block-heading\">Decision Guide<\/h2>\n<p class=\"wp-block-paragraph\"><strong>Start here:<\/strong> Use <strong>theme.json structured properties<\/strong> (#1) for everything they support. This gives you the best integration with the Global Styles system and lets users customize your styles.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Need CSS that theme.json properties can\u2019t express?<\/strong> Use the <strong>theme.json <code>css<\/code> property<\/strong> (#2) for small additions or <strong>block stylesheets<\/strong> (#12) for anything substantial.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Want to offer style choices to content editors?<\/strong> Create <strong>block style variations<\/strong> (#10) so they appear in the Styles panel.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Site owner making tweaks?<\/strong> Use the <strong>Global Styles UI<\/strong> (#5) first, then fall back to <strong>Additional CSS<\/strong> (#7 or #7) for anything the visual interface can\u2019t handle.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Need to target one specific block instance?<\/strong> Use <strong>Additional CSS Class(es)<\/strong> (#8) and define the class in your preferred CSS source.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Building a child theme?<\/strong> Override the parent via <strong>child theme.json<\/strong> (#4) and add block stylesheets as needed.<\/p>\n<p class=\"wp-block-paragraph\"><strong>Need to sync user edits with theme files<\/strong>? Use the <a href=\"https:\/\/wordpress.org\/plugins\/create-block-theme\/\">Create Block Theme plugin<\/a>. <\/p>\n<p class=\"wp-block-paragraph\"><strong>How to sync user editor to theme files and maintain version control?<\/strong> Here is a tutorial: <a href=\"https:\/\/developer.wordpress.org\/news\/2026\/01\/streamlining-block-theme-development-with-wordpress-playground-and-github\/\">Streamlining block theme development with WordPress Playground and GitHub<\/a>.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\" \/>\n<p class=\"wp-block-paragraph\"><em>Huge Thank you to Justin Tadlock for reviewing the post to make sure it\u2019s all technically accurate. <\/em><\/p>","protected":false},"excerpt":{"rendered":"<p>With the new Custom CSS on a block and post\/page level, I was wondering if I would know where to look if something needs to be changed that was modified by a Custom CSS setting. Turns out there are 14 different ways to skin WordPress. I am a fan of keeping one source of truth, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":552,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-551","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/posts\/551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=551"}],"version-history":[{"count":0,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/posts\/551\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/media\/552"}],"wp:attachment":[{"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xn--mnchen-3ya.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}