Preserve authored CSS specificity (#4024)
* feat: preserve authored CSS specificity * chore: update tests to use :where() * test: fix HTML and CSS test * test: fix imported markdown CSS test Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
parent
7db1cc20e9
commit
1215e731b8
6 changed files with 24 additions and 15 deletions
9
.changeset/fuzzy-donuts-wonder.md
Normal file
9
.changeset/fuzzy-donuts-wonder.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
**BREAKING** Implement [RFC0012](https://github.com/withastro/rfcs/blob/main/proposals/0012-scoped-css-with-preserved-specificity.md) to preserve authored specificity for Astro scoped styles.
|
||||
|
||||
If you use a mix of global styles and Astro scoped styles, **please visually inspect your site** after upgrading to confirm that styles are working as expected.
|
||||
|
||||
If you previously relied on Astro's scoped styles to increase the specificity of your selectors, please update your selectors to use an additional class. For example, updating `div` to `div.my-class` will match the previous behavior.
|
|
@ -82,7 +82,7 @@
|
|||
"test:e2e:match": "playwright test -g"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/compiler": "^0.21.0",
|
||||
"@astrojs/compiler": "^0.22.0",
|
||||
"@astrojs/language-server": "^0.20.0",
|
||||
"@astrojs/markdown-remark": "^0.12.0",
|
||||
"@astrojs/prism": "0.6.1",
|
||||
|
|
|
@ -46,7 +46,7 @@ describe('CSS', function () {
|
|||
expect(el2.attr('class')).to.equal(`visible ${scopedClass}`);
|
||||
|
||||
// 2. check CSS
|
||||
const expected = `.blue.${scopedClass}{color:#b0e0e6}.color\\\\:blue.${scopedClass}{color:#b0e0e6}.visible.${scopedClass}{display:block}`;
|
||||
const expected = `.blue:where(.${scopedClass}){color:#b0e0e6}.color\\\\:blue:where(.${scopedClass}){color:#b0e0e6}.visible:where(.${scopedClass}){display:block}`;
|
||||
expect(bundledCSS).to.include(expected);
|
||||
});
|
||||
|
||||
|
@ -69,11 +69,11 @@ describe('CSS', function () {
|
|||
});
|
||||
|
||||
it('<style lang="sass">', async () => {
|
||||
expect(bundledCSS).to.match(new RegExp('h1.astro-[^{]*{color:#90ee90}'));
|
||||
expect(bundledCSS).to.match(new RegExp('h1\\:where\\(.astro-[^{]*{color:#90ee90}'));
|
||||
});
|
||||
|
||||
it('<style lang="scss">', async () => {
|
||||
expect(bundledCSS).to.match(new RegExp('h1.astro-[^{]*{color:#ff69b4}'));
|
||||
expect(bundledCSS).to.match(new RegExp('h1\\:where\\(.astro-[^{]*{color:#ff69b4}'));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -308,10 +308,10 @@ describe('CSS', function () {
|
|||
it('resolves Astro styles', async () => {
|
||||
const allInjectedStyles = $('style[data-astro-injected]').text();
|
||||
|
||||
expect(allInjectedStyles).to.contain('.linked-css.astro-');
|
||||
expect(allInjectedStyles).to.contain('.linked-sass.astro-');
|
||||
expect(allInjectedStyles).to.contain('.linked-scss.astro-');
|
||||
expect(allInjectedStyles).to.contain('.wrapper.astro-');
|
||||
expect(allInjectedStyles).to.contain('.linked-css:where(.astro-');
|
||||
expect(allInjectedStyles).to.contain('.linked-sass:where(.astro-');
|
||||
expect(allInjectedStyles).to.contain('.linked-scss:where(.astro-');
|
||||
expect(allInjectedStyles).to.contain('.wrapper:where(.astro-');
|
||||
});
|
||||
|
||||
it('resolves Styles from React', async () => {
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('Imported markdown CSS', function () {
|
|||
expect(importedAstroComponent?.name).to.equal('h2');
|
||||
const cssClass = $(importedAstroComponent).attr('class')?.split(/\s+/)?.[0];
|
||||
|
||||
expect(bundledCSS).to.match(new RegExp(`h2.${cssClass}{color:#00f}`));
|
||||
expect(bundledCSS).to.include(`h2:where(.${cssClass}){color:#00f}`);
|
||||
});
|
||||
});
|
||||
describe('dev', () => {
|
||||
|
@ -53,7 +53,7 @@ describe('Imported markdown CSS', function () {
|
|||
const cssClass = $(importedAstroComponent).attr('class')?.split(/\s+/)?.[0];
|
||||
|
||||
const allInjectedStyles = $('style[data-astro-injected]').text().replace(/\s*/g, '');
|
||||
expect(allInjectedStyles).to.match(new RegExp(`h2.${cssClass}{color:#00f}`));
|
||||
expect(allInjectedStyles).to.include(`h2:where(.${cssClass}){color:#00f}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Partial HTML', async () => {
|
|||
|
||||
// test 2: correct CSS present
|
||||
const allInjectedStyles = $('style[data-astro-injected]').text();
|
||||
expect(allInjectedStyles).to.match(/\.astro-[^{]+{color:red}/);
|
||||
expect(allInjectedStyles).to.match(/\:where\(\.astro-[^{]+{color:red}/);
|
||||
});
|
||||
|
||||
it('injects framework styles', async () => {
|
||||
|
|
|
@ -438,7 +438,7 @@ importers:
|
|||
|
||||
packages/astro:
|
||||
specifiers:
|
||||
'@astrojs/compiler': ^0.21.0
|
||||
'@astrojs/compiler': ^0.22.0
|
||||
'@astrojs/language-server': ^0.20.0
|
||||
'@astrojs/markdown-remark': ^0.12.0
|
||||
'@astrojs/prism': 0.6.1
|
||||
|
@ -526,7 +526,7 @@ importers:
|
|||
yargs-parser: ^21.0.1
|
||||
zod: ^3.17.3
|
||||
dependencies:
|
||||
'@astrojs/compiler': 0.21.0
|
||||
'@astrojs/compiler': 0.22.0
|
||||
'@astrojs/language-server': 0.20.1
|
||||
'@astrojs/markdown-remark': link:../markdown/remark
|
||||
'@astrojs/prism': link:../astro-prism
|
||||
|
@ -2960,8 +2960,8 @@ packages:
|
|||
leven: 3.1.0
|
||||
dev: true
|
||||
|
||||
/@astrojs/compiler/0.21.0:
|
||||
resolution: {integrity: sha512-g+zkKpTsR0UCDiOAhjv0wQW0cPYd+2Hb5/z+ovIEu7K/v8z2jiQZqvhPvIsjI5ni+5rMFgjjoZWhkMCq+e4bOg==}
|
||||
/@astrojs/compiler/0.22.0:
|
||||
resolution: {integrity: sha512-TF3zwbPIgr3UPPkVquKUzSGsIqGKh3Gi34Y29+HZvL+YmrkAk+GAuUkOo2EXDJ6aS2Oxq0k7KO/yQ2LjkWl83A==}
|
||||
dev: false
|
||||
|
||||
/@astrojs/language-server/0.20.1:
|
||||
|
|
Loading…
Reference in a new issue