New Rule: `no-declarations-after-nested-rules`
- Dominant language
- JavaScript
- Stars
- 308
- Forks
- 44
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 18
Description
### Rule details
Disallow bare declarations placed after nested rules within the same block. Declarations should come before nested rules, or be wrapped in `& { }`.
### What type of rule is this?
Warns about a potential problem
### Example code
```css
.actions {
padding: 8px;
display: flex;
& > * + * {
margin-inline-start: 8px;
}
justify-content: flex-end; /* stranded after the nested rule */
}
.message {
@media (width >= 600px) {
padding: 16px;
}
padding: 8px; /* interop hazard: renders differently in older engines */
}
```
### Prior Art
- Sass made this pattern a breaking change in 1.77 and rejects it outright unless the declarations are wrapped in `& { }`: https://sass-lang.com/documentation/breaking-changes/mixed-decls/
- [stylelint-no-mixed-decls](https://github.com/apostrophecms/apostrophe/tree/main/packages/stylelint-no-mixed-decls) - a stylelint plugin enforcing the same constraint.
### Participation
- [x] I am willing to submit a pull request to implement this rule.
### AI acknowledgment
- [ ] I did not use AI to generate this issue report.
- [x] (If the above is not checked) I have reviewed the AI-generated content before submitting.
### Additional comments
- Before [CSSNestedDeclarations](https://web.dev/blog/css-nesting-cssnesteddeclarations) (Chrome 130, Firefox 132, Safari 18.2), engines hoisted trailing declarations above the nested rules, while engines implementing the current spec keep them in place - so in the `.message` example above, older engines render `padding: 16px` at `>= 600px` while spec-compliant ones always render `padding: 8px`. Same stylesheet, different rendering. The corrected behavior is Baseline newly available, so both behaviors coexist in still-supported browsers for a long while.
- Even on spec-compliant engines the pattern is a latent conflict: it is harmless until someone later adds an overlapping `@media`/state/child rule, at which point source order silently decides the winner.
- Declarations wrapped in `& { }` would not be reported - that is the spec-blessed way to place declarations after nested rules, and the fix Sass mandates.
- A suggestion (rather than an autofix) to wrap the declaration in `& { }` seems feasible. Moving the declaration up automatically would not be safe, since on spec-compliant engines that changes the cascade outcome.
Contributor guide
Assessment
This issue has not been assessed yet.