Zephyrnet-logo

Rasternamen gebruiken om uw lay-out te visualiseren (en ernaar te verwijzen)

Datum:

Wanneer we eenvoudige of complexe lay-outs bouwen met behulp van CSS Grid, plaatsen we items meestal met regelnummers. Rasterlay-outs bevatten rasterlijnen die automatisch worden geïndexeerd met positieve en negatieve regelnummers (tenzij we noem ze expliciet). Items met regelnummers positioneren is een prima manier om dingen op een rijtje te zetten, hoewel CSS Grid talloze manieren heeft om hetzelfde te bereiken met een ondermaatse cognitieve last. Een van die manieren is iets wat ik graag beschouw als de "ASCII"-methode.

De ASCII-methode in een notendop

De methode komt neer op het gebruik van grid-template-areas om rasteritems te positioneren met behulp van aangepaste benoemde gebieden op het niveau van de rastercontainer in plaats van regelnummers.

Wanneer we een element declareren als een rastercontainer met display: grid, genereert de rastercontainer standaard een spoor met één kolom en rijen die de rasteritems voldoende bevatten. De onderliggende elementen van de container die deelnemen aan de rasterlay-out worden geconverteerd naar rasteritems, ongeacht hun display eigendom.

Laten we bijvoorbeeld een raster maken door kolommen en rijen expliciet te definiëren met behulp van de grid-template-columns en grid-template-rows eigenschappen.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, 200px);
}

Dit kleine CSS-fragment maakt een raster van 3 × 2 waarin de rasteritems evenveel ruimte innemen in de kolommen, en waar het raster drie rijen bevat met een spoorgrootte van 200px.

We kunnen de volledige lay-out definiëren met benoemde rastergebieden met de grid-template-areas eigendom. Volgens de spec, de beginwaarde van grid-template-areas is none.

grid-template-areas = none | +

+ is een lijst van de groep strings tussen een aanhalingsteken. Elke tekenreeks wordt weergegeven als een cel en elke tekenreeks tussen aanhalingstekens wordt weergegeven als een rij. Soortgelijk:

grid-template-areas: "head head" "nav main" "foot foot";

De waarde van grid-template-areas beschrijft de lay-out als vier rastergebieden. Zij zijn,

  • head
  • nav
  • main
  • foot

head en foot overspannen twee kolomsporen en één rijspoor. De resterende nav en main elk omvat één kolomspoor en één rijspoor. De waarde van grid-template-areas lijkt veel op het rangschikken van ASCII-tekens, en als Chris stelde voor: een tijdje terug kunnen we een visualisatie van de algehele structuur van de lay-out krijgen van de CSS zelf, wat de meest probleemloze manier is om het te begrijpen.

(GIF op volledige grootte)

OK, dus we hebben onze lay-out gemaakt met vier benoemde rastergebieden: head, nav, main, foot.

Laten we nu beginnen met het plaatsen van de rasteritems tegen benoemde rastergebieden in plaats van regelnummers. Laten we in het bijzonder een header element in het benoemde rastergebied head en specificeer het benoemde rastergebied head in de header element met behulp van de grid-area eigendom.

Benoemde rastergebieden in een rasterlay-out heten identiteiten. Dus wat we net deden, was een aangepaste ident maken met de naam head die we kunnen gebruiken om items in bepaalde rastersporen te plaatsen.

header { grid-area: head; }

We kunnen andere HTML-elementen gebruiken met andere aangepaste idents:

nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: foot; }

Benoemde gebiedswaarden schrijven

Think CSS-rasterlay-outmodule niveau 1, moeten alle tekenreeksen worden gedefinieerd onder de volgende tokens:

  • Genoemd celtoken: Dit vertegenwoordigt het genoemde rastergebied in het raster. Bijvoorbeeld, head is een benoemde celtoken.
  • Null-cel-token: Dit vertegenwoordigt het naamloze rastergebied in de rastercontainer. Een lege cel in het raster is bijvoorbeeld een nulceltoken.
  • Prullenbak token: Dit is een syntaxisfout, zoals een ongeldige declaratie. Een ongelijksoortig aantal cellen en rijen vergeleken met het aantal rasteritems zou bijvoorbeeld een aangifte ongeldig maken.

