Zephyrnet-logo

CSS-raster en aangepaste vormen, deel 3

Datum:

Na Deel 1 en Deel 2, ben ik terug met een derde artikel om meer mooie vormen te ontdekken. Net als de vorige artikelen gaan we CSS Grid combineren met knippen en maskeren om fraaie lay-outs voor afbeeldingengalerijen te creëren.

CSS Grid en Custom Shapes-serie

Moet ik de vorige artikelen eerst lezen?

Het is niet verplicht, maar het wordt ten zeerste aanbevolen om zoveel mogelijk trucs uit te voeren. Je kunt ze ook in willekeurige volgorde lezen, maar chronologisch volgen is een goed idee om te zien hoe we hier terecht zijn gekomen.

Genoeg gepraat, laten we direct naar ons eerste voorbeeld gaan.

Laten we, voordat we in de CSS duiken, de opmaak controleren:

Niets dan een paar tags in een div-wrapper, toch? Vergeet niet dat de grootste uitdaging voor deze serie is om met zo min mogelijk HTML te werken. Alle voorbeelden die we in deze serie hebben gezien, gebruiken exact dezelfde HTML-opmaak. Geen extra divs, wrappers en dergelijke. Alles wat we nodig hebben zijn afbeeldingen in een wrapper-element.

Laten we nu de CSS controleren:

.gallery {
  --g: 6px; /* the gap */

  display: grid;
  width: 450px; /* the size */
  aspect-ratio: 1; /* equal height */
  grid: auto-flow 1fr / repeat(3, 1fr);
  gap: var(--g);
}
.gallery img:nth-child(2) {
  grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
  grid-area: 2 / 1 / span 2 / span 2;
}

In feite is dit een vierkant raster met drie gelijke kolommen. Vanaf daar is het enige dat gebeurt dat de tweede en derde afbeelding expliciet op het raster worden geplaatst, waardoor de eerste en laatste afbeelding er automatisch omheen kunnen worden geplaatst.

Dit automatische gedrag is een krachtig kenmerk van CSS Grid genaamd "auto-placement". Hetzelfde met het aantal rijen - geen van hen is expliciet gedefinieerd. De browser maakt ze "impliciet" op basis van de plaatsing van de items. ik heb een zeer gedetailleerd artikel die beide concepten verkent.

Je vraagt ​​je misschien af ​​wat daar aan de hand is grid en grid-area eigendomswaarden. Ze zien er vreemd uit en zijn moeilijk te groken! Dat komt omdat ik voor de CSS heb gekozen grid steno-eigenschap, wat superhandig is, maar een ongepast aantal waarden accepteert van de samenstellende eigenschappen. Je kunt ze allemaal zien in de Almanak.

Maar wat je echt moet weten is dit:

grid: auto-flow 1fr / repeat(3, 1fr);

…is gelijk aan dit:

grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;
DevTools-stijlregels voor de eigenschap grid.
U kunt ook uw favoriete DevTools gebruiken voor verder bewijs.

hetzelfde voor de grid-area eigendom. Als we DevTools openen en onze aangifte inspecteren: grid-area: 1/2/span 2/span 2; je krijgt het volgende:

grid-area: 1 / 2 / span 2 / span 2;

…dat is hetzelfde als dit allemaal uitschrijven:

grid-row-start: 1; /* 1st row */
grid-column-start: 2; /* 2nd column */
grid-row-end: span 2; /* take 2 rows */
grid-column-end: span 2; /* take 2 columns */

Zelfde deal voor de ander grid-area verklaring. Als we alles bij elkaar optellen, krijgen we het volgende:

Ja, de tweede en derde afbeelding overlappen elkaar in het midden. Dat is geen vergissing! Ik heb ze met opzet over elkaar gespannen zodat ik een clip-path om een ​​deel van elk te snijden en het uiteindelijke resultaat te krijgen:

Toont het effect met en zonder clip-path.

Hoe doen we dat? We kunnen de linkerbenedenhoek van de tweede afbeelding knippen (img:nth-child(2)) met de CSS clip-path eigendom:

