Att överbrygga Klyftan Mellan CSS och JavaScript: CSS-i-JS

0
5

I denna artikel kommer vi att gräva i begreppet CSS-i-JS. Om du redan är bekanta med det begreppet, kan du fortfarande njuta av en promenad genom den filosofi som metod, och du kan till och med vara mer intresserade i nästa artikel (kommer i morgon!).

Webbutveckling är mycket tvärvetenskapligt. Vi är vana att arbeta med flera språk. Och, som utvecklar webbapplikationer blir mer vanligt och nyanserad, ser vi ofta för kreativa sätt att överbrygga klyftorna mellan dessa språk för att göra våra utvecklingsmiljöer och arbetsflöden enklare och mer effektiv.

De vanligaste exemplen är normalt när du använder templating-språk. Till exempel, ett språk kan användas för att generera kod för en mer utförlig språk (ofta HTML). Detta är en av de viktigaste aspekterna av front end ramverk — vad gör att manipulera HTML-se ut? Den senaste twist på detta område var JSX, eftersom det är egentligen inte ett templating-språk, det är en syntax förlängning av JavaScript, och det gör att arbeta med HTML verkligen kortfattad.

Webbapplikationer gå igenom många statliga kombinationer och det är ofta svårt att hantera innehåll ensam. Det är därför CSS ibland faller i glömska trots att hantera styling genom olika stater och media frågor är lika viktiga och lika utmanande. I denna två-serie, jag skulle vilja placera CSS i rampljuset och utforska för att överbrygga klyftan mellan it och JavaScript. Hela denna serie, jag kommer att anta att du använder en modul bundler som webpack. Som sådan, kommer jag att använda Reagera i mina exempel, men samma eller liknande principer som gäller för andra JavaScript-ramverk, inklusive Vue.

CSS landskapet är under utveckling i många riktningar eftersom det finns en hel del utmaningar att lösa och det finns ingen “rätt” väg. Jag har spenderat stora ansträngningar för att experimentera med olika metoder, främst på personliga projekt, så avsikten med denna serie är bara för att informera, inte att förskriva.

Utmaningar CSS

Innan du dyker in i koden, det är värt att förklara de mest betydande utmaningar för styling webbapplikationer. De jag pratar om i denna serie är prövningens omfattning, villkor och dynamisk stilar, och återanvändbarhet.

Omfattning

Scope är en välkänd CSS utmaning, det är tanken på att skriva stilar som inte läcker utanför komponent, och därmed undvika oönskade biverkningar. Vi skulle vilja att uppnå det helst utan att kompromissa med författande erfarenhet.

Villkorade och dynamisk stilar

Samtidigt som staten i front-end-program som började bli mer och mer avancerade, CSS fortfarande statisk. Vi kunde bara gälla uppsättningar av stilar villkorligt — om en knapp var det primära, att vi förmodligen skulle gälla klassen “primära” och definiera dess stilar i en separat CSS-fil för att tillämpa hur det kommer att se ut på skärmen. Med ett par fördefinierade knappen variationer var hanterbar, men vad händer om vi vill ha en mängd olika knappar, som är specifika anpassade för , Pinterest och vem vet vad mer? Vad vi verkligen vill göra är helt enkelt att passera en färg och definiera stater med CSS som hover, fokus, funktionshindrade etc. Detta kallas för dynamisk styling på grund av att vi inte längre växla mellan fördefinierade stilar — vi vet inte vad som kommer härnäst. Inline styles kan komma att tänka för att lösa detta problem, men att de inte stöder pseudo-klasser, attribut-selektorer, media frågor, eller liknande.

Återanvändning

Att återanvända regeluppsättningar, media frågor etc. är ett ämne som jag ser sällan nämns nyligen eftersom det är lösts genom förbehandling som Sass och Mindre. Men jag skulle ändå vilja att återkomma i denna serie.

Jag kommer att lista några tekniker för att handskas med dessa utmaningar tillsammans med sina begränsningar i båda delarna av denna serie. Ingen teknik är överlägsen de andra, och de är inte ens ömsesidigt uteslutande, vilket innebär att du kan välja en eller kombinera dem, beroende på vad du väljer kommer att förbättra kvaliteten på ditt projekt.

Inställningar

Vi kommer att visa olika styling tekniker med hjälp av ett exempel komponent som kallas för Foto. Vi ska göra en lyhörd bild som kan ha rundade hörn medan visa alternativ text som en bildtext. Det kommer att användas så här:

<Foto publicId=”ballonger” alt=”Varm luft ballonger!” avrundade />

Innan man bygger den faktiska komponent, vi ska abstrakt bort srcSet attribut för att hålla exempel kod kort. Så, låt oss skapa en utils.js fil med två verktyg för att generera bilder av olika bredder med Cloudinary:

import { Cloudinary } från “cloudinary-core’

const cl = Cloudinary.nya({ cloud_name: ‘demo’, säker: true })

