These 2 guys

dgw.ltd September 26, 2025
Source

These two lines of 11ty code have really helped me increasingly over the last year or so // Read and parse the WP theme.json file const themeJSON = JSON.parse(await readFile(new URL('./theme.json', import.meta.url))); // Add theme settings to Eleventy global data eleventyConfig.addGlobalData('theme', themeJSON); I love design systems and I try where possible to stuff as much as I can into theme.json as this is our main source of truth when building WordPress websites. Another thing that’s increasingly helped me is popping 11ty into my WordPress themes, inception style (BRAAAM) to create a bunch of utilities, sw.njk > sw.js for my service worker, offline html files and so on. One of these utilities was to generate CSS via the theme.json file, for use outside of WordPress if I need the global settings and styles for whatever reason (vendor website, static site etc). Again we want to keep our single source of truth as singular as possible. Previously I generated my utility classes via a SASS map and loop…pretty decent: // Define the map with sizes and their corresponding values $sizes: ( sm: var(--wp--custom--spacing--xs), md: var(--wp--custom--spacing--md), lg: var(--wp--custom--spacing--lg), xl: var(--wp--custom--spacing--xl) ); // Loop through the map to generate utility classes for margins and paddings @each $size, $value in $sizes { .mt-#{$size} { margin-block-start: #{$value}; } .mb-#{$size} { margin-block-end: #{$value}; } .pt-#{$size} { padding-block-start: #{$value}; } .pb-#{$size} { padding-block-end: #{$value}; } } However, recently as I finally started the excellent Complete CSS Course from Piccalilli, I was looking at the generated tokens they use via Tailwind. I considered using something similar for margin and padding CSS utilities classes outside of the WordPress presets and custom settings (var(–wp–custom–spacing–md)) then remembered I have the above method for extracting our tokens from theme.json. So I fired up a quick file called wp-utils.njk, that outputs to my scss folder to be consumed back into our stylesheet with the following code: --- permalink: '../src/assets/scss/modules/_utilities-wp.scss' --- {%- set spacingSizes = theme.settings.custom.spacing -%} {%- set includeKeys = ['xs', 'sm', 'md', 'lg'] -%} {%- for key, value in spacingSizes -%} {%- if key in includeKeys -%} {%- if value is mapping -%} {# check whether the value is a nested #} {%- for subkey, subvalue in value %} /* Padding utilities - {{ key }} / .pt-{{ key }}-{{ subkey }} { padding-block-start: {{ subvalue }}; } .pb-{{ key }}-{{ subkey }} { padding-block-end: {{ subvalue }}; } .pl-{{ key }}-{{ subkey }} { padding-inline-start: {{ subvalue }}; } .pr-{{ key }}-{{ subkey }} { padding-inline-end: {{ subvalue }}; } .px-{{ key }}-{{ subkey }} { padding-inline: {{ subvalue }}; } .py-{{ key }}-{{ subkey }} { padding-block: {{ subvalue }}; } .p-{{ key }}-{{ subkey }} { padding: {{ subvalue }}; } / Margin utilities - {{ key }} / .mt-{{ key }}-{{ subkey }} { margin-block-start: {{ subvalue }}; } .mb-{{ key }}-{{ subkey }} { margin-block-end: {{ subvalue }}; } .ml-{{ key }}-{{ subkey }} { margin-inline-start: {{ subvalue }}; } .mr-{{ key }}-{{ subkey }} { margin-inline-end: {{ subvalue }}; } .mx-{{ key }}-{{ subkey }} { margin-inline: {{ subvalue }}; } .my-{{ key }}-{{ subkey }} { margin-block: {{ subvalue }}; } .m-{{ key }}-{{ subkey }} { margin: {{ subvalue }}; } {%- endfor %} {%- else %} / Padding utilities - {{ key }} / .pt-{{ key }} { padding-block-start: {{ value }}; } .pb-{{ key }} { padding-block-end: {{ value }}; } .pl-{{ key }} { padding-inline-start: {{ value }}; } .pr-{{ key }} { padding-inline-end: {{ value }}; } .px-{{ key }} { padding-inline: {{ value }}; } .py-{{ key }} { padding-block: {{ value }}; } .p-{{ key }} { padding: {{ value }}; } / Margin utilities - {{ key }} / .mt-{{ key }} { margin-block-start: {{ value }}; } .mb-{{ key }} { margin-block-end: {{ value }}; } .ml-{{ key }} { margin-inline-start: {{ value }}; } .mr-{{ key }} { margin-inline-end: {{ value }}; } .mx-{{ key }} { margin-inline: {{ value }}; } .my-{{ key }} { margin-block: {{ value }}; } .m-{{ key }} { margin: {{ value }}; } {%- endif -%} {%- endif -%} {%- endfor -%} / Auto margins / .mx-auto { margin-inline: auto; } .my-auto { margin-block: auto; } .m-auto { margin: auto; } .ml-auto { margin-inline-start: auto; } .mr-auto { margin-inline-end: auto; } .mt-auto { margin-block-start: auto; } .mb-auto { margin-block-end: auto; } / Zero spacing / .p-0 { padding: 0; } .m-0 { margin: 0; } .pt-0 { padding-block-start: 0; } .pb-0 { padding-block-end: 0; } .pl-0 { padding-inline-start: 0; } .pr-0 { padding-inline-end: 0; } .mt-0 { margin-block-start: 0; } .mb-0 { margin-block-end: 0; } .ml-0 { margin-inline-start: 0; } .mr-0 { margin-inline-end: 0; } Note we need to check incase there is any nesting in our JSON: flat: "spacing": { "sm": "1rem", "md": "2rem", "lg": "3rem" } vs nested "spacing": { "gutter": { "xs": "0.5rem" "sm": "1rem", "md": "2rem" }, "section": { "sm": "2rem", "lg": "4rem" } } And we get this out the other side: / Padding utilities - xs / .pt-xs { padding-block-start: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .pb-xs { padding-block-end: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .pl-xs { padding-inline-start: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .pr-xs { padding-inline-end: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .px-xs { padding-inline: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .py-xs { padding-block: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .p-xs { padding: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } / Margin utilities - xs / .mt-xs { margin-block-start: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .mb-xs { margin-block-end: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .ml-xs { margin-inline-start: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .mr-xs { margin-inline-end: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .mx-xs { margin-inline: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .my-xs { margin-block: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } .m-xs { margin: clamp(0.8125rem, 0.7786rem + 0.1695vi, 0.9375rem); } / Padding utilities - sm / .pt-sm { padding-block-start: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .pb-sm { padding-block-end: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .pl-sm { padding-inline-start: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .pr-sm { padding-inline-end: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .px-sm { padding-inline: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .py-sm { padding-block: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .p-sm { padding: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } / Margin utilities - sm / .mt-sm { margin-block-start: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .mb-sm { margin-block-end: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .ml-sm { margin-inline-start: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .mr-sm { margin-inline-end: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .mx-sm { margin-inline: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .my-sm { margin-block: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } .m-sm { margin: clamp(1.0625rem, 1.0117rem + 0.2542vi, 1.25rem); } ........... / Auto margins / .mx-auto { margin-inline: auto; } .my-auto { margin-block: auto; } .m-auto { margin: auto; } .ml-auto { margin-inline-start: auto; } .mr-auto { margin-inline-end: auto; } .mt-auto { margin-block-start: auto; } .mb-auto { margin-block-end: auto; } / Zero spacing */ .p-0 { padding: 0; } .m-0 { margin: 0; } .pt-0 { padding-block-start: 0; } .pb-0 { padding-block-end: 0; } .pl-0 { padding-inline-start: 0; } .pr-0 { padding-inline-end: 0; } .mt-0 { margin-block-start: 0; } .mb-0 { margin-block-end: 0; } .ml-0 { margin-inline-start: 0; } .mr-0 { margin-inline-end: 0; }

Discussion in the ATmosphere

Loading comments...