CSS @layer: Managing Cascade Layers in WordPress Themes

CSS @layer lets you define explicit cascade layers so that low-priority utility styles never accidentally override your component styles, regardless of selector specificity. This is especially useful in WordPress themes that load both Gutenberg base styles and your own CSS.

Problem: Third-party plugin stylesheets and WordPress block styles frequently override theme styles in unexpected ways — the cascade order is unpredictable and !important workarounds create escalating specificity conflicts.

Solution: Use CSS @layer to explicitly declare the cascade order at the top of your stylesheet — lower layers lose to higher ones regardless of specificity. Assign third-party styles, base resets, and block editor overrides to named layers so your theme styles always win without !important.

The examples below declare a layer order, assign third-party and base styles to lower layers, and show how block-editor styles can be scoped to a named layer so they never beat your theme layer.

/* 1. Declare layer order first — later layers win */
@layer reset, base, wordpress, components, utilities, theme;

/* 2. Put third-party / reset styles in a low-priority layer */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; margin: 0; }
}

/* 3. Enqueue WordPress block styles inside their own layer */
@layer wordpress {
  @import url("https://example.com/wp-includes/css/dist/block-library/style.min.css");
}

/* 4. Your theme rules always win because 'theme' is declared last */
@layer theme {
  .wp-block-image img {
    border-radius: 8px;
    box-shadow: 0 2px 8px rgb(0 0 0 / .15);
  }
  .entry-content p { line-height: 1.75; }
}

Anonymous (unlayered) styles still beat all named layers — so any rule you write outside a layer retains the highest priority:

/* Unlayered — beats every @layer */
.site-header { position: sticky; top: 0; z-index: 100; }

/* Inside a layer — can be overridden by unlayered rules or higher layers */
@layer components {
  .card { padding: 1rem; border: 1px solid #ddd; border-radius: 4px; }
  .card:hover { box-shadow: 0 4px 12px rgb(0 0 0 / .1); }
}

/* Layer nesting is also valid */
@layer utilities {
  @layer spacing {
    .mt-4 { margin-top: 1rem; }
    .mb-4 { margin-bottom: 1rem; }
  }
  @layer text {
    .text-center { text-align: center; }
    .text-muted { color: #6c757d; }
  }
}

NOTE: Use @layer in WordPress by enqueuing a stylesheet that starts with the layer declarations, or add it inline with wp_add_inline_style() before the first stylesheet that uses layers.

Leave Comment

Your email address will not be published. Required fields are marked *