de Facundo Corradini

Dacă ai folosit vreodată Selectorii fraților CSS, știi că sunt doar două. + combinatorul de frați selectează primul meci care vine imediat după, și ~ combinatorul ulterior-frate se potrivește cu toate cele care vin după.
Dar nu există nicio modalitate de a selecta ceea ce a venit înainte. Fie selectorii părinților, fie selectorii anteriori ai fraților nu sunt pur și simplu un lucru.

Știu că o vrei, știi că o vreau, dar adevărul dur este că ele nu există (și probabil că nu vor exista niciodată). Există un milion de postări despre de ce. Există chiar și propuneri cu privire la modul de implementare a acestora. Dar suntem blocați în procesarea unidirecțională a regulilor CSS, cel mai probabil să ne protejăm de „lipsa noastră de expertiză”, blocându-ne în re-fluxuri și chiar în bucle infinite.

Din fericire, ca și în cazul majorității limitărilor CSS, o putem falsifica.

Primul lucru pe care trebuie să îl luăm în considerare este de ce vrem să începem frații anteriori.
Îmi vin în minte două cazuri:

  1. Trebuie să selectăm toți frații unui anumit element și ~ combinatorul de frați ulterior selectează doar cele care vin după.
  2. Trebuie să selectăm doar frații care au venit înainte

1. Selectarea tuturor fraților

Uneori trebuie să selectăm atât frații anteriori, cât și pe următorii. Pentru a face acest lucru, putem selecta de fapt părintele și putem folosi câteva trucuri în jurul acestuia.

De exemplu, pentru a selecta toate intervalele din următoarea structură atunci când trecem pe oricare dintre ele, am putea folosi doar selectorul de copii de pe planul de plecare al părintelui. Ne asigurăm că dezactivăm pointer-events de la părinte și resetați-l înapoi pe copii. Deci, orice acțiune pe care dorim să se întâmple se va declanșa numai atunci când intrăm în copil și nu în părinte.

Dacă trebuie să selectați toți frații cu exceptia cel care este planat, puteți combina tehnica anterioară cu :not selector pentru al exclude.

Un caz de utilizare tipic pentru aceasta este meniurile:

Codul de mai sus va refuza opacitatea tuturor <li> elements, dar cel care este planat.

În plus, puteți utiliza filtre precum selectoarele de tip și al n-lea pentru a fi mai precis cu privire la frații pe care doriți să îi afectați.

Cu unele stiluri, ar trebui să funcționeze astfel:

Vă rugăm să rețineți: Dacă vei rula pointer-events:none abordare, țineți cont de faptul că se poate deranja cu stivuirea (vă poate permite să selectați elemente care sunt „mai jos” în ordinea stivuirii). De asemenea, nu va funcționa în IE10 și mai jos, în afară de implicația că s-ar putea să aveți nevoie de evenimentele pointer pentru altceva. Deci, fiți foarte atenți atunci când îl utilizați.

2. Selectarea a ceea ce a venit înainte

Pentru acest caz de utilizare, putem inversa ordinea de pe HTML, apoi o sortăm din nou în CSS și putem utiliza ~ combinator ulterior de frate sau + selector de frate alăturat. În acest fel vom selecta următorii frați, dar se va părea că îi selectăm pe cei anteriori.

Există mai multe modalități de a face acest lucru. Cel mai simplu și probabil cel mai vechi este schimbarea direcției de scriere a containerului nostru:

Dacă elementele dvs. trebuie să afișeze textul real, îl puteți inversa oricând:

Dar asta poate scăpa de sub control în multe feluri. Din fericire, cutia de instrumente CSS modernă o face mult mai simplă și mai sigură. Putem folosi doar Flexbox pe container și inversăm comanda cu flex-direction:row-reverse:

Cel mai bun lucru despre abordarea Flexbox este că nu ne încurcăm cu direcția de scriere. Nu este nevoie să resetăm copiii și totul este mult mai previzibil.

Folosirea „fraților anteriori” pentru a crea un sistem de evaluare a stelelor numai CSS

