Villkorligt utforma utvalda element i en rutnätsbehållare PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Villkorligt utforma utvalda element i en rutnätsbehållare

Kalendrar, kundvagnar, gallerier, filutforskare och onlinebibliotek är några situationer där valbara objekt visas i rutnät (dvs. kvadratiska galler). Du vet, även de där säkerhetskontrollerna som ber dig att välja alla bilder med övergångsställen eller vad som helst.

Villkorligt utforma utvalda element i en rutnätsbehållare PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.
????

Jag hittade ett snyggt sätt att visa valbara alternativ i ett rutnät. Nej, inte återskapa den reCAPTCHA, utan helt enkelt kunna välja flera objekt. Och när två eller flera angränsande föremål väljs ut, kan vi använda smart :nth-of-type kombinatorer, pseudoelement och :checked pseudoklass för att styla dem på ett sätt där de ser grupperade ut.

CodePen Bädda in reserv

Hela idén med kombinatorer och pseudos för att få de rundade kryssrutorna kom från en tidigare artikel jag skrev. Det var en enkel design med en kolumn:

CodePen Bädda in reserv

Den här gången appliceras dock avrundningseffekten på element längs både vertikala och horisontella axlar på ett rutnät. Du behöver inte ha läst min senaste artikel om kryssrutestyling för detta eftersom jag kommer att täcka allt du behöver veta här. Men om du är intresserad av en slankare syn på vad vi gör i den här artikeln, så är den värd att kolla in.

Innan vi börjar...

Det kommer att vara användbart för dig att notera några saker. Till exempel använder jag statisk HTML och CSS i min demo för enkelhetens skull. Beroende på din applikation kan du behöva generera rutnätet och objekten i det dynamiskt. Jag utelämnar praktiska kontroller för tillgänglighet för att fokusera på effekten, men man skulle definitivt vilja överväga sånt i en produktionsmiljö.

Dessutom använder jag CSS Grid för layouten. Jag skulle rekommendera detsamma men, naturligtvis, det är bara en personlig preferens och din körsträcka kan variera. För mig, med hjälp av rutnät kan jag enkelt använda syskonväljare för att rikta in ett objekt ::before och ::after pseudos.

Därför, vilken layoutstandard du än vill använda i din applikation, se till att pseudos fortfarande kan riktas in i CSS och se till att layouten förblir i takt över olika webbläsare och skärmar.

Låt oss börja nu

Som du kanske har märkt i den tidigare demon, ändrar utformningen av rutorna om du markerar och avmarkerar ett kryssruteelement, beroende på valtillståndet för de andra kryssrutorna runt det. Detta är möjligt eftersom jag formaterade varje ruta med hjälp av pseudoelementen i dess intilliggande element istället för sitt eget element.

Följande bild visar hur ::before pseudo-element av lådor i varje kolumn (förutom den första kolumnen) överlappar rutorna till vänster om dem, och hur ::after pseudo-element av lådor i varje v (förutom den första raden) överlappar rutorna ovan.

Två rutnät med kryssrutor som visar placeringen av före och efter pseudos.
Villkorligt utforma utvalda element i en rutnätsbehållare

Här är baskoden

Markeringen är ganska enkel:

<main> <input type=checkbox> <input type=checkbox> <input type=checkbox> <!-- more boxes -->
</main>

Det händer lite mer i den inledande CSS. Men först, själva rutnätet:

/* The grid */
main { display: grid; grid: repeat(5, 60px) / repeat(4, 85px); align-items: center; justify-items: center; margin: 0;
}

Det är ett rutnät med fem rader och fyra kolumner som innehåller kryssrutor. Jag bestämde mig för att ta bort standardutseendet för kryssrutorna och sedan ge dem min egen ljusgrå bakgrund och superrundade kanter:

/* all checkboxes */
input { -webkit-appearance: none; appearance: none; background: #ddd; border-radius: 20px; cursor: pointer; display: grid; height: 40px; width: 60px; margin: 0;
}

Observera också att kryssrutorna i sig är rutnät. Det är nyckeln för att placera sina ::before och ::after pseudoelement. På tal om det, låt oss göra det nu:

/* pseudo-elements except for the first column and first row */
input:not(:nth-of-type(4n+1))::before,
input:nth-of-type(n+5)::after { content: ''; border-radius: 20px; grid-area: 1 / 1; pointer-events: none;
}

Vi markerar bara pseudoelementen i kryssrutor som inte finns i den första kolumnen eller den första raden i rutnätet. input:not(:nth-of-type(4n+1)) börjar vid den första kryssrutan och väljer sedan ::before av var fjärde föremål därifrån. Men märker vi säger :not(), så egentligen är det vi gör hoppa d ::before pseudo-element i var fjärde kryssruta, med början på den första. Sedan tillämpar vi stilar på ::after pseudo för varje kryssruta från den femte.

Nu kan vi styla båda ::before och ::after pseudos för varje kryssruta som inte finns i den första kolumnen eller raden i rutnätet, så att de flyttas åt vänster eller uppåt, och döljer dem som standard.

/* pseudo-elements other than the first column */
input:not(:nth-of-type(4n+1))::before { transform: translatex(-85px);
} /* pseudo-elements other than the first row */
input:nth-of-type(n+5)::after { transform: translatey(-60px); }

Styling av :checked tillstånd