In grid-template-area, moet elke string tussen aanhalingstekens (de rijen) hetzelfde aantal cellen hebben en het volledige raster definiëren zonder een cel te negeren.

We kunnen een cel negeren of laten staan ​​als een lege cel met behulp van de punt (.)

.grid { 
  display: grid;
  grid-template-areas:
    "head head"
    "nav main"
    "foot .";
}

Als u dat visueel onhandig of onevenwichtig vindt, kunnen we meerdere punttekens gebruiken zonder spaties die ze scheiden:

.grid {
  display: grid;
  grid-template-areas:
    "head head"
    "nav main"
    "foot ....";
}

Een benoemd celtoken kan meerdere rastercellen omvatten, maar die cellen moeten een rechthoekige lay-out vormen. Met andere woorden, we kunnen geen "L"- of "T"-vormige lay-outs maken, hoewel de specificatie dat wel doet hint naar ondersteuning voor niet-rechthoekige lay-outs met niet-verbonden regio's in de toekomst.

ASCII is beter dan lijngebaseerde plaatsing

Op lijn gebaseerde plaatsing is waar we de . gebruiken grid-column en grid-row eigenschappen om een ​​element op het raster te positioneren met behulp van rasterlijnnummers die automatisch worden geïndexeerd door een nummer:

.grid-item {
  grid-column: 1 / 3; /* start at grid column line 1 and span to line 3 */
}

Maar de regelnummers van rasteritems kunnen veranderen als onze lay-out op een breekpunt verandert. In die gevallen is het niet zo dat we kunnen vertrouwen op dezelfde regelnummers die we op een specifiek breekpunt hebben gebruikt. Dit is waar het extra cognitieve last vereist om de code te begrijpen.

Daarom denk ik dat een op ASCII gebaseerde aanpak het beste werkt. We kunnen de lay-out voor elk breekpunt opnieuw definiëren met behulp van grid-template-areas binnen de rastercontainer, die een handig beeld biedt van hoe de lay-out er direct in de CSS uit zal zien - het is als zelfgedocumenteerde code!

.grid {
  grid-template-areas:
    "head head"
    "nav main"
    "foot ...."; /* much easier way to see the grid! */
}

.grid-item {
  grid-area: foot; /* much easier to place the item! */
}

We kunnen de regelnummers en rastergebieden van een raster in DevTools zien. Ga in Firefox bijvoorbeeld naar het paneel Lay-out. Dan, onder de Raster tabblad, zoek de "Instellingen rasterweergave" en schakel de “Regelnummer weergeven” en “Weergave gebiedsnamen” opties.

Rasterinstellingen inschakelen.

Deze ASCII-aanpak met benoemde gebieden vereist veel minder inspanning om de plaatsing van elementen te visualiseren en gemakkelijk te vinden.

Line-based plaatsing versus ASCII Art plaatsing.

Laten we eens kijken naar de "universele" use case

Telkens wanneer ik een tutorial over benoemde rastergebieden zie, is het algemene voorbeeld over het algemeen een lay-outpatroon met: header, main, sidebar en footer gebieden. Ik beschouw dit graag als de "universele" use-case, omdat het zo'n breed net werpt.

De lay-out van de Heilige Graal in rechthoeken.

Het is een geweldig voorbeeld om te illustreren hoe grid-template-areas werkt, maar een real-life implementatie omvat meestal mediaquery's die zijn ingesteld om de lay-out bij bepaalde viewport-breedten te wijzigen. In plaats van opnieuw te moeten declareren grid-area op elk rasteritem bij elk breekpunt om alles opnieuw te positioneren, kunnen we gebruiken grid-template-areas om in plaats daarvan te "reageren" op het breekpunt - en een mooi beeld te krijgen van de lay-out op elk breekpunt in het proces!

Laten we, voordat we de lay-out definiëren, een ident toewijzen aan elk element met behulp van de grid-area eigenschap als basisstijl.

header {
  grid-area: head;
}

.left-side {
  grid-area: left;
}

main {
  grid-area: main;
}

.right-side {
  grid-area: right;
}

footer {
  grid-area: foot;
}