Semantic, un sistem de evaluare poate fi considerat doar o simplă listă de butoane radio cu etichetele corespunzătoare. Acest lucru este util, deoarece ne va permite să folosim :checked pseudo-selector pentru a modifica frații.

Deci, să începem de acolo:

Așa cum am discutat anterior, elementele sunt în ordine inversă pentru a permite un selector „frate anterior”. Observați că folosim caracterul unicode „stea albă” (U + 2606) pentru a reprezenta stelele goale.

Să le afișăm unul lângă altul, în ordinea corectă (inversă):

Acum ascundeți singuri butoanele radio, nimeni nu vrea să vadă asta:

Și aplicați un anumit stil personajelor vedetă:

Singura linie cu adevărat importantă este position:relative. Ne va permite să poziționăm absolut un pseudoelement umplut (U + 2605) deasupra ei, care va fi ascuns inițial.

Când plutim deasupra unei stele, pseudo-elementul stelelor umplute ar trebui să devină vizibil pentru ea și pentru toate anterior fratii.

Același lucru pentru evaluarea selectată, prin potrivirea tuturor etichetelor care vin inainte de butonul radio bifat:

Tine minte că folosirea steagului! important este exact opusul a unei bune practici. O fac aici, deoarece nu există o altă modalitate de a realiza funcționalitatea adăugată discutată în secțiunea următoare fără ea.

Nu în ultimul rând, trebuie să „ne amintim” de evaluarea actuală, doar în cazul în care utilizatorul dorește să o schimbe. De exemplu, dacă ar fi selectat cinci stele și, din orice motiv, doresc să o schimbe în patru, ar trebui să afișăm stelele 1 până la 4 ca umplute și a cincea ca semitransparente când trecem peste a patra.

Acest lucru poate fi realizat prin schimbarea opacității anterior frați ai intrării verificate atunci când treceți peste container:

De aceea am avut nevoie de opacity:1 !important în declarația de planare inițială. Altfel, această ultimă regulă ar fi câștigat concursul de specificitate și ar fi aplicat o umplutură semitransparentă tuturor.

Și iată, îl avem, un sistem de evaluare a stelelor complet CSS, complet funcțional, care utilizează selectoare „frați anteriori”.

După cum puteți vedea, doar pentru că „este imposibil” nu înseamnă că nu ar trebui să încercați. Programarea înseamnă depășirea limitelor. Deci, ori de câte ori lovești peretele, doar împinge un pic mai tare. Sau cred că găsirea drumului în jurul acestuia ar putea fi o analogie mai bună? … oricum, știi la ce mă refer. Continuați să faceți hack!

O notă despre accesibilitate

Fragmentul anterior este o simplificare pentru a ușura înțelegerea. Este nu ceva ce aș recomanda să folosesc la producție din cauza multor limitări de accesibilitate.

Pentru a face fragmentul puțin mai accesibil, primul lucru ar fi să ascundeți butoanele radio cu aproape orice altă tehnică decât display:none pentru a le face concentrabile. Ar trebui, de asemenea, să adăugăm un inel de focalizare pe întregul fragment de stele atunci când orice element din interior este focalizat, prin pseudo-selector :focus-within.

Etichetele „☆” identice nu au sens pentru cititoarele de ecran, deci cea mai bună abordare va fi să aveți un <spun> în interiorul etichetei cu textul „n Stars”, care va fi ascuns utilizatorilor văzători.

De asemenea, sursa HTML inversă + display:row-reverse abordarea face ca evaluarea tastaturii să fie incomodă, deoarece nu se inversează. Accesibilitate Flexbox și tastatură este un subiect destul de dezordonat, dar cel mai apropiat lucru de o soluție este acela de a adăuga aria-flowtoetichetă fiecărui element, ceea ce rezolvă cel puțin problema pentru unele combinații de cititoare de ecran + browser.

Pentru un fragment mai accesibil (folosind o tehnică alternativă de modificare a următorilor frați pentru a arăta gol în loc să încerce să evalueze pe cele anterioare) verificați-l pe Patrick Cole, așa cum am discutat în răspunsurile de mai jos.