Zapytania o elementy i sposób ich wykorzystania dzisiaj
Opublikowany: 2022-03-10Pomyśl przez chwilę o fizycznej strukturze. Jeśli budujesz duży gmach ze słabego materiału, potrzeba dużo zewnętrznego wsparcia, aby utrzymać go w całości, a rzeczy muszą być przebudowane, aby pozostały solidne. Kiedy budujesz stronę internetową z HTML, CSS i JavaScript, to zewnętrzne wsparcie może wyglądać jak frameworki, wtyczki, preprocesory, transpilatory, narzędzia do edycji, menedżery pakietów i procesy kompilacji.
Zamiast dodawać kolejną wtyczkę na szczyt stosu, zastanawiałem się, czy poprzez rozszerzenie jednego z podstawowych języków, CSS , moglibyśmy wzmocnić materiał, z którego zbudowane są strony internetowe, tworząc lepsze, silniejsze strony, które wymagają mniej wsparcia i narzędzi z zewnątrz budować.
Aktualny stan zapytań o elementy
Za pomocą takich narzędzi jak preprocesory CSS piszemy skrótowo CSS, który później zostanie rozszerzony do pełnej postaci (zanim zostanie wyświetlony w przeglądarce). Wtyczki mogą działać na stronie obok elementów, na które mają wpływ, ale aby zastosować style, albo zapisują style CSS bezpośrednio w HTML, albo przełączają nazwy klas, które stosują różne reguły CSS. W obu przypadkach musimy napisać lub wygenerować CSS, którego będziemy potrzebować, zanim strona faktycznie się załaduje.
Problem
Problem z tą metodą polega na tym, że nawet najlepsze wtyczki często wymagają dostosowania i konfiguracji w każdym używanym układzie. Ponadto, gdy JavaScript pisze dla Ciebie style, może być trudno utrzymać logikę opartą na wtyczkach i style CSS podczas refaktoryzacji lub ponownego użycia kodu.
Innym problemem związanym z preprocesorami jest to, że wszelkie błędy napisane skrótowo szybko rozrastają się do znacznie większego bałaganu, gdy CSS zostanie rozszerzony do pełnej postaci. Używając wtyczek dodajemy wiele potencjalnych punktów awarii. Być może używamy wielu wtyczek, aby wykonać kilka różnych rzeczy, które mogłyby być niepotrzebne, gdyby CSS był trochę potężniejszy. Stwarza to dodatkowe obciążenie dla programistów, które muszą utrzymywać, renderować przeglądarki, a użytkownicy pobierać.
Czy jest jakaś nadzieja na przyszłość tworzenia stron internetowych?
W 2013 roku Tyson Matanich napisał artykuł zatytułowany „Media Queries Are Not the Answer: Element Query Polyfill”, w którym przedstawił koncepcję zapytań elementowych szerokiemu gronu odbiorców. Rozpoczął dyskusję o tym, jak można zbudować wtyczki i wypełniacze, aby poruszać się po niedociągnięciach CSS.
Od tego czasu, gdy czekamy na rozwój funkcji CSS, wydano wiele wtyczek, które umożliwiają programistom używanie zapytań o elementy na kilka różnych sposobów.
Co to są zapytania o elementy?
Zapytania o elementy są podobne do zapytań o media, z tą różnicą, że ich reguły dotyczą właściwości rzeczywistych elementów, a nie widoku przeglądarki.
Jak powstał EQCSS
Pod koniec 2013 roku pracowałem nad frontendem aplikacji internetowej Ruby on Rails. Aplikacja musiała wyświetlać szczegółowe informacje użytkownikom, a jej celem było zbudowanie responsywnego interfejsu, który działałby równie dobrze na telefonach, tabletach i przeglądarkach stacjonarnych. Stwarzało to kilka wyzwań, z których jednym było to, że większość ważnych treści do wyświetlenia była najlepiej wyświetlana w tabelach — tak, rzeczywiste elementy table
(aby pokazać transakcje finansowe, rekordy sportowe itp.).