clip-path: polygon(0 0, 100% 0, 100% 100%, calc(50% + var(--g) / 4) 100%, 0 calc(50% - var(--g) / 4))

En de rechterbovenhoek van de derde:

clip-path: polygon(0 0, calc(50% - var(--g) / 4) 0, 100% calc(50% + var(--g) / 4), 100% 100%, 0 100%);

Ik weet het. Dat zijn veel cijfers en zo. ik heb wel een artikel waarin de techniek wordt beschreven.

Dat is alles, we hebben ons eerste raster met afbeeldingen! Ik heb een grijstint toegevoegd filter op de selector om dat leuke zweefeffect te krijgen.

De gesplitste afbeelding onthullen

Laten we iets anders proberen. We kunnen wat we hebben geleerd over het afsnijden van de hoek van een afbeelding, combineren met een mooi effect om de volledige afbeelding bij zweven te onthullen.

De rasterconfiguratie voor deze is minder intens dan de vorige, omdat we alleen twee overlappende afbeeldingen nodig hebben:

.gallery {
  display: grid;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 350px; /* the size */
  aspect-ratio: 1; /* equal height */
}

Twee afbeeldingen van dezelfde grootte worden op elkaar gestapeld (dankzij grid-area: 1 / 1).

Het zweefeffect is afhankelijk van animatie clip-path. We zullen de code van de eerste afbeelding ontleden om te zien hoe deze werkt, en vervolgens hetzelfde in de tweede afbeelding stoppen met bijgewerkte waarden. Merk echter op dat we drie verschillende toestanden hebben:

  1. Als er geen afbeeldingen worden gezweefd, wordt de helft van elke afbeelding onthuld.
  2. Wanneer we de muisaanwijzer op de eerste afbeelding plaatsen, wordt deze vollediger onthuld, maar behoudt een kleine hoekclip.
  3. Als we met de muis over de tweede afbeelding gaan, is op de eerste alleen een kleine driehoek zichtbaar.
Toont de drie clipping-statussen van het zweefeffect.

In elk geval hebben we een driehoekige vorm. Dat betekent dat we een driepuntsveelhoek nodig hebben voor de clip-path waarde.

Wat? De tweede toestand is geen driehoek, maar meer een vierkant met een afgesneden hoek.

Je hebt gelijk, maar als we goed kijken zien we een “verborgen” driehoek. Laten we een toevoegen box-shadow naar de afbeeldingen.

Een ha! Is het je opgevallen?

De overgang tussen staten laten zien met de overloopvorm onthuld om uit te leggen hoe het werkt.

Wat is dit voor magie? Het is een weinig bekend feit dat clip-path accepteert waarden buiten de 0%-100% assortiment, waarmee we "overlopende" vormen kunnen creëren. (Ja, ik heb dit zojuist bedacht. Graag gedaan.) Op deze manier hoeven we alleen met drie punten te werken in plaats van de vijf die nodig zijn om dezelfde vorm te maken van de zichtbare delen. Geoptimaliseerde CSS voor de overwinning!

Dit is de code nadat we de polygoonwaarden in de clip-path eigendom:

.gallery > img:first-child {
  clip-path: polygon(0 0, calc(100% + var(--_p)) 0 , 0 calc(100% + var(--_p)))
}
.gallery > img:last-child {
  clip-path: polygon(100% 100%, 100% calc(0% - var(--_p)), calc(0% - var(--_p)) 100%)
}

Let op de --_p variabel. Ik gebruik dat om de code een beetje te optimaliseren terwijl we de zweefovergang toevoegen. In plaats van het geheel te updaten clip-path we werken deze variabele alleen bij om de beweging te krijgen. Hier is een video om te zien hoe de punten tussen elke toestand moeten bewegen:

We kunnen slap a nemen transition op de selector en werk vervolgens de --_p variabele op de toestanden om het uiteindelijke effect te krijgen:

