Los uw specificiteitshoofdpijn op met CSS-modules

"CSS-modules" heeft niets te maken met het W3C, maar maakt deel uit van een voorgesteld bouwproces. Het compileert uw project en geeft de selectors en klassen een nieuwe naam zodat ze uniek worden, toegespitst op individuele componenten. Stijlen zitten vast in die componenten en kunnen nergens anders worden gebruikt, tenzij je dat specifiek zegt!

Preambule

Tegenwoordig zijn we redelijk gewend aan het idee dat webtechnologieën de drijvende kracht achter apps zijn; web apps, mobiele en desktop apps. Maar in tegenstelling tot eenvoudige statische websites, zijn apps doorgaans dynamischer, complexer en bestaan ​​vaak uit componenten die zelfs verder gaan dan wat Bootstrap of ZURB Foundation biedt. Naarmate een app groeit in complexiteit, kan het beheren van zijn CSS een helse taak zijn. 

In de loop van de tijd zijn talloze strategieën ontwikkeld, zoals OOCSS, ITCSS, BEM, Atomic CSS, enz. Om CSS georganiseerd, herbruikbaar en (cruciaal) te houden schaalbaar. Deze strategieën vereisen dat u en iedereen in uw team de conventies aandachtig volgt.

Echter, vroeg of laat zal de complexiteit weer binnensluipen en kom je stijlregels tegen zoals de volgende:

html.progressive-image.js [data-progressive-image], html.progressive-image.js [data-progressive-image] * background-image: none! important; masker-afbeelding: geen! belangrijk; opacity: 0 .main # section-enhanced-gallery-heroes.homepage-section.enhanced-gallery .with-single-item transform: translate (0, 0)! important 

Het probleem met CSS op veel grootschalige websites en apps is dat het zo moeilijk is om de specificiteit laag te houden die op een gegeven moment !belangrijk kan niet worden vermeden. En het herschrijven van CSS op een grote codebasis is lastig, omdat het verwijderen van stijlen andere componenten kan breken.

In deze tutorial gaan we in op 'CSS-modules' en hoe dit ons kan helpen deze beruchte CSS-problemen te minimaliseren.

Notitie: bekijk de repo op Github voor ondersteunende codevoorbeelden.

CSS-modules gebruiken

In een notendop is "CSS-modules" een hulpmiddel dat CSS-klassen en -ID's hernoemt in unieke selectors, waardoor het de stijlregels lokaal kan scheiden van de toegewezen elementen of componenten. Ervan uitgaande dat we een knop hebben, schrijven we meestal de stijlregels als volgt:

.knop background-color: # 9b4dca; border: 0.1rem solid # 9b4dca; grensradius: .4rem; kleur: #fff; cursor: pointer; weergave: inline-block;  .knop: focus, .knop: zweeft background-colour: # 606c76; randkleur: # 606c76; kleur: #fff; overzicht: 0; 

Met CSS Modules worden deze stijlregels hernoemd naar zoiets als:

._12We30_knop achtergrondkleur: # 9b4dca; border: 0.1rem solid # 9b4dca; grensradius: .4rem; kleur: #fff; cursor: pointer; weergave: inline-block;  ._12We30_button: focus, ._12We30_button: hover background-color: # 606c76; randkleur: # 606c76; kleur: #fff; overzicht: 0; 

Als je grote sites zoals Facebook, Instagram of Airbnb bekijkt via de DevTools van je browser, zul je zien dat de CSS-klassen en id's worden genoemd met alleen dit soort patronen. Hier is een voorbeeld van de Airbnb-startpagina:

Wie noemde de klas met schijnbaar willekeurige cijfers?

Meerdere componenten

Het gebruik van CSS-modules zal niet veel zin hebben als we slechts één component hebben, dus laten we ons voorbeeld uitbreiden naar drie componenten en zien hoe we ons project moeten configureren om CSS-modules te implementeren..

Een component maken

In dit tweede voorbeeld gaan we drie componenten bouwen; een knop met drie verschillende stijlen. We noemen ze de 'primaire knop', de 'overzichtsknop' (ook wel 'spookknop' genoemd) en de 'wisknop'. We zullen deze knoppen in een aparte map plaatsen. Elke map bevat index.css en index.js.

In de index.js, we maken het element en kennen de klassen als volgt toe aan het element:

// 1. Importeer de stijlen van het index.css-bestand. importeer stijlen van './index.css'; / ** * 2. Een knopelement maken en de klasse uit index.css toevoegen. * @type String * / const-knop = ''; // 3. Exporteer de knop die moet worden gebruikt in de andere bestanden. standaard knop exporteren;

