CSS Evolution: Fra CSS, SASS, BEM, CSS moduler til stilede komponenter

Siden begyndelsen af ​​Internettet har vi altid haft behov for at style vores websteder, CSS har eksisteret for evigt og har udviklet sig i sit eget tempo gennem årene, denne artikel vil føre dig gennem det.

Til at begynde med er vi nødt til at være på den samme side af hvad CSS er, jeg tror, ​​vi alle kan være enige om, at css bruges til at beskrive præsentationen af ​​et dokument skrevet på et markup-sprog.

Det er ingen nyhed, at CSS har udviklet sig undervejs og er blevet mere magtfuld i dag, men det er bredt kendt, at yderligere værktøj skal bruges for at få css på en eller anden måde til at fungere for teams.

CSS i det vilde vest

I 90'erne brugte vi fokus på at skabe “fancy” -grænseflader, wow-faktoren var den vigtigste ting, inline-stilarter var det dengang, vi var bare ligeglade med, om ting så anderledes ud, til sidst websider var som søde legetøj vi kunne smide nogle GIF'er, markeringer og andre forfærdelige (på det tidspunkt imponerende) elementer over og forvente at fange dine besøgende opmærksomhed.

Derefter begyndte vi at oprette dynamiske websteder, men css forblev et konstant rod, hver udvikler havde sin måde at udføre css på. Nogle af os kæmpede med specificitet og forårsagede visuelle regressioner, når vi introducerede ny kode, og vi stolede på at bruge! Vigtigt at sætte vores stærke vilje i sten til at få et UI-element til at se på en bestemt måde. Men vi indså snart, at:

Al denne praksis blev mere tydelig og større problemer, så snart projekter voksede i størrelse, kompleksitet og teammedlemmer. Så at ikke have et konsistent mønster til at udføre styling blev en af ​​de største blokerere for erfarne og uerfarne udviklere, der kæmpede for at finde en rigtig måde at gøre ting i CSS. I sidste ende var der ingen rigtige eller forkerte ting at gøre, vi var lige interesserede i at få tingene til at se ok ud.

SASS til redning

SASS omdannede CSS til et anstændigt programmeringssprog i form af en forarbejdningsmotor, der implementerede redning, variabler, mixins, udvidelser og logik til stilark, så du bedre kunne organisere dine css-filer og i det mindste have nogle måder at dekonstruere dine css-bidder i mindre filer, hvilket var en god ting dengang.

Den tager i det væsentlige scss-kode, forarbejder den og udsender de kompilerede versioner af filen i et globalt css-bundt. Fantastisk ikke? men ikke så meget ville jeg sige, efter et stykke tid viste det sig, at medmindre der var strategier og bedste praksis på plads, skabte SASS kun flere problemer, end det lettede.

Pludselig blev vi uvidende om, hvad forarbejdningsvirksomheden lavede under hætten og stolede på dovende rede for at erobre specificitetskampen, men fik kompilerede stilark til at gå i nød i størrelser.

Indtil BEM kom med….

BEM og komponentbaseret tænkning

Da BEM fulgte med var det et frisk pust, der fik os til at tænke mere på genanvendelighed og komponenter. Grundlæggende bragte det semantitet til et nyt niveau, det lod os sikre, at className er unikt, hvilket reducerer risikoen for specificitetskonflikt ved hjælp af en simpel konvention om blokelementmodifikator. Se på følgende eksempel:

Hvis du analyserer markeringen lidt, kan du straks se Block Element Modifier-konventionen i spillet her.

Du kan se, at vi har to meget eksplicitte blokke i koden: .Scenery og .sky, hver af dem har deres egne blokke. Sky er den eneste, der har modifikatorer, da det kan være tåget, dagtimerne eller skumringen, det er forskellige karakteristika, der kan anvendes på det samme element.

Lad os se på ledsager-css med en pseudokode, der lader os analysere det bedre:

Hvis du vil have en indgående forståelse af, hvordan BEM fungerer, anbefaler jeg, at du kigger på denne artikel, skrevet af min kollega og ven Andrei Popa.

BEM er god i den forstand, at du sørget for, at komponenter var unikke #reusabilityFtw. Med denne form for tænkning blev nogle tilsyneladende mønstre mere tydelige, da vi begyndte at migrere vores gamle stilark til denne nye konvention.