.gallery {
  --g: 8px; /* the gap */
}
.gallery > img {
  /* etc. */
  --_p: calc(-1 * var(--g));
  transition: .4s .1s;
}
.gallery:hover > img:last-child,
.gallery:hover > img:first-child:hover{
  --_p: calc(50% - var(--g));
}
.gallery:hover > img:first-child,
.gallery:hover > img:first-child:hover + img {
  --_p: calc(-50% - var(--g));
}

Als we geen rekening houden met de kloof (gedefinieerd als --g in de code) tussen de afbeeldingen, dan de drie waarden van --_p zijn 0%, 50% en -50%. Elk definieert een van de toestanden die we eerder hebben uitgelegd.

Het taartbeeld wordt onthuld

Laten we de moeilijkheidsgraad van die laatste verhogen en proberen dezelfde truc uit te voeren, maar dan met vier afbeeldingen in plaats van twee.

Cool toch? Elke afbeelding is een kwart van een cirkel en bij zweven hebben we een animatie die een afbeelding transformeert in een volledige cirkel die de resterende afbeeldingen bedekt. Het effect lijkt misschien onmogelijk omdat er geen manier is om punten te roteren en ze te transformeren om de cirkel te vullen. In werkelijkheid draaien we echter helemaal geen punten. Het is een illusie!

Voor dit voorbeeld zal ik me alleen concentreren op de clip-path animatie omdat de configuratie van het raster hetzelfde is als in het vorige voorbeeld: vier afbeeldingen van gelijke grootte op elkaar gestapeld.

En een video die een saaie en lange uitleg waard is:

De clip-path wordt gevormd door zeven punten, waarvan er drie in een vaste positie staan ​​en de andere bewegen zoals getoond in de video. Het effect ziet er minder cool uit als het langzaam draait, maar we kunnen zien hoe de clip-path morphs tussen vormen.

Het effect is een beetje beter als we toevoegen border-radius en we maken het sneller:

En door het nog sneller te maken, zoals in het originele voorbeeld, krijgen we de perfecte illusie dat een kwart van een cirkel overgaat in een volledige cirkel. Dit is de polygoonwaarde voor our clip-path op de eerste afbeelding in de reeks:

.gallery > img:nth-child(1) {
  clip-path: polygon(50% 50%, calc(50% * var(--_i, 0)) calc(120% * var(--_i, 0)), 0 calc(100% * var(--_i, 0)),0 0, 100% 0, 100% calc(100% * var(--_i, 0)), calc(100% - 50% * var(--_i, 0)) calc(120% * var(--_i, 0)));
}
.gallery > img:hover {
 --_i: 1;
}

Zoals gewoonlijk gebruik ik een variabele om de code te optimaliseren. De variabele zal schakelen tussen 0 en 1 om de polygoon bij te werken.

Hetzelfde geldt voor de anderen afbeelding, maar met een andere clip-path configuratie. Ik weet dat de waarden misschien moeilijk te ontcijferen lijken, maar je kunt altijd online tools gebruiken zoals Clippy om de waarden te visualiseren.

Het mozaïek van afbeeldingen

Je kent mozaïeken, toch? Het is een kunststijl die decoratieve ontwerpen maakt van kleinere individuele stukken, zoals gekleurde stenen. Maar het kan ook een samengesteld beeld zijn dat bestaat uit andere kleinere beelden.

En je raadt het al: we kunnen dat soort dingen helemaal in CSS doen!

Laten we ons eerst eens voorstellen hoe het is als clip-path werden uit de mix gehaald en alles wat we hadden waren vijf overlappende afbeeldingen:

Ik speel een beetje vals in deze video omdat ik de code inspecteer om het gebied van elke afbeelding te identificeren, maar dit is wat je in je hoofd moet doen. Probeer voor elke afbeelding het ontbrekende deel te voltooien om de volledige rechthoek te zien en hiermee kunnen we de positie en grootte van elke afbeelding identificeren.