export const getSrc = ({ publicId, bredd }) =>
cl.url(publicId, { beskär: ‘skala’, bredd })

export const getSrcSet = ({ publicId, bredder }) => bredder
.karta(bredd => `${getSrc({ publicId, bredd })} ${bredd}w`)
.gå med i(‘, ‘)

Vi satte upp våra Cloudinary exempel att använda namnet på Cloudinary s demo moln, liksom dess url: en metod för att generera Url-adresser för bild publicId enligt angivet alternativ. Vi är bara intresserade av att ändra bredden i denna del.

Vi kommer att använda dessa verktyg för src-och srcset attribut, respektive:

getSrc({ publicId: ‘ballonger’, bredd: 200 })
// => ‘https://res.cloudinary.com/demo/image/upload/c_scale,w_200/ballonger’

getSrcSet({ publicId: ‘ballonger’, bredder: [200, 400] })
// => ‘https://res.cloudinary.com/demo/image/upload/c_scale,w_200/ballonger 200w,
https://res.cloudinary.com/demo/image/upload/c_scale,w_400/ballonger 400w’

Om du är obekant med srcset och storlekar attribut, jag föreslår att du läser lite om lyhörda bilder först. På det sättet kommer du ha en enklare tid att följa exemplen.

CSS-i-JS

CSS-i-JS är en styling-strategi som abstracts CSS-modell till komponentnivå, snarare än handlingen nivå. Denna idé är att CSS kan vara begränsad till en specifik komponent — och endast som komponent i en sådan omfattning att de specifika stilar inte delas med eller läckt ut till andra komponenter, och ytterligare, kallas bara när de behövs. CSS-i-JS-bibliotek för att skapa stilar vid körning genom att sätta <style> – taggar i <head>.

En av de första bibliotek för att sätta detta begrepp att använda är JSS. Här är exempel och anställa dess syntax:

importera Reagerar från ‘reagerar’
importera injectSheet från ‘reagerar-jss’
import { getSrc, getSrcSet }’. /utils”

const stilar = {
foto: {
bredd: 200,
‘@media (min-width: 30rem)’: {
bredd: 400,
},
borderRadius: rekvisita => (rekvisita.rundade ? ‘1rem’ : 0),
},
}

const Photo = ({ klasser, publicId alt }) => (
<bild>
<img
className={klasser.foto}
src={getSrc({ publicId, bredd: 200 })}
srcSet={getSrcSet({ publicId, bredder: [200, 400, 800] })}
storlekar=”(min-width: 30rem) 400px, 200px”
/>
<figcaption>{alt}</figcaption>
</bild>
)
Foto.defaultProps = {
rundad: false,
}

export standard injectSheet(stilar)(Foto)

Vid första anblicken, stilar objektet ser ut, CSS skrivs i object notation med ytterligare funktioner, som att passera en funktion för att ställa in värdet baserat på rekvisita. De genererade klasserna är unik, så du behöver aldrig oroa dig för dem kolliderar med andra stilar. Med andra ord, du får omfattning gratis! Detta är hur de flesta CSS-i-JS-bibliotek arbete — naturligtvis med vissa vändningar i funktioner och syntax som vi kommer att täcka så går vi.

Du kan se av de attribut som bredden av vår uppritade bilden börjar vid 200px, sedan när det virtuella bredd blir minst 30rem, bredden ökar till 400px brett. Vi genererade en extra 800 källa för att täcka ännu större skärm densitet:

  • 1x skärmar kommer att använda 200 och 400
  • 2x skärmar kommer att använda 400 och 800

stil-komponenter är en annan CSS-i-JS-bibliotek, men med en mycket mer bekant syntax som skickligt använder taggade mall strängar i stället för objekt att titta mer likt CSS:

importera Reagerar från ‘reagerar’
importera stil, { css } ‘stil-komponenter”
import { getSrc, getSrcSet }’. /utils”

const mediaQuery = ‘(min-width: 30rem)’

const roundedStyle = css”
border-radius: 1rem;
`

const Image = inredda.img -`
width: 200px;
@media ${mediaQuery} {
width: 400px;
}
${rekvisita = rekvisita.rundade && roundedStyle};

const Photo = ({ publicId, alt, rundade }) => (
<bild>
<Bild
src={getSrc({ publicId, bredd: 200 })}
srcSet={getSrcSet({ publicId, bredder: [200, 400, 800] })}
storlekar={`${mediaQuery} 400px, 200px`}
rundade={rundade}
/>
<figcaption>{alt}</figcaption>
</bild>
)
Foto.defaultProps = {
rundad: false,
}

export-standard Foto

Vi skapar ofta semantiskt-neutrala element som <div> och <span> enbart för styling ändamål. Detta bibliotek, och många andra, att tillåta oss att skapa och stil dem i en enda rörelse.