Stworzyłem responsywne style za pomocą zapytań o media, które poprawnie wyświetlały element table
dla przeglądarek o różnych rozmiarach. Ale gdy tylko jedna z tych responsywnych tabel została wyświetlona w szablonie zawierającym pasek boczny, nagle wszystkie moje responsywne punkty przerwania zamieniły się w reagujące punkty przerwania . Po prostu nie uwzględnili paska bocznego o szerokości 200 pikseli, powodując, że elementy nakładają się na siebie i wydają się zepsute.
Kolejna przeszkoda: nazwy użytkowników różniły się długością od 3 do 20 znaków i żałowałem, że nie mogę automatycznie dostosować rozmiaru czcionki każdej nazwy użytkownika na podstawie liczby zawartych w niej znaków . Musiałem umieścić każdą nazwę użytkownika na pasku bocznym i trudno było wybrać rozmiar czcionki wystarczająco mały, aby zmieścić 20-znakową nazwę użytkownika, ale wystarczająco duży, aby widz mógł zobaczyć 3-znakową nazwę użytkownika.
Aby obejść takie problemy, często kopiowałem całe zapytania o media, duplikując duże sekcje mojego kodu, po prostu dlatego, że potrzebowałem inteligentniejszego sposobu na zastosowanie responsywnych stylów w każdym układzie. Polegałem na JavaScript jako innym prowizorycznym rozwiązaniu, pisząc wiele niemal identycznych funkcji, które oglądałyby stronę i nakładały style w miejscach, do których CSS nie mógł dotrzeć. Po pewnym czasie dodatkowy ciężar całego tego zduplikowanego kodu zaczął obciążać bazę kodu i utrudniać wprowadzanie zmian.
Wiedziałem, że musi być lepsze rozwiązanie i po chwili zacząłem myśleć: nie potrzebuję zapytań o media — potrzebuję zapytań elementowych!
Badania i rozwój
Do 2014 roku zacząłem eksperymentować z różnymi sposobami informowania CSS o właściwościach elementów pojawiających się na stronie, aby móc stosować lepsze style. Miałem nadzieję, że odkryję podejście, które pozwoli mi pisać style łączące piękno CSS z potęgą JavaScript.
Niektóre porzucone podejścia, z których zrezygnowałem, obejmują dodawanie atrybutów do tagów HTML w celu dodania responsywnej obsługi i próby znalezienia sposobów osadzenia całych bloków kodu CSS w instrukcjach if
opartych na JavaScript, aby stworzyć coś w rodzaju potwora Frankensteina załatanego razem z JavaScript i CSS.
Ale zamiast ułatwiać sprawy, wszystkie moje nieudane podejścia miały jedną wspólną cechę: dodały więcej pracy! Wiedziałem, że właściwe rozwiązanie uprości i zmniejszy ilość pracy do wykonania, więc szukałem dalej. Dzięki tym eksperymentom uzyskałem wyrafinowany pomysł na typ składni, który byłby wymagany do prawidłowego działania zapytań o elementy.
Jak wspomniano, w przypadku strony internetowej zbudowanej z HTML, CSS i JavaScript, zewnętrzne wsparcie ma postać frameworków, wtyczek, preprocesorów, transpilerów, narzędzi do edycji, menedżerów pakietów i procesów budowania. Zamiast dodawać kolejną wtyczkę na szczyt stosu, zastanawiałem się, czy poprzez rozszerzenie jednego z podstawowych języków, CSS, moglibyśmy wzmocnić materiał, z którego zbudowane są strony internetowe, budując lepsze, silniejsze strony, które wymagają mniej wsparcia zewnętrznego i narzędzia do budowania.
Narodziny składni
Pod koniec 2014 roku, wyposażony w lepszą wizję potrzebnej składni, skontaktowałem się z Maxime Euziere, fenomenalnym golfistą kodu JavaScript i zapytałem o jego opinię na temat możliwości rozszerzenia CSS za pomocą JavaScript w przeglądarce w czasie wykonywania. Nie tylko poinformował mnie, że jest to możliwe, ale zaproponował, że pomoże mi to zrobić! Nazwaliśmy składnię EQCSS, skrót od „CSS zapytania o element”. Nazwa jest również ukłonem w stronę słowa „nadmiar”, ponieważ wszystko, co robi, przekracza możliwości CSS.
Potrzeba
Moim wymaganiem co do składni było to, aby była jak najbardziej zbliżona do CSS — tak blisko, że osoby zakreślające składnię zostałyby oszukane, myśląc, że to standardowy CSS. Zmapowałem więc składnię CSS dla zapytań o elementy, które miały sens — rodzaj składni, który ludzie są zaskoczeni, jeszcze nie istnieje.
Wiedziałem, że jeśli zamierzamy rozszerzyć obsługę CSS w przeglądarce za pomocą JavaScript, wtyczka musiałaby być tak lekka i prosta, jak to tylko możliwe, aby wykonać zadanie, co wykluczało użycie bibliotek takich jak jQuery do zbudowania wtyczki. Potrzebowałem czystej biblioteki JavaScript, która dodałaby funkcje, których chcę w przyszłości, do przeglądarek, które muszę obsługiwać dzisiaj.
W tej chwili dyskusja w społeczności CSS koncentruje się na niestandardowych regułach @
, a rozmowa o zapytaniach elementowych jest wciąż wstępna. Prawdopodobnie jeszcze wiele lat dzieli nas od oficjalnej specyfikacji CSS dla takich funkcji, a nawet po specyfikacji nadal będziemy musieli poczekać na wystarczającą obsługę przeglądarek, zanim będziemy mogli korzystać z tych funkcji w witrynach internetowych.
Czekanie na dodanie tych funkcji do CSS nie ma sensu, gdy potrzebujemy tej funkcji do tworzenia i naprawiania witryn internetowych.
Wynik
Efektem tych badań było stworzenie składni zawierającej nowy zestaw zaawansowanych warunków responsywnych, style o określonym zakresie i nowe selektory do elementów targetowania, a także czystą bibliotekę JavaScript o nazwie EQCSS.js. Dodatkowo, wsparcie dla Internet Explorera (IE) 8 zostało zapewnione w opcjonalnym zewnętrznym wypełnieniu. Zarówno wtyczka, jak i polyfill zostały wydane na licencji MIT i są bezpłatne dla każdego.
Przypadki użycia dla zapytań o elementy
Twórcy wtyczek
Tworząc komponenty i widżety interfejsu użytkownika, programiści często są ograniczani przez zapytania o media. Często musimy wybierać między budowaniem wielu różnych układów, które może skonfigurować osoba korzystająca z wtyczki, a uproszczeniem interfejsu do tego stopnia, że można zbudować rozwiązanie o jednym rozmiarze.
Ale projektując wtyczki i interfejsy z zapytaniami o elementy, możemy łatwo napisać responsywne style, które obejmują wszystkie przewidywane przez nas sytuacje, czyniąc je naprawdę kuloodpornymi, bez względu na to, jaką zawartość umieści użytkownik lub gdzie pojawi się wtyczka. Załóżmy, że możemy nadać styl widżetowi z układami o szerokości od 150 do 2000 pikseli. Wtedy, bez względu na to, gdzie ten widżet jest wyświetlany na stronie, zawsze będzie wyglądał świetnie.
Konstruktorzy szablonów
Kiedy tworzysz prototyp witryny, często reorganizujesz elementy projektu na stronie i myślisz o projekcie jak o zbiorze komponentów modułowych. Jeśli piszesz zapytania o media CSS, czasami może to oznaczać przedwczesną optymalizację . Projektując za pomocą zapytań elementowych, zachowujesz niezależne od układu warunków responsywnych, co zapewnia znacznie większą elastyczność w przenoszeniu elementów bez konieczności przerabiania stylów.
Rzeczy, które uważam za szczególnie przydatne do projektowania lub makiety za pomocą zapytań elementowych, obejmują:
- paski nawigacyjne,
- modalności,
- formularze rejestracji i logowania,
- stopki,
- wykresy cenowe,
- strony docelowe,
- stoły,
- pola z zakładkami,
- akordeony,
- widżety paska bocznego,
- odtwarzacze multimedialne,
- sekcje referencji.
Dowolny element projektu może być „ograniczony” i przeniesiony w dowolne miejsce — strona na stronę lub witryna do witryny.
Obsługa urządzeń
Jednym z problemów, z jakimi borykasz się podczas obsługi sieci na urządzeniach mobilnych, jest obfitość sprzętu. Rynek urządzeń jest bardziej rozdrobniony niż kiedykolwiek wcześniej, a nowe urządzenia pojawiają się każdego dnia. Nie możemy już utrzymywać listy obsługiwanych przeglądarek i urządzeń, dlatego ważne jest, aby wiedzieć, że projekt działa wszędzie, nawet na urządzeniach, które nie zostały jeszcze wydane.
Korzystając z zapytań elementowych, możesz lepiej projektować strony internetowe i wyeliminować niektóre z tych różnic między przeglądarkami.
Wiele artykułów napisanych niedawno o potrzebie zapytań o elementy szczegółowo ilustruje wiele przypadków użycia. Przejdźmy więc do tego, jak z nich korzystać!
Jak pisać zapytania dotyczące elementów
Rozpoczęcie pracy z EQCSS jest łatwe. Wszystko, czego potrzebujesz, aby zacząć używać składni EQCSS, to umieścić kod JavaScript w swoim kodzie HTML.
Pobieranie EQCSS.js
Jeśli chcesz sklonować projekt EQCSS z GitHub, możesz wpisać:
git clone https://github.com/eqcss/eqcss.git
Jeśli używasz npm, możesz dodać EQCSS do swojego projektu za pomocą następującego polecenia:
npm install eqcss
Dodawanie EQCSS.js do Twojego HTML
Po pobraniu EQCSS możesz dodać go do swojego kodu HTML za pomocą tagu script
:
<script src="EQCSS.js"></script>
Ten plik ( EQCSS.js
) obejmuje obsługę wszystkich obecnych przeglądarek, w tym IE 9 i nowszych. Do obsługi IE 8 musielibyśmy użyć wielu innych wypełniaczy. Należy pamiętać, że IE 8 nie obsługuje nawet zapytań o media CSS bez wypełniania, więc jest całkiem zdumiewające, że byliśmy w stanie uzyskać działające zapytania elementów. Aby włączyć obsługę IE 8 dla strony internetowej korzystającej z EQCSS, dodaj następujący link przed linkiem do głównej wtyczki:
<!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>
Bieganie EQCSS
Domyślnie wtyczka EQCSS oblicza wszystkie style, które znajdzie po załadowaniu strony, a także za każdym razem, gdy wykryje zmianę rozmiaru przeglądarki, podobnie jak w przypadku zapytań o media. Możesz również wywołać EQCSS.apply()
ręcznie za pomocą JavaScript, aby przeliczyć style w dowolnym momencie, co może być przydatne po zaktualizowaniu treści na stronie.
Pisanie zapytania elementu CSS
Wtyczka EQCSS.js może odczytywać style na kilka różnych sposobów. EQCSS można dołączyć do dowolnych znaczników style
na stronie HTML. Możesz także napisać EQCSS w zewnętrznym arkuszu stylów CSS.
Jeśli chcesz, aby kod oparty na EQCSS był oddzielony od CSS, możesz załadować składnię EQCSS za pomocą tagu script
z typem ustawionym na text/eqcss
. Możesz dodać style wbudowane w tagu takim jak ten lub połączyć z zewnętrznym arkuszem stylów .eqcss
za pomocą <script type=“text/eqcss” src=styles.eqcss></script>
, który załaduje plik o nazwie styles.eqcss
.
Anatomia zapytania o element
Zakres stylu
Składnia w EQCSS do pisania zapytań o elementy jest bardzo podobna do formatowania zapytań o media CSS, ale zamiast @media
zaczynamy zapytanie od @element
. Jedyną inną informacją, którą musimy podać, jest co najmniej jeden selektor, do którego te style powinny się odnosić. Oto jak utworzyć nowy zakres dla elementu o nazwie <div class=“widget”>
:
@element '.widget' { }
Elementem pomiędzy cudzysłowami (w tym przypadku .widget
) może być dowolny poprawny selektor CSS. Za pomocą tego zapytania utworzyliśmy nowy zakres na elemencie .widget
. Nie uwzględniliśmy jeszcze żadnych warunków responsywnych dla zakresu, więc wszelkie style w zapytaniu, takie jak to, będą miały zastosowanie do elementu objętego zakresem przez cały czas.
Bez możliwości określenia zakresu stylów na jeden lub więcej elementów (zamiast całej strony jednocześnie) nie bylibyśmy w stanie zastosować zapytań responsywnych tylko do tych elementów. Kiedy już stworzymy ten zakres na poziomie elementu, korzystanie z bardziej zaawansowanych funkcji składni EQCSS staje się łatwe — jak na przykład meta selektor $parent
— ponieważ JavaScript ma teraz punkt odniesienia, z którego można obliczać takie rzeczy, jak parentNode
w zakresie element. To jest ogromne!
To prawda, że CSS zawiera już selektor bezpośrednio potomny, z >
, który pozwala nam wybrać elementy, które są bezpośrednimi dziećmi określonego elementu. Ale CSS obecnie nie oferuje możliwości podróżowania w innym kierunku w górę drzewa genealogicznego, aby wybrać element, który zawiera inny element, który nazwalibyśmy elementem nadrzędnym. Specyfikacja „CSS Selectors Level 4” zawiera teraz selektor :has()
, który działa podobnie do selektora :has()
) w jQuery, ale obecnie obsługa przeglądarek jest zerowa. Ograniczony CSS umożliwia inny rodzaj selektora nadrzędnego.
Teraz, gdy otworzyliśmy zakres w kontekście elementu .widget
, możemy pisać style z jego perspektywy, aby kierować się na własny element nadrzędny:
@element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }
Innym przykładem specjalnych selektorów, których można użyć w dowolnym zapytaniu o element, są selektory $prev
i $next
, które reprezentują poprzedni i następny element równorzędny. Mimo że CSS może dotrzeć do następnego rodzeństwa naszego widżetu za pomocą selektora takiego jak .widget + *
, w CSS nie ma możliwości cofnięcia się i wybrania elementu, który znajduje się bezpośrednio przed innym elementem.
<section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>
Zapytania dotyczące elementów
Deweloperzy najczęściej używają zapytań o media CSS do projektowania responsywnego, stosując style oparte na wysokości lub szerokości widocznego obszaru przeglądarki. Składnia EQCSS obsługuje wiele nowych typów warunków responsywnych. Zamiast pracować z samą szerokością i wysokością przeglądarki, możesz pisać style, które mają zastosowanie do elementów na podstawie ich własnych właściwości, takich jak liczba elementów podrzędnych, które zawiera lub liczba znaków lub wierszy tekstu w danym momencie .
Dodanie tych warunków elastycznych do stylów z zakresem jest podobne do formatowania zapytań o media: dodajesz and (condition: value)
dla każdego warunku, który chcesz sprawdzić. W tym przykładzie sprawdzimy, czy jakiekolwiek elementy .widget
wyświetlają na stronie co najmniej 500 pikseli szerokości.
@element '.widget' and (min‐width: 500px) { /* CSS rules here */ }
Składnia zapytania o element wygląda następująco:
- zapytanie o element
@element selector_list [ condition_list ] { css_code }
- lista selektorów
" css selector [ "," css selector ]* "
- lista warunków
and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
- wartość
number [ css unit ]
- warunek zapytania
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
- jednostka CSS
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
Jako kolejny przykład, oto jak napisać zapytanie, które zmienia element body
na czerwony, gdy element .widget
osiąga szerokość 500 pikseli:
@element '.widget' and (min‐width: 500px) { body { background: red; } }
Zauważ, że element body
zmienia się, gdy .widget
osiągnie określoną szerokość, a nie sam element .widget
!
Warunki zapytania elementu
Poniżej znajduje się pełna lista responsywnych warunków obsługiwanych przez EQCSS.
Warunki oparte na szerokości
- demo
min-width
dla pikseli, demo dla procentów - demo
max-width
dla pikseli, demo dla procentów
Warunki oparte na wysokości
- Demo
min-height
dla pikseli, demo dla procentów - demo
max-height
dla pikseli, demo dla procentów
Warunki oparte na liczeniach
- demo
min-characters
dla elementów blokowych, demo dla danych wejściowych formularzy - demo
max-characters
dla elementów blokowych, demo dla danych wejściowych formularzy - prezentacja
min-lines
- demo
max-lines
- demo
min-children
-
max-children
demo
Warunki oparte na przewijaniu
-
min-scroll-y
demo -
max-scroll-y
demo - prezentacja
min-scroll-x
-
max-scroll-x
demo
Możesz połączyć dowolną liczbę tych warunków w swoich zapytaniach elementowych, aby uzyskać prawdziwie wielowymiarowe style responsywne. Daje to znacznie większą elastyczność i kontrolę nad sposobem renderowania elementów. Na przykład, aby zmniejszyć rozmiar czcionki nagłówka, który ma więcej niż 15 znaków, gdy do wyświetlenia jest mniej niż 600 pikseli, możesz połączyć warunki dla max‐characters: 15
i max‐width: 600px
:

