CSS @private At-Rule
The @private at-rule is an experimental CSS feature for defining custom properties that are private to a style rule and its nested rules. It helps avoid name collisions and keeps intermediate values from becoming ordinary inherited custom properties.
Syntax
The rule must be nested inside a style rule or a nested group rule within a style rule. It is not valid at the top level of a stylesheet.
@private {
--local-name: value;
}
How @private Works
The local name is available to declarations in the same style rule and its nested rules. It is distinct from an ordinary custom property of the same name outside that scope.
.panel {
@private {
--accent: #0066aa;
}
border-color: var(--accent);
}
The proposed rule declares private custom properties scoped to the containing style rule and its nested rules. Unlike ordinary inherited custom properties, these names are intended for internal intermediate values.
Private Property Scope
The nested .label rule can use the private value, while .other refers to an unrelated ordinary custom property. Private variables are not a security mechanism; they are a scoping mechanism.
.panel {
@private {
--gap: 12px;
}
padding: var(--gap);
& > .label {
margin-bottom: var(--gap);
}
}
.other {
margin-bottom: var(--gap, 4px);
}
A declaration outside the relevant style rule cannot depend on the private value. Keep public configuration in ordinary custom properties and use private variables only for implementation details.
Nested Group Rules
Private names are also available in nested conditional rules within the same style-rule scope. A @private block may contain custom property declarations and nested group rules, but not arbitrary styling declarations.
.card {
@private {
--accent: #0077aa;
}
@media (min-width: 700px) {
border-color: var(--accent);
}
}
Using @private With Mixins
The CSS mixins draft uses private properties to keep intermediate calculations and parameters from conflicting with ordinary element styles. @mixin and @apply are also experimental and not yet broadly supported.
@mixin --badge(--tone: teal) {
@private {
--edge: color-mix(in srgb, var(--tone), black 20%);
}
color: var(--tone);
border: 2px solid var(--edge);
}
.badge {
@apply --badge(royalblue);
}
Limitations and Browser Support
This example demonstrates proposed syntax, not a dependable cross-browser production technique. Current browser implementations do not provide interoperable support for the full @private behavior. Use ordinary custom properties with carefully chosen names for production code.
.example {
@private {
--local: 16px;
}
padding: var(--local);
}
@private Example
This proposed example uses local spacing and color values in a notice and its nested strong element. Browsers without @private support will ignore the at-rule and may not resolve those variables. Do not rely on the example for a production layout.
.notice {
@private {
--space: 12px;
--tone: #175d91;
}
padding: var(--space);
border-left: 4px solid var(--tone);
& > strong {
color: var(--tone);
}
}
Browser Support
Experimental - limited or no interoperable browser support. The draft can change. Can I Use?
The draft syntax and interactions with proposed mixins may change. A browser that does not recognize this at-rule will ignore its contents; use normal custom properties for production styles.
Specifications
@private At-Rule is described in CSS Custom Functions and Mixins Module Level 1. This feature is experimental and subject to changes.
