Scoped Dynamic CSS
Write per-block CSS with {{ }} expressions inside CSS values. Each block’s styles are automatically wrapped in @scope so they only apply to the block they’re attached to — zero global leakage.
How It Works
The Style Editor field in the Vector Expressions sidebar accepts raw CSS. Expressions embedded inside the CSS are evaluated server-side on every render, enabling data-driven styles.
/* In the Style Editor field: */
background-color: {{ post.meta.brand_color | default "#1a1a2e" }};
padding: {{ post.meta.card_padding | default "2rem" }};
font-size: {{ post.meta.heading_size | default "1.5rem" }};
Rendered Output
Each block is stamped with a unique data-vep attribute. The CSS is wrapped in an @scope rule targeting that attribute, so styles are perfectly isolated:
<div data-vep="vectexpro-a1b2c3d4" class="wp-block-group">
<!-- block content -->
<style>
@scope ([data-vep="vectexpro-a1b2c3d4"]) {
:scope {
background-color: #1a1a2e;
padding: 2rem;
font-size: 1.5rem;
}
}
</style>
</div>
Scope Limiting
For advanced layouts, you can set a lower boundary using the @scope (...) to (...) syntax via the Scope Limit field. This ensures styles apply only between the block and a specified descendant selector boundary.
/* Styles apply to the block but stop at any nested .card elements */
@scope ([data-vep="..."]) to (.card) {
:scope { padding: 2rem; }
}
Use Cases
- Brand-colored cards —
background-color: {{ post.meta.brand_color }} - Responsive spacing from meta —
padding: {{ post.meta.section_padding | default "3rem" }} - Dynamic grid columns —
grid-template-columns: repeat({{ post.meta.columns | default 3 }}, 1fr) - User-personalized themes —
color: {{ user.meta.preferred_color | default "#333" }}