Men et andet sæt problemer fulgte:

  • Valg af klassens navn blev en kedelig opgave
  • Markup blev oppustet med alle de lange klassebetegnelser
  • Du var nødt til eksplicit at udvide hver ui-komponent, når du ville genbruge
  • Markup blev unødvendigt semantisk

CSS-moduler og lokalt omfang

Nogle af de problemer, som hverken SASS eller BEM fik rettet på, var, at der i sproglogikken ikke er noget begreb om ægte indkapsling, hvilket således er afhængig af udvikleren til at vælge unikke klassenavne. En proces, der føltes, kunne løses ved hjælp af værktøjer snarere ved konventioner.

Og det er præcis, hvad CSS-moduler gjorde, det var afhængig af at oprette en dynamisk klassenavne for hver lokalt defineret stil, og sørg for, at ingen visuelle regressioner skyldes indsprøjtning af nye css-egenskaber, alle stilarter blev korrekt indkapslet.

CSS-moduler vandt hurtigt popularitet i React-økosystemet, og nu er det almindeligt at se mange reagerer projekter, der bruger det, det har det fordele og ulemper, men overalt viser det sig at være et godt paradigme at bruge.

Men ... CSS-moduler i sig selv løser ikke kerneproblemerne i CSS, det viser dig kun en måde at lokalisere stildefinitioner: en smart måde at automatisere BEM på, så du ikke behøver at tænke på at vælge et klassens navn igen (eller i det mindste tænke på det mindre).

Men det lindrer ikke behovet for en god og forudsigelig stilarkitektur, der er let at udvide genbrug og kontrol med mindst mulig indsats.

Sådan ser lokale css ud:

Du kan se, at det bare er css, den vigtigste forskel er, at alle klassenavne, der er udskrevet med: local, genererer et unikt klassens navn, der ligner sådan:

.app-komponenter-knap -__ root - 3vvFf {}

Du kan konfigurere den genererede identitet med forespørgselsparameteren localIdentName. Eksempel: css-loader? LocalIdentName = [sti] [navn] --- [lokal] --- [hash: base64: 5] for lettere debugging.

Det er det enkle princip bag lokale CSS-moduler. Hvis du kan se, blev lokale moduler en måde at automatisere BEM-notationen ved at generere et unikt klassenavn, som var sikker på, at det ikke ville kollidere med andres, selvom de brugte samme navn. Ganske praktisk.

Stylede komponenter til blanding af css i JS (fuldt ud)

Stylede komponenter er rene visuelle primitiver, der fungerer som en indpakningskomponent; de kan kortlægges til faktiske html-tags, og hvad de gør er at indpasse børnekomponenterne med den stylede komponent.

Denne følgende kode forklarer det bedre:

Hvis du ser, at den stylede komponent er meget enkel at forstå, bruger den skabelonens bogstavelige notation til at definere css-egenskaber, ser det ud til, at kernet stylede komponentteamet spikede det denne gang, da det blander ESC og CSS's fulde kraft.

Stylede komponenter giver et meget simpelt mønster til at genbruge og fuldstændigt adskille brugergrænsefladen fra funktionelle og tilstødende komponenter. Oprettelse af en api, der har adgang til native tags enten i browseren som HTML eller Natively ved hjælp af React Native.

Sådan overfører du brugerdefinerede rekvisitter (eller modifikatorer) til en stylet komponent:

Du kan se, at rekvisitterne pludselig bliver de modifikatorer, som hver af komponenterne modtager, og de kan behandles til output forskellige linjer med css, pænt ikke?

Dette giver os mulighed for at bevæge os hurtigere og bruge den fulde kraft af JS til at behandle vores stilarter, mens vi sørger for, at de forbliver konsistente og genanvendelige.

Kerne UI for alle at genbruge

Det viste sig hurtigt, at CSS-moduler eller stylede komponenter i sig selv ikke var den perfekte løsning, det havde brug for en slags mønster for at det kunne fungere og skalere. Mønsteret opstod ved at definere, hvad en komponent er og adskille det fuldstændigt fra logik, skabe kernekomponenter, der udelukkende er at style og intet mere.

Et eksempel på implementering af en sådan komponent ved hjælp af CSS-moduler:

Hvis du ser, er der intet smarte heri, bare en komponent, der modtager rekvisitter, og disse er kortlagt til børnekomponenten. Med andre ord: indpakningskomponenten overfører alle rekvisitterne til børnene.

Derefter kan din komponent forbruges på følgende måde

Lad mig vise dig et lignende eksempel på en fuld implementering af en knap ved hjælp af stylede komponenter:

