Overview: HTML and CSS Generation
When creating content in the block editor, users generate:- HTML document - Block structure and content
- CSS stylesheets - Styling for the content (embedded or external)
Stylesheets Loaded on Frontend
1. Block Styles Stylesheets that come with blocks:- Single stylesheet with all block styles (
wp-block-library-*) - Or separate stylesheets per block (
wp-block-group-*,wp-block-columns-*)
theme.json data:
- Output as embedded stylesheet:
global-styles-inline-css - Merges WordPress defaults, theme.json, and user preferences
- Traditional theme stylesheets (e.g.,
twentytwentytwo-style-css) - Plus styles from theme.json (merged into global styles)
- Duotone filters
- Layout styles
- Link colors
Block Supports API
Block Supports is an API that allows blocks to declare styling features they support.How It Works
By adding configuration toblock.json, blocks automatically get:
- UI controls for users
- Data binding to block attributes
- Serialization to HTML markup
Example Configuration
- Font size picker in the block toolbar
- Line height control in the inspector
- Color pickers for text and background
- Proper serialization to HTML classes and inline styles
From UI to HTML Markup
The Block Supports API handles four essential pieces: 1. UI Control Presents choices to users (e.g., font size picker) 2. Block Attribute Stores the user’s selection in block data 3. Style Data Access Retrieves available presets (colors, font sizes) from theme.json 4. Serialization Converts block data to HTML markup with appropriate classes/stylesSerialization Example
User selects small font size → HTML output:Benefits
Less Code: Achieve complex styling features with minimal configuration Consistency: Use the same UI controls across all blocks Automatic Updates: UI improvements apply to all blocks automatically Cross-Platform: Style information available in native mobile apps and on the serverLimitations
1. One Style Type Per Block
Blocks can only have one instance of each style property. Example Problem: A table block can only have one font size—not separate sizes for header, body, and footer.2. Styles Apply to Wrapper Only
Block supports serialize styles to the outermost HTML node:<tbody> directly.
Skip Serialization Escape Hatch
For advanced use cases, use__experimentalSkipSerialization:
edit, save, and render_callback.
Skip Specific Properties:
fontSize skips serialization; lineHeight still auto-serializes.
Global Styles
Global Styles generates site-wide styles fromtheme.json data. Unlike block styles, these are not serialized into post content.
The Three-Layer Merge
Architectural Decision:Styles system: Three-layer merge — WordPress defaults <theme.json< user preferences. Use Block Supports API and CSS custom properties (--wp--preset--*), not hardcoded values.
Data Flow
Processing Steps
1. Gather Data
WordPress Defaults: From bundledtheme.json in WordPress core
Theme Data:
From active theme’s theme.json file (if exists)
User Data:
From database (saved via Global Styles UI in Site Editor)
2. Consolidate Data
Normalize Versions: Different sources may use different theme.json versions (v1, v2, etc.) Merge Styles: User styles override theme styles, which override WordPress defaults Example:3. Convert to CSS
Styles to CSS Rules:CSS Selector Generation
Top-level:body selector
Elements: ID selector matching HTML element (h1, a)
Blocks: Default class name (.wp-block-group) or custom via __experimentalSelector in block.json
Elements in blocks: Concatenated selector (.wp-block-group h1)
Limitations
1. Server Registration Required for Custom Selectors
Blocks using__experimentalSelector must be registered on the server via block.json, or Global Styles will use the default selector.
2. Single Selector Per Block
Each block chunk can only use one selector—cannot target different HTML nodes for different styles.3. One Property Per Block
Same limitation as Block Supports—only one instance of each style property.4. Block Supports Required for UI
Only blocks using Block Supports appear in the Global Styles UI panel.Layout Styles
Layout styles provide common styling for container blocks (Group, Row, Columns, Buttons, Social Icons).Base Layout Styles
Common styles for all blocks using a layout type:display: flexfor Flex layout blocks- Default max-width for constrained layouts
- Output in global styles stylesheet
- Always included for core block support
Individual Layout Styles
Generated per block when rendered: Semantic Class Names:Layout Types
Default/Flow: Vertical stack with margin-based spacing Constrained: Vertical stack with max-width constraints Flex: Flexbox layout with gap-based spacing Grid: Grid layout with gap-based spacingSemantic Class Names
is-layout-flow,is-layout-constrained,is-layout-flex,is-layout-gridis-horizontal,is-verticalis-content-justification-left/center/right/space-betweenis-nowrapwp-container-$id(avoid targeting directly)
Best Practices
Use Block Supports
Prefer Block Supports API over manual implementation for standard styling needs.Use CSS Custom Properties
Reference preset values via CSS custom properties:Avoid Hardcoded Values
Don’t hardcode colors, font sizes, etc.—use theme.json presets.Target Blocks Correctly
Use block class names (.wp-block-group) and semantic layout classes, not container IDs.