Laten we nu de lay-out opnieuw definiëren als een basisstijl. We gaan voor een mobile-first-aanpak, zodat dingen standaard worden gestapeld:

.grid-container {
  display: grid;
  grid-template-areas:
    "head"
    "left"
    "main"
    "right"
    "foot";
}

Elk rasteritem is automatisch formaat in deze configuratie — die een beetje raar lijkt — zodat we kunnen instellen min-height: 100vh op de rastercontainer om ons meer ruimte te geven om mee te werken:

.grid-container {
  display: grid;
  grid-template-areas:
    "head"
    "left"
    "main"
    "right"
    "foot";
  min-height: 100vh;
}

Laten we nu zeggen dat we de main element om rechts van de gestapelde te zitten left en right zijbalken als we bij een iets bredere viewport-breedte komen. We verklaren opnieuw: grid-template-areas met een bijgewerkte ASCII-lay-out om dat te krijgen:

@media (min-width: 800px) {
  .parent {
    grid-template-columns: 0.5fr 1fr;
    grid-template-rows: 100px 1fr 1fr 100px;
    grid-template-areas:
      "head head"
      "left main"
      "right main"
      "foot foot";
  }
}

Ik gooide er wat kolom- en rij-afmetingen in, puur voor esthetiek.

Naarmate de browser nog breder wordt, willen we misschien de lay-out opnieuw wijzigen, zodat main zit ingeklemd tussen de left en right zijbalken. Laten we de lay-out visueel schrijven!

.grid-container {
  grid-template-columns: 200px 1fr 200px; /* again, just for sizing */
  grid-template-areas:
    "head head head"
    "left main right"
    "left main right"
    "foot foot foot";
}

Gebruikmaken van impliciete regelnamen voor flexibiliteit

Volgens de specificaties, grid-template-areas genereert automatisch namen voor de rasterlijnen die zijn gemaakt door benoemde rastergebieden. We noemen deze impliciet genoemde rasterlijnen omdat ze gratis naar ons worden genoemd zonder extra werk.

Elk benoemd rastergebied krijgt vier impliciet benoemde rasterlijnen, twee in de kolomrichting en twee in de rijrichting, waarbij -start en -end worden toegevoegd aan de ident. Bijvoorbeeld een rastergebied met de naam head krijgt head-start en head-end lijnen in beide richtingen voor een totaal van vier impliciet genoemde rasterlijnen.

Impliciet toegewezen regelnamen.

We kunnen deze lijnen in ons voordeel gebruiken! Als we bijvoorbeeld willen dat een element de main, left en right gebieden van ons netwerk. Eerder hebben we het gehad over hoe lay-outs rechthoekig moeten zijn - geen "T" en "L" -vormige lay-outs toegestaan. Daarom kunnen we de visuele indelingsmethode ASCII niet gebruiken om de overlay te plaatsen. We kunnen echter onze impliciete regelnamen gebruiken met dezelfde grid-area eigenschap op de overlay die we gebruiken om de andere elementen te positioneren.

Wist je dat grid-area is een steno-eigenschap, ongeveer op dezelfde manier dat margin en padding zijn steno-eigenschappen? Het heeft meerdere waarden op dezelfde manier nodig, maar in plaats van een "met de klok mee" richting te volgen, zoals, margin - wat in volgorde van gaat margin-block-start, margin-inline-end, margin-block-end en margin-inline-start - grid-area gaat zoals dit:

grid-area: block-start / inline-start / block-end / inline-end;
De blok- en inline-stroomrichtingen weergeven in een schrijfmodus van links naar rechts.

Maar we hebben het over rijen en kolommen, niet over blok- en inline-richtingen, toch? Nou, ze komen overeen met elkaar. De rij-as komt overeen met de blokrichting en de kolomas komt overeen met de inline-richting:

grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;
Blok- en inline-as.

Terug naar het positioneren van dat overlay-element als een rasteritem in onze lay-out. De grid-area eigenschap zal handig zijn om het element te positioneren met behulp van onze impliciet genoemde rasterlijnen:

.overlay {
  grid-area: left-start / left-start / right-end / main-end;
}

Een minimaal rastersysteem creëren