Det, der er interessant ved dette mønster, er, at komponenten er stum og kun fungerer som en indpakning af css-definitioner, der er kortlagt til overordnede komponent. Der er en fordel ved at gøre dette:

Det giver os mulighed for at definere et basis-UI-api, som du kan bytte efter vilje og sikre dig, at alt UI forbliver konsistent i hele applikationen.

På denne måde kan vi fuldstændigt isolere designprocessen fra implementeringsprocessen, hvilket gør det muligt at udløse dem parallelt, hvis det ønskes; Du kan have 1 udvikler med fokus på implementeringen af ​​funktionen og en anden polering af brugergrænsefladen for at opnå fuld adskillelse af bekymringer.

Hidtil lyder det som en fantastisk løsning, internt havde vi diskussioner omkring det og syntes det var en god ide at følge dette mønster. Sammen med dette mønster begyndte vi også at identificere andre nyttige mønstre:

Prop modtagere

Disse gør funktionen af ​​at lytte til rekvisitter, der sendes til en hvilken som helst komponent, hvilket gør det let at bruge disse funktioner i enhver komponent, du ønsker, hvilket gør det til den hellige gral til genanvendelighed og udvide kapaciteterne til en given komponent, du kan tænke på det som en måde at arve modifikatorer, et eksempel på, hvad jeg mener med dette:

På denne måde er du sikker på, at du ikke behøver at hardkode alle grænser igen for hver bestemt komponent , hvilket sparer dig masser af tid.

Stedholder / Mixin-lignende funktionalitet

I stilkomponenter kan du bruge JS 'fulde kraft til at være i stand til at oprette funktioner, ikke bare som propmodtagere, men også som en måde at dele kode mellem forskellige komponenter, her er et eksempel:

Layoutkomponenter

Vi har opdaget, at en af ​​de første ting, vi skal gøre, når vi arbejder i en applikation, er at placere vores UI-elementer. Til dette formål har vi identificeret nogle komponenter, der hjælper os i processen.

Disse komponenter har vist sig at være meget nyttige, da nogle udviklere ofte (ikke kender nok med css-positioneringsteknikker) har svært ved at indstille strukturen, her er et eksempel på sådanne komponenter:

Hvis du kan se, har vi -komponenten, der tager en bredde og en højde som rekvisitter og også modtager den vandrette prop, så rullebjælken vises nedenfor.

Hjælpekomponenter

Hjælpekomponenter gør vores liv lettere og giver os mulighed for at genbruge kraftigt. Dette er stedet, hvor vi gemmer alle vores fælles mønstre.

Dette er nogle af de hjælpere, jeg hidtil har fundet ganske nyttig:

Tema

Når du har et tema, kan du have 1 kilde til sandhed af værdier, der kan genbruges i hele applikationen, det har vist sig nyttigt at gemme værdier, der ofte genbruges i applikationen, som farvepalet og generelt udseende og fornemmelse.

Fordele

  • JS 'fulde kraft på vores hænder, hvilket betyder fuld kommunikation med komponentens brugergrænseflade.
  • Eliminerer behovet for at kortlægge komponenter og stilarter ved hjælp af et className (dette gøres under hætten)
  • Fantastisk udviklingserfaring indtil videre, det reducerer mængden af ​​tid, der bruges til at tænke på klassens navne og kortlægge dem til komponenten.

Ulemper

  • Endnu at blive testet i naturen
  • Bygget til reaktion
  • Super ung
  • Testning skal udføres via aria-etiketter eller ved hjælp af classNames

Konklusion

Uanset hvilken teknologi du bruger, hvad enten det er SASS, BEM, CSS-moduler eller stylede komponenter er der ingen erstatning for en veldefineret stylingarkitektur, der gør det intuitivt for andre udviklere at bidrage til din kodebase uden at tænke for meget, bryde eller introducere nye bevægelige dele til systemet.

Denne tilgang er vigtig for at skalere korrekt og kan opnås, selv hvis der bruges almindelig CSS og BEM, den største forskel er mængden af ​​arbejde og LOC, der er nødvendigt for hver implementering, generelle stylede komponenter føles som en god dragt til stort set alle React-projekter, endnu til at teste det i naturen, men ganske lovende.

Hvis du har nogen feedback tanker, udtalelser, råd eller noget, bedes du kommentere nedenfor, eller du er velkommen til at nå mig via twitter @ perezpriego7