We moeten vinden hoeveel kolommen en rijen we nodig hebben voor het raster:

  1. We hebben twee grote afbeeldingen naast elkaar geplaatst die elk de helft van de rasterbreedte en de volledige rasterhoogte vullen. Dat betekent waarschijnlijk nodig hebben twee kolommen (één voor beide afbeeldingen) en een rij (voor de volledige hoogte van het rooster).
  2. We hebben de afbeelding in het midden die de twee andere afbeeldingen overlapt. Dat betekent dat we het echt nodig hebben vier kolommen in plaats van twee, hoewel we nog steeds alleen de nodig hebben een rij.
  3. De laatste twee afbeeldingen vullen elk de helft van het raster, net als de eerste twee afbeeldingen. Maar ze zijn slechts de helft van de hoogte van het raster. We kunnen de bestaande kolommen gebruiken die we al hebben, maar we zullen ze nodig hebben twee rijen in plaats van één om er rekening mee te houden dat deze afbeeldingen de helft van de rasterhoogte zijn.
Dat laat ons achter met een opgeruimd 4 × 2-raster.

Ik wil niet dat je denkt dat de manier waarop ik dit in stukken heb gesneden, het is Slechts manier om het te doen. Dit is slechts hoe ik het heb begrepen. Ik weet zeker dat er andere configuraties mogelijk zijn om dezelfde lay-out te krijgen!

Laten we die informatie nemen en ons raster definiëren en de afbeeldingen erop plaatsen:

.gallery {
  display: grid;
  grid: repeat(2, 1fr) / repeat(4, 1fr); 
  aspect-ratio: 2;
}
.gallery img:nth-child(1) {
  grid-area: 1 / 1 / span 2 / span 2;
}
.gallery img:nth-child(2) {
  grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
  grid-area: span 2 / span 2 / -1 / -1;
}
.gallery img:nth-child(4) {
  grid-area: 2 / 1 / span 1 / span 2;
}
.gallery img:nth-child(5) {
  grid-area: span 1 / span 2 / -1 / -1;
}

Ik denk dat je een idee krijgt van wat hier gebeurt nu we een paar voorbeelden hebben gezien die dezelfde aanpak gebruiken. We definiëren een raster en plaatsen er expliciet afbeeldingen op, met behulp van grid-area zodat de afbeeldingen elkaar overlappen.

Oké, maar de aspect-ratio is deze keer anders.

Het is! Als je teruggaat naar de redenering die we hebben gemaakt, hebben we de eerste twee afbeeldingen die vierkant naast elkaar staan ​​en dezelfde grootte hebben. Dit betekent dat de breedte van het raster gelijk moet zijn aan tweemaal de hoogte. Vandaar, aspect-ratio: 2.

Nu is het tijd voor de clip-path waarden. We hebben vier driehoeken en een ruit.

Toont de drie unieke vormen en de clip-path-waarden waardoor ze zijn gemaakt.
We laten alleen de drie unieke vormen zien die we maken in plaats van de vijf totale vormen.

Nogmaals, ik gebruik Clippy voor al deze wiskundige dingen. Maar eerlijk gezegd kan ik veel eenvoudige vormen met de hand schrijven, nadat ik er een aantal jaren nauw mee heb samengewerkt clip-path, en ik weet dat jij dat ook kunt met oefenen!

Het complexe mozaïek van afbeeldingen

Laten we de moeilijkheidsgraad verhogen en een ander mozaïek proberen, dit keer met minder symmetrie en complexere vormen.

Maak je geen zorgen, je zult zien dat het hetzelfde concept is als degene die we zojuist hebben gemaakt! Nogmaals, laten we ons voorstellen dat elke afbeelding een rechthoek is en vervolgens het raster gaan definiëren op basis van wat we zien.

We beginnen met twee afbeeldingen:

Het zijn beide vierkanten. De eerste afbeelding is gelijk aan de helft van de grootte van de tweede afbeelding. De eerste afbeelding neemt minder dan de helft van de rasterbreedte in beslag, terwijl de tweede afbeelding meer dan de helft in beslag neemt, wat ons een totaal geeft van twee kolommen met een andere maat (de eerste is gelijk aan de helft van de tweede). De eerste afbeelding is de helft van de hoogte, dus laten we er automatisch van uitgaan dat we die nodig hebben twee rijen .

Laten we nog een afbeelding aan de lay-out toevoegen