h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }
Meta selektory
Jednym z problemów, które możesz napotkać po rozpoczęciu pisania stylów o zasięgu z warunkami responsywnymi, jest to, że gdy na stronie znajduje się wiele wystąpień tego samego selektora, użycie tego selektora w zapytaniu o element spowoduje zastosowanie stylów do wszystkich wystąpień tego selektora w strony, gdy którykolwiek z nich spełnia warunki. Biorąc nasze wcześniejsze przykłady .widget
, załóżmy, że mamy na stronie dwa widżety (może jeden na pasku bocznym, a drugi na pełnej szerokości) i napisaliśmy zapytanie o elementy w następujący sposób:
@element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }
Oznaczałoby to, że jeśli którykolwiek z elementów .widget
na stronie ma co najmniej 500 pikseli szerokości, styl zostanie zastosowany do obu elementów .widget
. W większości przypadków prawdopodobnie nie tak chcemy. Tutaj wkraczają selektory meta!
Dwie części, które składają się na nasze zapytanie o element, to selektor i warunek responsywny. Jeśli więc chcemy kierować reklamy tylko na te elementy na stronie, które odpowiadają jednocześnie selektorowi i warunkom responsywnym, możemy użyć meta selektora $this
. Możemy przepisać nasz ostatni przykład tak, aby styl dotyczył tylko elementów .widget
, które pasują do warunku min‐width: 500px
:
@element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }
Szereg nowych selektorów jest obsługiwanych przez składnię EQCSS, których nie ma w zwykłym CSS. Oto pełna lista:
-
$this
demo -
$parent
demo -
$root
demo -
$prev
prezentacja -
$next
prezentacja
Te selektory będą działać tylko w zapytaniu o element.
Otwarcie portalu między JavaScript a CSS
-
eval(')
demo
Ostatnią i ostatnią cechą EQCSS jest najdziksza ze wszystkich: eval(')
. Przez te drzwi kryje się cała moc JavaScript, dostępna z CSS. Chociaż JavaScript może stosować style do elementów, obecnie ma trudności z dotarciem do niektórych rzeczy, takich jak pseudoelementy :before
i :after
. Ale co by było, gdyby CSS mógł dotrzeć do JavaScriptu z innej strony? Zamiast ustawiać właściwości CSS przez JavaScript, co by było, gdyby CSS mógł być świadomy JavaScript?
Tutaj wkracza eval(')
. Możesz uzyskać dostęp i ocenić dowolny JavaScript, czy użyć wartości zmiennej JavaScript w swoim CSS, aby wykonać jednowierszowy JavaScript (jak eval('new Date().getFullYear()')
), aby ustalić wartości dotyczące przeglądarki i innych elementów, które JavaScript może mierzyć (takich jak eval('innerHeight')
) lub uruchomić funkcję JavaScript i użyć wartości, którą zwraca ona w stylach CSS. Oto przykład, który wyświetla 2016
w elemencie <footer>
:
@element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }
Używanie $it wewnątrz eval()
Podczas oceny JavaScript, eval(')
działa również z kontekstu elementu o aktywnym zasięgu, tego samego elementu, do którego mają zastosowanie style dla $this
. Możesz użyć $it
w JavaScript napisanym w eval(')
jako symbolu zastępczego dla elementu objętego zakresem, jeśli pomaga ci to ustrukturyzować kod, ale jeśli zostanie pominięty, będzie działał w ten sam sposób. Załóżmy na przykład, że mamy div
ze słowem „hello”. Poniższy kod wyświetli „hello hello”:
<div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>
W tym $it
odnosi się do div
, ponieważ jest to selektor aktualnie objęty zakresem. Możesz również pominąć $it
i napisać następujący kod, aby wyświetlić to samo:
@element 'div' { div:before { content: "eval('textContent') "; } }
eval(')
może być pomocny w sytuacjach, gdy CSS nie jest świadomy pomiarów lub zdarzeń, które mają miejsce na stronie po jej załadowaniu. Na przykład elementy iframe używane do osadzania filmów z YouTube mają określoną szerokość i wysokość. Chociaż możesz ustawić szerokość na auto
w CSS, nie ma łatwego sposobu na utrzymanie prawidłowego współczynnika proporcji szerokości do wysokości, gdy wideo rozwija się, aby wypełnić dostępną przestrzeń.
Typowym obejściem zachowania responsywnych proporcji podczas skalowania jest umieszczenie zawartości, która musi zachować swój współczynnik proporcji, w otoce, a następnie dodanie do otoki dopełnienia wartością opartą na stosunku szerokości do wysokości, który chcesz zachować. To działa, ale wymaga wcześniejszej znajomości proporcji wszystkich filmów, a także wymaga większej liczby znaczników HTML (element opakowania) dla każdego filmu, który chcesz osadzić w sposób responsywny. Pomnóż to w każdej witrynie, która ma responsywne filmy, a to jest dużo rzeczy, które nie musiałyby tam być, gdyby CSS był trochę mądrzejszy.
Być może lepsze podejście do responsywnych współczynników proporcji polega na umieszczeniu każdego filmu w opakowaniu bez dopełniania, a następnie napisaniu biblioteki JavaScript, która oblicza współczynnik proporcji każdego znalezionego filmu i stosuje odpowiednią ilość dopełnienia do każdego opakowania.
Ale co by było, gdyby CSS miał bezpośredni dostęp do tych pomiarów? Nie tylko moglibyśmy skonsolidować CSS dla wszystkich różnych współczynników proporcji w jednej regule, ale gdybyśmy mogli ocenić go po załadowaniu strony, moglibyśmy napisać jedną regułę, która responsywnie zmienia rozmiar każdego filmu, który kiedykolwiek nadamy mu w przyszłości. I mogliśmy to wszystko zrobić bez żadnych opakowań!
Jeśli to wydaje się zbyt piękne, aby mogło być prawdziwe, sprawdź to. Oto, jak proste jest napisanie w EQCSS elementów iframe bez owijania i responsywnych zmian rozmiaru:
@element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }
W tym przypadku width
i height
odnoszą się do atrybutów width=“”
i height=“”
w elemencie iframe w HTML. JavaScript może wykonać obliczenie (width/height)
, co daje nam proporcje; i aby zastosować go na dowolnej szerokości, podzielilibyśmy po prostu bieżącą szerokość elementu iframe przez współczynnik.
Ma zwięzłość i czytelność CSS oraz całą moc JavaScript. Bez dodatkowych opakowań, bez dodatkowych klas i bez dodatkowego CSS.
Bądź jednak ostrożny z eval(')
. Jest powód, dla którego wyrażenia CSS były w przeszłości uważane za niebezpieczne, i jest też powód, dla którego wypróbowaliśmy ten pomysł. Jeśli nie jesteś ostrożny z liczbą elementów, do których je stosujesz na stronie lub z częstotliwością przeliczania stylów, JavaScript może skończyć się uruchamianiem rzeczy setki razy więcej niż to konieczne. Na szczęście EQCSS pozwala nam wywołać EQCSS.apply()
lub EQCSS.throttle()
w celu ręcznego przeliczenia stylów, dzięki czemu mamy większą kontrolę nad aktualizacją stylów.
Strefa zagrożenia!
Inne problemy mogą wystąpić, jeśli tworzysz zapytania o sprzecznych warunkach lub stylach. EQCSS, podobnie jak CSS, jest odczytywany od góry do dołu przy użyciu hierarchii szczegółowości. Chociaż CSS jest językiem deklaratywnym, zawiera pewne zaawansowane funkcje. Tylko kilka kroków dzieli go od ukończenia Turinga jako języka programowania. Jak dotąd debugowanie CSS było dość prostą sprawą, ale EQCSS zmienia CSS z po prostu interpretowanego języka deklaratywnego na dynamiczny język arkuszy stylów z dodatkową warstwą interpretacji między CSS a przeglądarką. Na tym nowym terytorium pojawia się wiele potencjalnych nowych pułapek.
Oto przykład odwrotnej pętli w EQCSS, coś, na co normalne zapytania o media CSS są z założenia odporne:
@element '.widget' and (min‐width: 300px) { $this { width: 200px; } }
Nazywam to jekyll: hide;
CSS. Ale oprócz ciągłego wyzwalania się jednego stylu, istnieje również możliwość napisania wielu zapytań, które wyzwalają się nawzajem, w czymś, co nazywamy „podwójnie odwróconą pętlą odwrotną”, najgorszą ze wszystkich:
@element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }
Teoretycznie ten nieszczęsny widżet utknął w pętli, zmieniając rozmiar między 200 a 500 pikseli do końca czasu, nie mogąc ustalić szerokości. W takich przypadkach EQCSS po prostu oblicza reguły w kolejności, w jakiej są oceniane, nagradza zwycięzcę i przechodzi dalej. Gdybyś miał zmienić kolejność, w jakiej pojawiają się te reguły, ten drugi styl zawsze zwycięży, jeśli będą miały taką samą szczegółowość.
Niektórzy twierdzą, że możliwość tworzenia pętli (lub nawet podwójnie odwróconych pętli wzajemnych) jest wadą projektową, ale aby zapobiec powstawaniu pętli, należałoby ograniczyć moc EQCSS w sposób, który usunie większość wartość, którą zapewnia składnia. Z drugiej strony tworzenie nieskończonych pętli w JavaScript jest bardzo łatwe, ale nie jest to postrzegane jako wada języka — jest postrzegane jako dowód jego mocy! To samo dotyczy zapytań elementowych.
Debugowanie zapytań o elementy
Obecnie debugowanie zapytań o elementy może przypominać debugowanie zapytań o media, zanim nie mieliśmy narzędzi takich jak inspektor sieci, które pokazywały nam style, tak jak zostały obliczone na stronie. Na razie debugowanie i opracowywanie zapytań o elementy wymagają od programisty zachowania mentalnego modelu tego, jakie zachowanie responsywne powinno mieć miejsce. W przyszłości budowanie narzędzi programistycznych uwzględniających EQCSS może być możliwe, ale obecnie narzędzia programistyczne we wszystkich głównych przeglądarkach są świadome tylko stylów, które EQCSS już zastosował do elementów na stronie, i nie są świadome warunki reakcji, które obserwuje EQCSS.
Jak projektować za pomocą zapytań elementów
Najprostszym sposobem wykorzystania zapytań elementowych jest przekształcenie istniejących projektów za pomocą zapytań o media na zapytania elementowe, „uwolnienie” elementów i ich responsywnych stylów z jednego układu oraz ułatwienie ponownego wykorzystania tego kodu na innych stronach i projektach. Poniższe zapytanie o media i zapytanie o element może oznaczać to samo:
footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }
Różnica polega na tym, że w oryginalnym przykładzie linki w stopce pozostają display: block
dopóki przeglądarka nie będzie miała co najmniej 500 pikseli szerokości. Drugi przykład, używający zapytań elementowych, wyglądałby tak samo, ale tylko wtedy, gdyby element footer
miał pełną szerokość.
Po uwolnieniu tego stylu z oryginalnego zapytania o media, możemy teraz umieścić stopkę w kontenerze o dowolnej szerokości i mieć pewność, że gdy stopka wymaga zastosowania stylu responsywnego (tj. gdy jest węższa niż 500 pikseli), zostanie stosowany.
- Upewnij się, że
EQCSS.js
jest obecny w kodzie HTML dokumentu docelowego. - Zamień
@media
na@element
w CSS. - Dodaj selektor CSS do zakresu każdego zapytania
@element
. - Opcjonalnie: Zamień wystąpienia elementu objętego zakresem na
$this
w zapytaniach o elementy.
O ile konwertowany komponent projektu nie został pierwotnie zaprojektowany do wyświetlania przy użyciu pełnej szerokości okna przeglądarki, prawdopodobnie będziesz musiał dostosować punkty przerwania po konwersji na zapytania elementów.
Unikanie blokady
Doświadczenie tworzenia stylów EQCSS jest podobne do doświadczenia pisania zwykłego CSS: wszystkie Twoje ulubione właściwości i techniki CSS nadal istnieją, tylko z kilkoma dodatkowymi funkcjami, które pomagają im współpracować na nowe sposoby. Ponieważ EQCSS wysyła do przeglądarki standardowy kod CSS, każda funkcja CSS, dla której Twoja przeglądarka ma wbudowaną obsługę, będzie działać w połączeniu z EQCSS. Jeśli pewnego dnia funkcje, takie jak zapytania o elementy i style o określonym zakresie, są określone w CSS i obsługiwane w przeglądarkach, będziesz mógł od razu zacząć ich używać w swoim kodzie EQCSS, nadal polegając na EQCSS w przypadku innych funkcji, których przeglądarka nie obsługuje. jeszcze wspierać natywnie.
Ponieważ możesz używać składni EQCSS zarówno bezpośrednio w CSS, jak i we własnym skrypcie, z typem text/eqcss
, jeśli CSS kiedykolwiek opracuje składnię dla zapytań o elementy natywne, nadal będziesz w stanie załadować EQCSS jako skrypt i uniknąć konfliktów .
Patrząc w przyszłość, jednym z rozwiązań, z którym obecnie eksperymentują twórcy przeglądarek, jest Houdini, które umożliwiłoby twórcom wtyczek rozszerzenie CSS na nowe sposoby, na przykład dodanie obsługi samej przeglądarki. Pewnego dnia może być możliwe napisanie wydajniejszych wtyczek, które będą interpretować składnię EQCSS i wprowadzać te funkcje do przeglądarek w bardziej bezpośredni i wydajny sposób niż pozwala na to obecna biblioteka JavaScript.
Czy więc nadal powinniśmy używać zapytań o media?
Tak, chociaż zapytania o elementy zapewniają wiele nowych i ekscytujących sposobów kierowania elementów za pomocą stylów, zapytania o media (choć ograniczone) zawsze będą działać szybciej w przeglądarce niż styl, który do obliczeń opiera się na JavaScript. Jednak zapytania o media CSS są czymś więcej niż tylko stylizacją HTML dla ekranów. Zapytania o media CSS obsługują również zapytania drukowane i inne sposoby wyświetlania informacji w witrynach internetowych. EQCSS może być używany w połączeniu z zapytaniami o media dla takich rzeczy, jak style drukowania, więc nie ma potrzeby wycofywania zapytania o media tylko dlatego, że teraz można również używać zapytań o elementy!
Projektowanie z wizją 20 ⁄ 20
Najlepszą rzeczą, jaką możemy zrobić dla przyszłości CSS, jest jak największe eksperymentowanie z tymi pomysłami już dziś. Żadna ilość burzy mózgów i teoretyzowania na temat tych funkcji nie będzie tak przydatna, jak próba ich wdrożenia i wykorzystania, odkrywanie technik, które czynią je użytecznymi i potężnymi.
Oprócz dostarczania rozwiązania dla zapytań o elementy, EQCSS.js, miejmy nadzieję, służy również jako platforma dla innych eksperymentów w rozszerzaniu CSS. If you have an idea for a new responsive condition, a new CSS property or a new selector to use in your code, forking EQCSS.js and modifying it to include your idea can get you most of the way there with little effort.
Modular Design
In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.
The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.
Thinking Element-First
Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.
For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”
<form> <input type=search> <input type=button value=Search> </form>
Desktop-First Approach
In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.
input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }
Mobile-First Approach
In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.
input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }
Element-First Approach
In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form
element itself, writing a style like this:
input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }
The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.
Resources For Getting Started
EQCSS-Enabled Template
<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>
Demos
- Responsive Aspect Ratio
- Sticky Scroll Header
- Blockquote Style
- Kalendarz
- Content Demo
- Counting Children Demo
- Date Demo
- Zastrow-style Element Query Demo Demo
- Flyout Demo
- Headline Demo
- Media Player Demo
- Message Style Demo
- Modal Demo
- Nav Demo
- Parent Selector Demo
- Pricing Chart Demo
- Responsive Tables Demo
- Scroll-triggered Blocker Demo
- Signup Form Demo
- Testimonials Block Demo
- Tweet-Counter Demo
- JS Variables Demo
- Responsive Scaling Demo
- Geometric Design Demo
- Responsive Order Form
- Element Query Grid
- JS Functions in CSS
- Responsive Content Waterfall
Dalsza lektura
You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.
Happy hacking!