Põhjalik ülevaade CSS-i @apply reeglist. Uurige, mis see oli, miks see kasutuselt kõrvaldati, ja avastage kaasaegsed alternatiivid mixin'ide rakendamiseks ja stiilide komponeerimiseks.
CSS-i @apply reegel: natiivsete mixin'ide tõus ja langus ning kaasaegsed alternatiivid
Pidevalt arenevas veebiarenduse maailmas on püüdlus puhtama, paremini hooldatava ja korduvkasutatava koodi poole lakkamatu. Aastaid on arendajad toetunud CSS-i eelprotsessoritele nagu Sass ja Less, et tuua stiililehtedesse programmilist võimekust. Üks armastatumaid funktsioone nendest tööriistadest on mixin – viis defineerida korduvkasutatav CSS-deklaratsioonide plokk. See tekitas loomuliku küsimuse: kas me saaksime selle võimsa funktsiooni ka natiivselt CSS-i? Mõnda aega tundus vastus olevat jaatav ja selle nimeks oli @apply.
@apply reegel oli paljutõotav ettepanek, mille eesmärk oli tuua mixin'i-laadne funktsionaalsus otse brauserisse, kasutades CSS-i kohandatud omaduste (Custom Properties) võimsust. See lubas tulevikku, kus saaksime defineerida korduvkasutatavaid stiililõike puhtas CSS-is ja rakendada neid kõikjal, isegi neid dünaamiliselt JavaScriptiga uuendades. Kuid kui olete täna arendaja, ei leia te @apply reeglit ühestki stabiilsest brauserist. Ettepanek eemaldati lõpuks ametlikust CSS-i spetsifikatsioonist.
See artikkel on põhjalik ülevaade CSS-i @apply reeglist. Me rändame läbi selle, mis see oli, millist võimsat potentsiaali see stiilide komponeerimiseks pakkus, keerulistest põhjustest selle kasutuselt kõrvaldamiseks ja, mis kõige tähtsam, kaasaegsetest, tootmisvalmis alternatiividest, mis lahendavad samu probleeme tänapäeva arenduse ökosüsteemis.
Mis oli CSS-i @apply reegel?
Oma olemuselt oli @apply reegel loodud selleks, et võtta kohandatud omadusse salvestatud CSS-deklaratsioonide kogum ja "rakendada" seda CSS-reegli sees. See võimaldas arendajatel luua sisuliselt "omaduste kotte" või "reeglikomplekte", mida sai taaskasutada mitme selektori vahel, kehastades seeläbi "Ära korda ennast" (Don't Repeat Yourself - DRY) põhimõtet.
Kontseptsioon põhines CSS-i kohandatud omadustel (sageli nimetatud CSS-i muutujateks). Kui tavaliselt kasutame kohandatud omadusi üksikute väärtuste, nagu värvi (--brand-color: #3498db;) või suuruse (--font-size-md: 16px;) salvestamiseks, siis @apply ettepanek laiendas nende võimekust hoida terveid deklaratsioonide plokke.
Kavandatud süntaks
Süntaks oli otsekohene ja intuitiivne kõigile, kes on CSS-iga tuttavad. Esmalt defineeriksite kohandatud omaduse, mis sisaldab CSS-deklaratsioonide plokki, mis on ümbritsetud loogeliste sulgudega {}.
:root {
--primary-button-styles: {
background-color: #007bff;
color: #ffffff;
border: 1px solid transparent;
padding: 0.5rem 1rem;
font-size: 1rem;
border-radius: 0.25rem;
cursor: pointer;
transition: background-color 0.2s ease-in-out;
};
}
Seejärel saaksite mis tahes CSS-reegli sees kasutada @apply at-reeglit, et sisestada kogu see stiilide plokk:
.btn-primary {
@apply --primary-button-styles;
}
.form-submit-button {
@apply --primary-button-styles;
margin-top: 1rem; /* Saate siiski lisada ka teisi stiile */
}
Selles näites päriksid nii .btn-primary kui ka .form-submit-button kõik stiilid, mis on defineeritud --primary-button-styles-is. See oli oluline erinevus tavalisest var() funktsioonist, mis suudab asendada ainult ühe väärtuse ühes omaduses.
Peamised kavandatud eelised
- Koodi korduvkasutatavus: Kõige ilmsem eelis oli korduste vähendamine. Levinud mustreid, nagu nuppude stiilid, kaartide paigutused või teavituskastid, sai defineerida ühe korra ja rakendada kõikjal.
- Parem hooldatavus: Kõigi esmaste nuppude välimuse uuendamiseks oleks vaja muuta ainult
--primary-button-styleskohandatud omadust. Muudatus leviks seejärel igale elemendile, kus seda rakendati. - Dünaamiline teemade muutmine: Kuna see põhines kohandatud omadustel, sai neid mixin'e dünaamiliselt JavaScriptiga muuta, võimaldades võimsaid käitusajal teemade muutmise võimekusi, mida eelprotsessorid (mis töötavad kompileerimise ajal) pakkuda ei suuda.
- Lõhe ületamine: See lubas tuua eelprotsessorite maailmast armastatud funktsiooni natiivsesse CSS-i, vähendades sõltuvust ehitustööriistadest selle konkreetse funktsionaalsuse jaoks.
@apply lubadus: natiivsed mixin'id ja stiilide komponeerimine
@apply potentsiaal ulatus palju kaugemale lihtsast stiilide taaskasutamisest. See avas kaks võimsat kontseptsiooni CSS-i arhitektuuri jaoks: natiivsed mixin'id ja deklaratiivne stiilide komponeerimine.
Natiivne vastus eelprotsessorite mixin'idele
Aastaid on Sass olnud mixin'ide kuldstandard. Võrdleme, kuidas Sass seda saavutab ja kuidas @apply pidi töötama.
Tüüpiline Sassi mixin:
@mixin flexible-center {
display: flex;
justify-content: center;
align-items: center;
}
.hero-banner {
@include flexible-center;
height: 100vh;
}
.modal-content {
@include flexible-center;
flex-direction: column;
}
Vastav lahendus @apply'ga:
:root {
--flexible-center: {
display: flex;
justify-content: center;
align-items: center;
};
}
.hero-banner {
@apply --flexible-center;
height: 100vh;
}
.modal-content {
@apply --flexible-center;
flex-direction: column;
}
Süntaks ja arendajakogemus olid märkimisväärselt sarnased. Peamine erinevus seisnes aga täitmises. Sassi @mixin töödeldakse ehitamise etapis, väljastades staatilise CSS-i. @apply reeglit oleks brauser töödelnud käitusajal. See erisus oli nii selle suurim tugevus kui ka, nagu näeme, selle lõplik langus.
Deklaratiivne stiilide komponeerimine
@apply oleks võimaldanud arendajatel ehitada keerukaid komponente, komponeerides väiksemaid, üheotstarbelisi stiililõike. Kujutage ette kasutajaliidese komponenditeegi ehitamist, kus teil on alusplokid tüpograafia, paigutuse ja välimuse jaoks.
:root {
--typography-body: {
font-family: 'Inter', sans-serif;
font-size: 16px;
line-height: 1.5;
color: #333;
};
--card-layout: {
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
};
--theme-light: {
background-color: #ffffff;
border: 1px solid #ddd;
};
--theme-dark: {
background-color: #2c3e50;
border: 1px solid #444;
color: #ecf0f1;
};
}
.article-card {
@apply --typography-body;
@apply --card-layout;
@apply --theme-light;
}
.user-profile-card.dark-mode {
@apply --typography-body;
@apply --card-layout;
@apply --theme-dark;
}
See lähenemine on väga deklaratiivne. .article-card CSS deklareerib selgelt oma koostise: sellel on põhiteksti tüpograafia, kaardi paigutus ja hele teema. See muudab koodi lihtsamini loetavaks ja mõistetavaks.
Dünaamiline supervõime
Kõige köitvam omadus oli selle käitusaegne dünaamilisus. Kuna --card-theme võis olla tavaline kohandatud omadus, saaksite terveid reeglikogumeid JavaScriptiga välja vahetada.
/* CSS */
.user-profile-card {
@apply --typography-body;
@apply --card-layout;
@apply var(--card-theme, --theme-light); /* Rakenda teema, vaikimisi hele */
}
/* JavaScript */
const themeToggleButton = document.getElementById('theme-toggle');
themeToggleButton.addEventListener('click', () => {
const root = document.documentElement;
const isDarkMode = root.style.getPropertyValue('--card-theme') === '--theme-dark';
if (isDarkMode) {
root.style.setProperty('--card-theme', '--theme-light');
} else {
root.style.setProperty('--card-theme', '--theme-dark');
}
});
See hüpoteetiline näide näitab, kuidas saaksite komponenti heleda ja tumeda teema vahel vahetada, muutes ühte kohandatud omadust. Brauser peaks seejärel @apply reegli uuesti hindama ja suure hulga stiile lennult välja vahetama. See oli uskumatult võimas idee, kuid see vihjas ka tohutule keerukusele, mis pinna all podises.
Suur debatt: miks eemaldati @apply CSS-i spetsifikatsioonist?
Miks kadus @apply nii köitva visiooni juures? Otsust selle eemaldamiseks ei tehtud kergekäeliselt. See oli pikkade ja keeruliste arutelude tulemus CSS-i töörühmas (CSSWG) ja brauseritootjate seas. Põhjused taandusid olulistele probleemidele jõudluse, keerukuse ja CSS-i aluspõhimõtetega.
1. Vastuvõetamatud mõjud jõudlusele
See oli selle languse peamine põhjus. CSS on loodud olema uskumatult kiire ja tõhus. Brauseri renderdusmootor suudab stiililehti parsida, ehitada CSSOM-i (CSS Object Model) ja rakendada stiile DOM-ile väga optimeeritud järjestuses. @apply reegel ähvardas need optimeerimised purustada.
- Parsimine ja valideerimine: Kui brauser kohtab kohandatud omadust nagu
--main-color: blue;, ei pea ta väärtust `blue` valideerima enne, kui seda tegelikult kasutatakse omaduses nagu `color: var(--main-color);`. Kuid@applypuhul peaks brauser parsima ja valideerima terve ploki suvalisi CSS-deklaratsioone kohandatud omaduse sees. See on palju koormavam ülesanne. - Kaskaadi keerukus: Suurim väljakutse oli välja mõelda, kuidas
@applysuhtleks kaskaadiga. Kui te@apply'te stiilide ploki, siis kuhu need stiilid kaskaadis sobivad? Kas neil on sama spetsiifilisus kui reeglil, milles nad on? Mis juhtub, kui@apply'tud omadus hiljem teise stiiliga üle kirjutatakse? See tekitas "hilise murdumise" kaskaadiprobleemi, mis oli arvutuslikult kulukas ja raskesti üheselt defineeritav. - Lõputud tsüklid ja ringviited: See tekitas ringviidete võimaluse. Mis siis, kui
--mixin-arakendaks--mixin-b, mis omakorda rakendaks--mixin-a? Nende juhtumite tuvastamine ja käsitlemine käitusajal lisaks CSS-mootorile märkimisväärset lisakoormust.
Sisuliselt nõudis @apply brauserilt märkimisväärse hulga töö tegemist, mida tavaliselt teevad ehitustööriistad kompileerimise ajal. Selle töö tõhus teostamine käitusajal iga stiili ümberarvutamise jaoks tunnistati jõudluse seisukohast liiga kulukaks.
2. Kaskaadi garantiide rikkumine
CSS-i kaskaad on etteaimatav, kuigi mõnikord keeruline süsteem. Arendajad toetuvad selle spetsiifilisuse, pärilikkuse ja lähtekoodi järjekorra reeglitele, et oma stiilidest aru saada. @apply reegel lisas kaudsuse taseme, mis muutis selle arutluskäigu palju raskemaks.
Vaatleme seda stsenaariumi:
:root {
--my-mixin: {
color: blue;
};
}
div {
@apply --my-mixin; /* värv on sinine */
color: red; /* värv on nüüd punane */
}
See tundub piisavalt lihtne. Aga mis siis, kui järjekord oleks vastupidine?
div {
color: red;
@apply --my-mixin; /* Kas see kirjutab punase üle? */
}
CSSWG pidi otsustama: kas @apply käitub nagu lühendomadus, mis laieneb kohapeal, või käitub see nagu deklaratsioonide kogum, mis sisestatakse omaenda lähtekoodi järjekorraga? See mitmetähenduslikkus õõnestas CSS-i põhilist etteaimatavust. Seda kirjeldati sageli kui "maagiat" – terminit, mida arendajad kasutavad käitumise kohta, mida ei ole lihtne mõista ega siluda. Sellise maagia sissetoomine CSS-i tuuma oli oluline filosoofiline mure.
3. Süntaksi ja parsimise väljakutsed
Süntaks ise, kuigi pealtnäha lihtne, tekitas probleeme. Suvalise CSS-i lubamine kohandatud omaduse väärtuses tähendas, et CSS-i parser peaks olema palju keerulisem. See peaks hakkama saama pesastatud plokkide, kommentaaride ja võimalike vigadega omaduse definitsioonis endas, mis oli oluline kõrvalekalle sellest, kuidas kohandatud omadused olid loodud töötama (hoides sisuliselt stringi kuni asendamiseni).
Lõppkokkuvõttes oli konsensus, et jõudluse ja keerukuse kulud kaalusid arendaja mugavuse eelised kaugelt üle, eriti kuna teised lahendused olid juba olemas või silmapiiril.
@apply pärand: kaasaegsed alternatiivid ja parimad praktikad
Unistus korduvkasutatavatest stiililõikudest CSS-is pole kaugeltki surnud. Probleemid, mida @apply püüdis lahendada, on endiselt väga reaalsed ja arendajate kogukond on sellest ajast alates omaks võtnud mitu võimsat, tootmisvalmis alternatiivi. Siin on see, mida peaksite täna kasutama.
Alternatiiv 1: CSS-i kohandatud omaduste meisterlik kasutamine (ettenähtud viisil)
Kõige otsesem, natiivsem lahendus on kasutada CSS-i kohandatud omadusi nende algsel eesmärgil: üksikute, korduvkasutatavate väärtuste salvestamiseks. Selle asemel, et luua nupu jaoks mixin, loote kohandatud omaduste komplekti, mis määratlevad nupu teema. See lähenemine on võimas, jõudluselt hea ja täielikult toetatud kõigi kaasaegsete brauserite poolt.
Näide: komponendi ehitamine kohandatud omadustega
:root {
--btn-padding-y: 0.5rem;
--btn-padding-x: 1rem;
--btn-font-size: 1rem;
--btn-border-radius: 0.25rem;
--btn-transition: color .15s ease-in-out, background-color .15s ease-in-out;
}
.btn {
/* Strukturaalsed stiilid */
display: inline-block;
padding: var(--btn-padding-y) var(--btn-padding-x);
font-size: var(--btn-font-size);
border-radius: var(--btn-border-radius);
transition: var(--btn-transition);
cursor: pointer;
text-align: center;
border: 1px solid transparent;
}
.btn-primary {
/* Teemastamine kohandatud omaduste kaudu */
--btn-bg: #007bff;
--btn-color: #ffffff;
--btn-hover-bg: #0056b3;
background-color: var(--btn-bg);
color: var(--btn-color);
}
.btn-primary:hover {
background-color: var(--btn-hover-bg);
}
.btn-secondary {
--btn-bg: #6c757d;
--btn-color: #ffffff;
--btn-hover-bg: #5a6268;
background-color: var(--btn-bg);
color: var(--btn-color);
}
.btn-secondary:hover {
background-color: var(--btn-hover-bg);
}
See lähenemine annab teile teemastatavad, hooldatavad komponendid, kasutades natiivset CSS-i. Struktuur on defineeritud klassis .btn ja teemat (osa, mille oleksite võinud panna @apply reeglisse) juhitakse kohandatud omadustega, mis on seotud modifikaatoritega nagu .btn-primary.
Alternatiiv 2: Utility-First CSS (nt Tailwind CSS)
Utility-first raamistikud nagu Tailwind CSS on viinud stiilide komponeerimise kontseptsiooni selle loogilise lõpuni. Selle asemel, et luua CSS-is komponendiklasse, komponeerite stiile otse oma HTML-is, kasutades väikeseid, üheotstarbelisi abiklasse.
Huvitaval kombel on Tailwind CSS-il oma @apply direktiiv. On ülioluline mõista, et see EI OLE natiivne CSS-i @apply. Tailwindi @apply on ehitamisaegne funktsioon, mis töötab selle ökosüsteemis. See loeb teie abiklasse ja kompileerib need staatiliseks CSS-iks, vältides kõiki natiivse ettepaneku käitusaegseid jõudlusprobleeme.
Näide: Tailwindi @apply kasutamine
/* Teie CSS-failis, mida töötleb Tailwind */
.btn-primary {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700;
}
/* Teie HTML-is */
<button class="btn-primary">
Primary Button
</button>
Siin võtab Tailwindi @apply abiklasside loendi ja loob uue komponendiklassi, .btn-primary. See pakub sama arendajakogemust korduvkasutatavate stiilikogumite loomisel, kuid teeb seda turvaliselt kompileerimise ajal.
Alternatiiv 3: CSS-in-JS teegid
Arendajatele, kes töötavad JavaScripti raamistikes nagu React, Vue või Svelte, pakuvad CSS-in-JS teegid (nt Styled Components, Emotion) veel ühe võimsa viisi stiilide komponeerimiseks. Nad kasutavad stiilide ehitamiseks JavaScripti enda komponeerimismudelit.
Näide: Mixin'id Styled Components'is (React)
import styled, { css } from 'styled-components';
// Defineeri mixin, kasutades mall-literaali
const buttonBaseStyles = css`
background-color: #007bff;
color: #ffffff;
border: 1px solid transparent;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
cursor: pointer;
`;
// Loo komponent ja rakenda mixin
const PrimaryButton = styled.button`
${buttonBaseStyles}
&:hover {
background-color: #0056b3;
}
`;
// Teine komponent, mis taaskasutab samu baasstiile
const SubmitButton = styled.input.attrs({ type: 'submit' })`
${buttonBaseStyles}
margin-top: 1rem;
`;
See kasutab JavaScripti täit võimsust, et luua korduvkasutatavaid, dünaamilisi ja skoobitud stiile, lahendades DRY-probleemi komponendipõhises paradigmas.
Alternatiiv 4: CSS-i eelprotsessorid (Sass, Less)
Ärgem unustagem tööriistu, mis selle kõik algatasid. Sass ja Less on endiselt uskumatult võimsad ja laialdaselt kasutatavad. Nende mixin-funktsionaalsus on küps, funktsioonirikas (nad saavad vastu võtta argumente) ja täiesti usaldusväärne, sest sarnaselt Tailwindi @apply'le töötavad nad kompileerimise ajal.
Paljude projektide jaoks, eriti nende, mis ei ole ehitatud raskele JavaScripti raamistikule, on eelprotsessor endiselt kõige lihtsam ja tõhusam viis keerukate, korduvkasutatavate stiilide haldamiseks.
Kokkuvõte: @apply eksperimendist õpitud õppetunnid
CSS-i @apply reegli lugu on põnev juhtumiuuring veebistandardite arengus. See esindab julget katset tuua armastatud arendajafunktsioon natiivsele platvormile. Selle lõplik eemaldamine ei olnud idee ebaõnnestumine, vaid tunnistus CSS-i töörühma pühendumisest jõudlusele, etteaimatavusele ja keele pikaajalisele tervisele.
Peamised järeldused arendajatele tänapäeval on:
- Kasutage CSS-i kohandatud omadusi väärtuste, mitte reeglikogumite jaoks. Kasutage neid võimsate teemasüsteemide loomiseks ja disaini järjepidevuse säilitamiseks.
- Valige komponeerimiseks õige tööriist. Probleemi, mida
@applypüüdis lahendada – stiilide komponeerimine – lahendavad kõige paremini spetsiaalsed tööriistad, mis töötavad ehitamise ajal (nagu Tailwind CSS või Sass) või komponendi kontekstis (nagu CSS-in-JS). - Mõistke veebistandardite "miksi". Teadmine, miks funktsioon nagu
@applytagasi lükati, annab meile sügavama arusaama brauserite inseneritöö keerukusest ja CSS-i aluspõhimõtetest, nagu kaskaad.
Kuigi me ei pruugi kunagi näha natiivset @apply reeglit CSS-is, elab selle vaim edasi. Soov modulaarsema, komponendipõhisema ja DRY-lähenemise järele stiilimisel on kujundanud kaasaegseid tööriistu ja parimaid praktikaid, mida me iga päev kasutame. Veebiplatvorm areneb jätkuvalt, pakkudes uusi natiivseid viise organiseerituma ja hooldatavama CSS-i kirjutamiseks selliste funktsioonidega nagu CSS Nesting, @scope ja Cascade Layers. Teekond parema stiilimiskogemuse poole on pidev ja eksperimentidest nagu @apply õpitud õppetunnid on need, mis sillutavad teed edasi.