Wanneer we ons concentreren op lay-outs zoals de "universele" use case die we zojuist hebben gezien, is het verleidelijk om rastergebieden te zien in termen van één gebied per element. Maar zo hoeft het niet te werken. We kunnen idents herhalen om er meer ruimte voor te reserveren in de layout. Dat zagen we toen we de head en foot idents in het laatste voorbeeld:

.grid-container {
  grid-template-areas:
    "head head head"
    "left main right"
    "left main right"
    "foot foot foot";
}

Let erop dat main, left en right worden ook herhaald, maar in de richting van het blok.

Laten we de lay-outs van volledige pagina's vergeten en benoemde rastergebieden op een component gebruiken. Raster is net zo goed voor componentlay-outs als volledige pagina's!

Hier is een vrij standaard heldencomponent met een rij afbeeldingen gevolgd door verschillende tekstblokken:

Een rij foto's van gewichtheffen boven een kop, flaptekst en dan een rij van drie links.

De HTML is vrij eenvoudig:

We zouden dit kunnen doen voor een echt snel gestapelde lay-out:

.hero {
  grid-template-areas:
    "image"
    "text";
}

Maar dan moeten we er wat uithalen padding, max-width of wat dan ook om het tekstgebied smaller te maken dan de rij afbeeldingen. Wat dacht je ervan om onze ASCII-lay-out uit te breiden tot een raster met vier kolommen in plaats daarvan door onze idents op beide rijen te herhalen:

.hero {
  display: grid;
  grid-template-columns: repeat(4, 1fr); /* maintain equal sizing */
  grid-template-areas:
    "image image image image"
    "text  text  text  text";
}

Oké, nu kunnen we onze rasteritems in die benoemde gebieden plaatsen:

.hero .image {
  grid-area: image;
}

.hero .text {
  grid-area: text;
}

Tot nu toe, zo goed - beide rijen nemen de volledige breedte in beslag. We kunnen dat gebruiken als onze basislay-out voor kleine schermen.

Rasterlijnen weergeven op de gestapelde mobiele versie van de pagina.

Maar misschien willen we de smallere tekst introduceren wanneer de viewport een grotere breedte bereikt. We kunnen wat we weten over het punt-teken gebruiken om kolommen over te slaan. Laten we de text ident slaat in dit geval de eerste en laatste kolom over.

@media (min-width: 800px) {
  main {
    grid-template-columns: repeat(6, 1fr); /* increase to six columns */
    grid-template-areas:
      "image image image image image image"
      "..... text  text  text  text  .....";
  }
}

Nu hebben we de gewenste afstand:

Rasterlijnen weergeven voor een lay-out van de pagina ter grootte van een tabel.

Als de lay-out extra moet worden aangepast op nog grotere breekpunten, kunnen we meer kolommen toevoegen en van daaruit verder gaan:

.hero {
  grid-template-columns: repeat(8, 1fr);
  grid-template-areas:
    "image image image image image image image image"
    "..... text  text  text  text  text  text  .....";
}

Visualisatie van dev-tool:

Rasterlijnen tonen voor een grote tabelformaat lay-out van de pagina.

Weet je nog dat lay-outs met 12 kolommen en 16 kolommen de grote dingen waren in CSS-frameworks? We kunnen daar snel naar opschalen en een mooie visuele ASCII-lay-out in de code behouden:

main {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "image image image image image image image image image image image image"
    "..... text  text  text  text  text  text  text  text  text  text  .....";
}

Laten we naar iets complexers kijken

We hebben gekeken naar een vrij algemeen voorbeeld en een relatief eenvoudig voorbeeld. We kunnen nog steeds mooie ASCII-lay-outvisualisaties krijgen met complexere lay-outs.

Laten we hier naartoe werken:

Drie afbeeldingen gepositioneerd rond een mooie kop.

Ik heb dit opgesplitst in twee elementen in de HTML, a header en main:

...

...

...
...

Ik denk dat flexbox meer geschikt is voor de header omdat we de onderliggende elementen op die manier gemakkelijk kunnen uit elkaar plaatsen. Dus nee grid er:

header {
  display: flex;
  justify-content: space-between;
  /* etc. */
}