Nu kommer styling av kryssrutorna när de är i en :checked stat. Låt oss först ge dem en färg, säg en limegreen bakgrund:

input:checked { background: limegreen; }

En kryssad ruta ska kunna ändra stilen på alla intilliggande kryssrutor. Med andra ord, om vi markerar den elfte kryssrutan i rutnätet, bör vi också kunna utforma rutorna som omger den överst, botten, vänster och höger.

Ett rutnät fyra gånger fem med rutor numrerade ett till 20. 11 väljs och 7, 10, 12 och 15 är markerade.
Villkorligt utforma utvalda element i en rutnätsbehållare

Detta görs genom att rikta in de korrekta pseudoelementen. Hur gör vi det? Tja, det beror på det faktiska antalet kolumner i rutnätet. Här är CSS om två intilliggande rutor är markerade i ett 5⨉4-rutnät:

/* a checked box's right borders (if the element to its right is checked) */
input:not(:nth-of-type(4n)):checked + input:checked::before { border-top-right-radius: 0; border-bottom-right-radius: 0; background: limegreen;
}
/* a checked box's bottom borders (if the element below is checked) */
input:nth-last-of-type(n+5):checked + * + * + * + input:checked::after { border-bottom-right-radius: 0; border-bottom-left-radius: 0; background: limegreen;
}
/* a checked box's adjacent (right side) checked box's left borders */
input:not(:nth-of-type(4n)):checked + input:checked + input::before { border-top-left-radius: 0; border-bottom-left-radius: 0; background: limegreen;
}
/* a checked box's adjacent (below) checked box's top borders */
input:not(:nth-of-type(4n)):checked + * + * + * + input:checked + input::before { border-top-left-radius: 0; border-top-right-radius: 0; background: limegreen;
}

Om du föredrar kan du generera ovanstående kod dynamiskt. Men ett typiskt rutnät, säg ett bildgalleri, kommer antalet kolumner att vara litet och troligen ett fast antal objekt, medan raderna kan fortsätta att öka. Speciellt om den är designad för mobilskärmar. Det är därför detta tillvägagångssätt fortfarande är en effektiv väg att gå. Om din applikation av någon anledning råkar ha begränsade rader och expanderande kolumner, överväg att rotera rutnätet i sidled eftersom, med en ström av objekt, arrangerar CSS Grid dem från vänster till höger och uppifrån och ner (dvs. rad för rad) .

Vi måste också lägga till stil för de sista kryssrutorna i rutnätet – de täcks inte alla av pseudoelement eftersom de är de sista objekten på varje axel.

/* a checked box's (in last column) left borders */
input:nth-of-type(4n-1):checked + input:checked { border-top-left-radius: 0; border-bottom-left-radius: 0;
}
/* a checked box's (in last column) adjacent (below) checked box's top borders */
input:nth-of-type(4n):checked + * + * + * + input:checked { border-top-left-radius: 0; border-top-right-radius: 0;
}

Det är några knepiga väljare! Den första…

input:nth-of-type(4n-1):checked + input:checked

...säger i princip detta:

A kontrollerad <input> element bredvid en markerad <input> i den näst sista kolumnen.

Och nth-of-type beräknas så här:

4(0) - 1 = no match
4(1) - 1 = 3rd item
4(2) - 1 = 7th item
4(3) - 1 = 11th item
etc.

Så vi börjar med den tredje kryssrutan och väljer var fjärde därifrån. Och om en kryssruta i den sekvensen är markerad, utformar vi även kryssrutorna bredvid, om de också är markerade.

Och denna rad:

input:nth-of-type(4n):checked + * + * + * + input:checked

Säger detta:

An <input> element, förutsatt att det är markerat, ligger i direkt anslutning till ett element, som ligger i direkt anslutning till ett annat element, som också ligger i direkt anslutning till ett annat element, som i sin tur ligger i direkt anslutning till en <input> element som är i ett kontrollerat tillstånd.

Vad det betyder är att vi markerar var fjärde kryssruta som är markerad. Och om en kryssruta i den sekvensen är markerad, utformar vi nästa fjärde kryssruta från den kryssrutan om den också är markerad.

CodePen Bädda in reserv

Att använda den

Det vi just tittade på är den allmänna principen och logiken bakom designen. Återigen, hur användbar det är i din applikation beror på rutnätsdesignen.

Jag använde rundade kanter, men du kan prova andra former eller till och med experimentera med bakgrundseffekter (Temani har dig täckt för idéer). Nu när du vet hur formeln fungerar är resten helt upp till din fantasi.

Här är ett exempel på hur det kan se ut i en enkel kalender:

CodePen Bädda in reserv

Återigen, detta är bara en grov prototyp som använder statisk uppmärkning. Och det skulle finnas massor av tillgänglighetsfrågor att ta hänsyn till i en kalenderfunktion.


Vi är klara! Ganska snyggt, eller hur? Jag menar, det finns inget exakt "nytt" om vad som händer. Men det är ett bra exempel på välja saker i CSS. Om vi ​​har koll på mer avancerade urvalstekniker som använder kombinatorer och pseudos, kan våra stylingkrafter nå långt bortom styling av ett föremål - som vi såg kan vi villkorligt styla föremål baserat på tillståndet hos ett annat element.


Villkorligt utforma utvalda element i en rutnätsbehållare ursprungligen publicerad på CSS-tricks. Du borde få nyhetsbrevet.

Tidsstämpel:

Mer från CSS-tricks