Deze maakt de zaken een beetje ingewikkelder! We moeten enkele lijnen trekken om te identificeren hoe de rasterconfiguratie moet worden bijgewerkt.

We gaan van een 2×2 raster naar vier kolommen en drie rijen. Vrij asymmetrisch, toch? Voordat we die volledige grootte proberen te achterhalen, laten we eens kijken of dezelfde lay-out standhoudt wanneer we de andere afbeeldingen toevoegen.

Het lijkt erop dat we nog steeds meer rijen en kolommen nodig hebben om alles op zijn plaats te laten vallen. Gebaseerd op de lijnen in die afbeelding, krijgen we een totaal van vijf kolommen en vier rijen.

De logica is eenvoudig, ook al is de lay-out complex, toch? We voegen de afbeeldingen één voor één toe om de juiste configuratie te vinden die overal bij past. Nu moeten we de grootte van elke kolom en rij bepalen.

Als we zeggen dat de kleinste rij/kolom gelijk is aan één fractie van het raster (1fr) we zullen krijgen:

grid-template-columns: 1fr 1fr 2fr 3fr 5fr;

…voor de kolommen, en:

grid-template-rows: 3fr 1fr 2fr 2fr;

…voor de rijen. We kunnen dit consolideren met behulp van de grid nogmaals afgekort eigendom:

grid: 3fr 1fr 2fr 2fr / 1fr 1fr 2fr 3fr 5fr;

Je weet hoe het gaat! Plaats de afbeeldingen op het raster en pas a clip-path op hen:

.gallery img:nth-child(1) {
  grid-area: 1 / 1 /span 2 / span 3;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.gallery img:nth-child(2) {
  grid-area: 1/2/span 3/span 3;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.gallery img:nth-child(3) {
  grid-area: 1 / span 2 / -1 / -1;
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.gallery img:nth-child(4) {
  grid-area: span 3 / 1 / -1 / span 3;
  clip-path: polygon(25% 0, 100% 60%, 50% 100%, 0 100%, 0 20%);
}
.gallery img:nth-child(5) {
  grid-area: span 3/span 3/-1/-1;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

We kunnen hier stoppen en onze code is prima, maar we zullen nog wat meer doen om de clip-path waarden. Omdat we geen openingen hebben tussen onze afbeeldingen, kunnen we het feit dat onze afbeeldingen elkaar overlappen gebruiken om dingen af ​​te slanken. Hier is een video om het idee te illustreren:

Zoals je kunt zien, heeft de afbeelding in het midden (die met de camera) geen a nodig clip-path. omdat de andere afbeeldingen het overlappen, waardoor we de vorm krijgen zonder extra werk! En merk op dat we dezelfde overlopende driepunts kunnen gebruiken clip-path concept dat we eerder op de afbeelding linksonder gebruikten om de code ook daar kleiner te houden.

Uiteindelijk hebben we een complex ogend raster van afbeeldingen met slechts vier clip-path declaraties — het zijn allemaal driepuntspolygonen!

Afsluiten

Wauw, toch? Ik weet niet hoe het met jou zit, maar het verveelt me ​​nooit om te zien wat CSS tegenwoordig kan doen. Het is nog niet zo lang geleden dat dit alles uitgebreide hacking en zeker wat JavaScript zou hebben gekost.

Gedurende deze serie hebben we heel veel verschillende soorten afbeeldingsrasters verkend, van de basisdingen tot de complexe mozaïeken die we vandaag hebben gemaakt. En we hebben veel praktische ervaring met CSS-clipping - iets dat u zeker voor andere projecten kunt gebruiken!

Maar voordat we dit beëindigen, heb ik wat huiswerk voor je...

Hier zijn twee mozaïeken die ik wil dat je maakt met behulp van wat we hier behandeld hebben. De ene is aan de "gemakkelijkere" kant en de andere is een beetje lastig. Het zou echt geweldig zijn om je werk in de reacties te zien, dus link ze! Ik ben benieuwd of jouw aanpak anders is dan hoe ik het zou aanpakken!

spot_img

Laatste intelligentie

spot_img