Maar grid is zeer geschikt voor de main lay-out van het element. Laten we de lay-out definiëren en de idents toewijzen aan de corresponderende elementen die we nodig hebben om de . te positioneren .text en drie .image elementen. We beginnen met dit als onze basislijn voor kleine schermen:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-areas:
    "image1 image1 .....  image2"
    "texts  texts  texts  texts"
    ".....  image3 image3 .....";
}

Je kunt al zien waar we hiermee naartoe gaan, toch? De lay-out wordt voor ons gevisualiseerd en we kunnen de rasteritems op hun plaats laten vallen met de aangepaste idents:

.image:nth-child(1) {
  grid-area: image1;
}

.image:nth-last-child(2) {
  grid-area: image2;
}

.image:nth-last-child(1) {
  grid-area: image3;
}

h2 {
  grid-area: texts;
}
Rasterlijnen weergeven op een mobiele lay-out van de pagina.

Dat is onze basislay-out, dus laten we ons wagen aan een breder breekpunt:

@media (min-width: 800px) {
  .grid {
    grid-template-columns: repeat(8, 1fr);
    grid-template-areas:
      ". image1 image1 ...... ......  ...... image2 ."
      ". texts  texts  texts  texts   texts  image2 ."
      ". .....  image3 image3 image3  image3 ...... .";
  }
}

Ik wed dat je precies weet hoe dat eruit zal zien, want de lay-out staat precies in de code!

Rasterlijnen weergeven voor een lay-out van de pagina ter grootte van een tabel.

Dezelfde deal als we besluiten nog verder op te schalen:

.grid {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    ". image1 image1 .....  .....   .....  .....  .....  .....  .....  .....  ."
    ". texts  texts  texts  texts   texts  texts  texts  texts  texts  image2 ."
    ". .....  image3 image3 image3  image3 .....  .....  .....  .....  .....  .";
}
Rasterlijnen weergeven voor een lay-out van de pagina op desktopformaat.

Hier is de volledige demo:

Ik gebruik de "negatieve" margin hack" om ervoor te zorgen dat de eerste afbeelding de kop overlapt.

Afsluiten

Ik ben benieuwd of iemand anders het gebruikt grid-template-areas om benoemde gebieden te maken met het voordeel van een ASCII-visual van de rasterlay-out. Het hebben van dat als referentie in mijn CSS-code heeft geholpen bij het demystificeren van een aantal anders complexe ontwerpen die misschien nog complexer waren bij het omgaan met regelnummers.

Maar als er niets anders is, leert het definiëren van rasterlay-outs op deze manier ons een aantal interessante dingen over CSS Grid die we in dit bericht hebben gezien:

  • De grid-template-areas eigenschap stelt ons in staat om aangepaste idents - of "benoemde gebieden" - te maken en deze te gebruiken om rasteritems te positioneren met behulp van de grid-area eigendom.
  • Er zijn drie soorten "tokens" die: grid-template-areas accepteert als waarden, inclusief benoemde celtokens, null-celtokens en prullenbakceltokens.
  • Elke rij die is gedefinieerd in grid-template-areas hetzelfde aantal cellen nodig. Het negeren van een enkele cel creëert geen lay-out; het wordt beschouwd als een prullenbak.
  • We kunnen een visueel ASCII-achtig diagram van de rasterlay-out krijgen in de grid-template-areas eigenschapswaarde door de vereiste witruimten tussen benoemde celtokens te gebruiken bij het definiëren van de rasterlay-out.
  • Zorg ervoor dat er geen witruimte is in een null-celtoken (bijv .....). Anders creëert een enkele witruimte tussen null-celtokens onnodige lege cellen, wat resulteert in een ongeldige lay-out.
  • We kunnen de lay-out op verschillende breekpunten opnieuw definiëren door de rasteritems opnieuw te positioneren met grid-area, en vervolgens de lay-out opnieuw declareren met grid-template-areas op de rastercontainer om de tracklist indien nodig bij te werken. Het is niet nodig om de rasteritems aan te raken.
  • Aangepaste benoemde rastergebieden krijgen automatisch vier impliciet toegewezen lijnnamen — -start en -end in zowel de kolom- als de rijrichting.
spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?