Min favorit nytta av denna syntax är att det är som vanlig CSS, minus interpoleringar. Detta innebär att vi kan migrera vår CSS-kod lättare och vi får använda våra befintliga muskel minne i stället för att bekanta oss med att skriva CSS i objektet syntax.

Observera att vi kan interpolera nästan allt i våra stilar. Detta exempel visar hur vi kan spara media sökning i variabel och återanvända den på flera ställen. Lyhörd bilder är ett utmärkt sätt använda fallet för detta eftersom de storlekar attribut innehåller i princip CSS, så vi kan använda JavaScript för att göra koden mer TORR.

Låt oss säga att vi bestämde att vi vill att visuellt dölja rubriken, men ändå göra den åtkomlig för en skärmläsare. Jag vet att ett bättre sätt att uppnå detta skulle vara att använda en alt-attributet i stället, men låt oss använda ett annat sätt för den skull av detta exempel. Vi kan använda ett bibliotek för stil mixins kallas polerad — det fungerar bra med CSS-i-JS-bibliotek som gör det bra för vårt exempel. Detta bibliotek har en mixin kallas hideVisually som gör precis vad vi vill och vi kan använda det genom att interpolera dess returvärde:

import { hideVisually } ‘blank’

const Caption = inredda.figcaption`
${hideVisually()};
`

<Caption{alt}</Caption>

Även om hideVisually utgångar ett objekt, stil-komponenter bibliotek som vet hur man interpolera det som stilar.

CSS-i-JS-bibliotek har många avancerade funktioner som teman, säljare prefix och även inlining kritiska CSS, vilket gör det lätt att sluta skriva CSS-filer helt. Vid denna punkt, du kan börja att se varför CSS-i-JS blir ett lockande koncept.

Nackdelar och begränsningar

Den uppenbara nackdelen att CSS-i-JS är att det införs en runtime: de stilar som måste läsas, tolkas och genomförs via JavaScript. Författarna av CSS-i-JS-bibliotek är att lägga till alla typer av smarta optimeringar, som Babel plugins, men några runtime kostnader kommer ändå att existera.

Det är också viktigt att notera att dessa bibliotek inte är som analyseras av PostCSS eftersom PostCSS var inte avsedd att kunna tas med i runtime. Många använder e i stället som ett resultat, eftersom det är mycket snabbare. Detta innebär att vi tyvärr inte kan använda PostCSS plugins.

Den sista nackdelen jag kommer att nämna är verktyg. CSS-i-JS utvecklas i en riktigt snabb takt och text editor förlängning, linters, kod-formatters etc. behovet av att spela catch-up med nya funktioner för att hålla i nivå. För att till exempel människor använder VS Kod förlängning stil-komponenter för liknande CSS-i-JS-bibliotek så som känslor, även om de inte alla har samma funktioner. Jag har även sett API val av föreslagna funktioner att påverkas av målet att behålla syntax-markering!

Framtiden

Det finns två nya CSS-i-JS-bibliotek, Linaria och konstgräs, som har lyckats noll runtime genom att extrahera CSS till filer. Deras Api: er som finns liknande stil-komponenter, men de varierar i funktioner och mål.

Målet för Linaria är att efterlikna API för CSS-i-JS-bibliotek som stil-komponenter genom att ha inbyggda funktioner som avgränsning, häckande och säljare prefix. Omvänt, astroturf är byggt på CSS-Moduler, har begränsad interpolation kapacitet, och uppmuntrar att använda en CSS-ekosystem i stället för att skjuta upp det till JavaScript.

Jag byggde Gatsby plugins för både bibliotek om du vill spela med dem:

  • gatsby-plugin-linaria
  • gatsby-plugin-konstgräs

Två saker att ha i åtanke när du använder dessa bibliotek:

  1. med faktiska CSS-filer innebär att vi kan behandla dem med välbekanta verktyg som PostCSS
  2. Linaria använder anpassade egenskaper (en.k.en. CSS-variabler) under huven, se till att ta sin webbläsare stöd hänsyn till innan du använder detta bibliotek

Slutsats

CSS-i-JS är allt-i-ett-styling lösningar för att överbrygga klyftan mellan CSS och JavaScript. De är lätta att använda och de innehåller användbara inbyggda optimeringar — men alla som kommer till en kostnad. Framför allt, genom att använda CSS-i-JS, vi är i huvudsak ut från CSS ekosystem och avvakta med att JavaScript för att lösa våra problem.

Noll-runtime-lösningar mildra några av de nackdelar genom att föra tillbaka den CSS-verktyg, som stiger CSS-i-JS diskussion till en mycket mer intressant nivå. Vad är den faktiska begränsningar av förbehandling verktyg jämfört med CSS-i-JS? Detta kommer att behandlas i nästa del av denna serie.

Artikel-Serien:

  1. CSS-i-JS (Detta inlägg)
  2. CSS-Moduler, PostCSS och Framtiden för CSS (Kommer i morgon!)