Het nieuwe gebruiken importeren richtlijn in ES6, we importeren de stylesheet en lezen de klassen en de ID's als een JavaScript-object. Vervolgens maken we een element en voegen de genoemde klasse toe .knop met native JavaScript Templating, die ook werd geïntroduceerd in ES6. Ten slotte exporteren we ons element, zodat het element ook kan worden geïmporteerd en opnieuw kan worden gebruikt in de andere JavaScript-bestanden.

Ten tijde van dit schrijven heeft niet elke browser de nieuwste JavaScript-functies en syntaxis geïmplementeerd uit de ES6-specificatie. Daarom hebben we Babel nodig om die fragmenten om te zetten in JavaScript-syntaxis die compatibel is in de meeste browsers.

Ons stylesheet, index.css, is gewone CSS. Het bevat een aantal selectors om het knopelement te stijlen.

/ * 1. Primaire knop * / .knop achtergrondkleur: # 9b4dca; border: 0.1rem solid # 9b4dca; grensradius: .4rem; kleur: #fff; cursor: pointer; weergave: inline-block; font-size: 1.1rem; font-gewicht: 700; hoogte: 3.8rem; letter-spacing: .1rem; regelhoogte: 3.8rem; opvulling: 0 3.0rem; text-align: center; tekstdecoratie: geen; text-transform: hoofdletters; white-space: nowrap;  / * Meer stijlen van de primaire knop hier * / 

Een van de voordelen van het gebruik van CSS-modules is dat we ons geen zorgen hoeven te maken over het benoemen van conventies. U kunt nog steeds uw favoriete CSS-methodologieën zoals BEM of OOCSS gebruiken, maar niets wordt afgedwongen; je kunt de stijlregels op de meest praktische manier voor de component schrijven, omdat de klassenaam uiteindelijk zal zijn naamruimten.

In dit voorbeeld geven we alle klassen van onze knopcomponent een naam .knop in plaats van .button-primaire of .button-outline.

Werken met CSS in Shadow DOM Ik heb nog steeds de oude gewoonte om de BEM-notatie te gebruiken, ook al heb ik dit niet * nodig *. Stijl inkapseling FTW!

- Razvan Caliman (@razvancaliman) 31 juli 2017

Modules samenstellen met Webpack

Wanneer we de laden index.js op een HTML-pagina verschijnt er niets in de browser. In dit geval zullen we de code moeten compileren om deze functioneel te maken. We zullen Babel, Babel Preset voor ES2015 (ES6) en Webpack samen met de volgende zogenaamde "loaders" moeten installeren om Webpack in staat te stellen onze bronbestanden te verwerken.

  • babel-loader: laden .js bestanden en transformeren de broncode met de Babel kernmodule.
  • css-loader: laden .css bestanden.
  • style-loader: om interne stijlen te injecteren die uit de css-loader in onze HTML-pagina met behulp van de 

    In Vue voegen we de module toeschrijven aan de stijl element, zoals hierboven weergegeven, om de CSS-modules in te schakelen. Wanneer we deze code compileren, krijgen we vrijwel hetzelfde resultaat.

    Afsluiten

    Voor sommigen van jullie is dit iets compleet nieuws. Het is volkomen begrijpelijk als het concept van CSS Modules op het eerste gezicht een beetje een hoofd-scratcher is. Dus laten we kort samenvatten wat we hebben geleerd over CSS Modules in dit artikel.

    • Met "CSS-modules" kunnen we stijlregels inkapselen door de naam ervan of namespacing de klassenamen, waarbij het botsen op de selecteursspecificiteit wordt geminimaliseerd naarmate de codebase groter wordt.
    • Dit stelt ons ook in staat om de klassenamen comfortabeler te schrijven in plaats van vast te houden aan één bepaalde methodologie.
    • Ten slotte, omdat stijlregels aan elk onderdeel zijn gekoppeld, worden de stijlen ook verwijderd wanneer we het onderdeel niet langer gebruiken.

    In dit artikel hebben we nauwelijks het oppervlak van CSS-modules en andere moderne hulpmiddelen voor webontwikkeling zoals Babel, Webpack en Vue bekrast. Dus hier heb ik enkele verwijzingen samengesteld om verder te kijken naar die tools.

    Verdere referentie

    • Bekijk de demo op Github
    • Start het coderen van ES6 met Babel: Tuts + Course
    • Aan de slag met Vue: Tuts + Course
    • Instant Webpack 2: Tuts + Course
    • Strategieën voor het laag houden van de CSS-specificiteit
    • Daniel Eden: beweeg langzaam en verbeter dingen