Kilka razy zapytania dotyczące rozmiaru kontenera pomogłyby mi w rozwiązaniu PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Kilka zapytań o rozmiar kontenera pomogłoby mi

Zapytania kontenerowe CSS wciąż zyskują na popularności i wielu z nas ma z nimi ręce, nawet jeśli chodzi o małe eksperymenty lub cokolwiek innego. Mają świetne, ale nie do końca pełne, obsługa przeglądarki — wystarczająco, aby uzasadnić ich użycie w niektórych projektach, ale może nie w takim stopniu, w którym moglibyśmy pokusić się o wymianę zapytania o media z poprzednich projektów dzięki nowym, błyszczącym zapytaniom o rozmiar kontenera.

Z pewnością są jednak przydatne! W rzeczywistości spotkałem się już z kilkoma sytuacjami, w których naprawdę chciałem po nie sięgnąć, ale po prostu nie mogłem spełnić wymagań dotyczących wsparcia. Gdybym mógł je wykorzystać, tak by to wyglądało w tamtych sytuacjach.

Wszystkie poniższe wersje demonstracyjne najlepiej będzie oglądać w przeglądarce Chrome lub Safari w chwili pisania tego tekstu. Firefox planuje wsparcie statku w wersji 109.

Przypadek 1: Siatka kart

W pewnym sensie musiałeś się tego spodziewać, prawda? Jest to tak powszechny wzorzec, że wydaje się, że każdy z nas w pewnym momencie go napotkał. Ale faktem jest, że zapytania o rozmiar kontenera byłyby dla mnie ogromną oszczędnością czasu i lepszym wynikiem, gdybym mógł ich używać zamiast standardowych zapytań o media.

Załóżmy, że otrzymałeś zadanie zbudowania tej siatki kart z wymaganiem, aby każda karta zachowała proporcje 1:1:

Kilka zapytań o rozmiar kontenera pomogłoby mi

Jest twardszy niż się wydaje! Problem polega na tym, że ustalanie rozmiaru zawartości komponentu na podstawie szerokości rzutni sprawia, że ​​jesteś zdany na łaskę tego, jak komponent zareaguje na rzutnię — a także sposób, w jaki reagują na niego wszelkie inne kontenery nadrzędne. Jeśli na przykład chcesz zmniejszyć rozmiar czcionki nagłówka karty, gdy karta osiągnie określony rozmiar w tekście, nie ma na to niezawodnego sposobu.

Możesz ustawić rozmiar czcionki w vw jednostek, jak sądzę, ale komponent jest nadal powiązany z szerokością okna przeglądarki. A to może powodować problemy, gdy siatka kart jest używana w innych kontekstach, które mogą nie mieć tych samych punktów przerwania.

W moim prawdziwym projekcie zdecydowałem się na podejście JavaScript, które:

  1. Posłuchaj zdarzenia zmiany rozmiaru.
  2. Oblicz szerokość każdej karty.
  3. Dodaj wewnętrzny rozmiar czcionki do każdej karty na podstawie jej szerokości.
  4. Stylizuj wszystko w środku za pomocą em jednostek.

Wydaje się dużo pracy, prawda? Ale jest to stabilne rozwiązanie, aby uzyskać wymagane skalowanie na różnych rozmiarach ekranu w różnych kontekstach.

Zapytania kontenerowe byłyby o wiele lepsze, ponieważ zapewniają nam jednostki zapytania kontenera, tak jak cqw jednostka. Pewnie już to rozumiesz, ale 1cqw jest równe 1% szerokości kontenera. Mamy również cqi jednostka, która jest miarą wewnętrznej szerokości kontenera i cqb dla szerokości bloku kontenera. Tak więc, jeśli mamy pojemnik na karty, to znaczy 500px szeroki, A 50cqw wartość oblicza się 250px.

Gdybym mógł używać zapytań kontenerowych w mojej siatce kart, mógłbym skonfigurować .card komponent jako kontener:

.card { 
  container: card / size;
}

Wtedy mógłbym ustawić wewnętrzne opakowanie padding to skala w 10% ukończenia .cardszerokość za pomocą cqw jednostka:

.card__inner { 
  padding: 10cqw; 
} 

To dobry sposób na spójne skalowanie odstępów między krawędziami karty i jej zawartością, bez względu na to, gdzie karta jest używana przy danej szerokości widocznego obszaru. Zapytania o media nie są wymagane!

Inny pomysł? Posługiwać się cqw jednostki dla rozmiaru czcionki wewnętrznej zawartości, a następnie zastosuj dopełnienie em jednostki:

.card__inner { 
  font-size: 5cqw; 
  padding: 2em;
} 

5cqw jest wartością arbitralną — taką, na której się zdecydowałem. To wypełnienie jest nadal równe 10cqw ponieważ em jednostka jest względna .card__inner rozmiar czcionki!

Złapałeś to? The 2em jest względem 5cqw ustawiony rozmiar czcionki na tym samym pojemniku. Kontenery działają inaczej niż to, do czego jesteśmy przyzwyczajeni, jak np em jednostki są względne względem tego samego elementu font-size value. Ale szybko zauważyłem, że jednostki zapytań kontenerów odnoszą się do najbliższy rodzic, który jest również kontenerem.

Na przykład, 5cqw nie skaluje się w oparciu o .card szerokość elementu w tym przykładzie:

.card { 
  container: card / size; 
  container-name: card; 
  font-size: 5cqw; 
}

Zamiast tego skaluje się do dowolnego najbliższego elementu nadrzędnego, który jest zdefiniowany jako kontener. Dlatego założyłem tzw .card__inner obwoluta.

Przypadek 2: Naprzemienny układ

Potrzebowałem jeszcze jednego elementu karty w innym projekcie. Tym razem potrzebowałem karty, aby przejść z układu poziomego do układu pionowego… następnie z powrotem do układu poziomego iz powrotem do układu pionowego, gdy ekran się zmniejszy.

Przedstawia cztery stany elementu karty zmieniające się między układem pionowym i poziomym w różnych punktach przerwania.
Kilka zapytań o rozmiar kontenera pomogłoby mi

Wykonałem brudną robotę, zmieniając ten komponent w portret w tych dwóch określonych zakresach rzutni (krzyczeć do nowa składnia zakresu zapytań o media!), ale znowu problem polega na tym, że jest on następnie zablokowany dla ustawionych na nim zapytań o media, jego rodzica i wszystkiego innego, co może odpowiadać na szerokość widocznego obszaru. Chcemy czegoś, co działa w każdych warunkach, nie martwiąc się o to, gdzie zawartość się zepsuje!

Zapytania o kontenery ułatwiłyby to zadanie dzięki @container reguła:

.info-card {
  container-type: inline-size;
  container-name: info-card;
}

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Jedno zapytanie, nieskończona płynność:

Ale trzymaj się! Jest coś, na co możesz chcieć uważać. W szczególności użycie takiego zapytania kontenera w systemie projektowania opartym na rekwizytach może być trudne. Na przykład to .info-card komponent może zawierać komponenty potomne, których wygląd zależy od rekwizytów.

Dlaczego to wielka sprawa? Układ pionowy karty może wymagać alternatywnego stylu, ale nie można zmienić rekwizytów JavaScript za pomocą CSS. W związku z tym ryzykujesz powielenie wymaganych stylów. Właściwie dotknąłem tego i jak to obejść w innym artykule. Jeśli potrzebujesz użyć zapytań kontenerowych dla znacznej części swojego stylu, być może będziesz musiał oprzeć na nich cały system projektowy, zamiast próbować wcisnąć je do istniejącego systemu projektowego, który jest obciążony zapytaniami o media.

Przypadek 3: obrysy SVG

Oto kolejny bardzo powszechny wzorzec, którego ostatnio użyłem, w którym zapytania o rozmiar kontenera skutkowałyby bardziej dopracowanym produktem. Załóżmy, że masz zamkniętą ikonę z nagłówkiem:

Heading

Skalowanie ikony za pomocą rozmiaru tytułu jest dość proste, nawet bez zapytań o media. Problem polega jednak na tym, że pliki SVG stroke-width może stać się zbyt chudy, aby można go było tak dobrze zauważyć w mniejszym rozmiarze, i być może przykuć zbyt wiele uwagi super grubym pociągnięciem w większym rozmiarze.

Musiałem utworzyć i zastosować klasy do każdej instancji ikony, aby określić jej rozmiar i szerokość obrysu. To jest OK, jeśli ikona znajduje się obok nagłówka, który jest stylizowany na stały rozmiar czcionki, jak sądzę, ale nie jest tak dobrze, gdy pracuje się z płynnym typem, który ciągle się zmienia.

Blokada sześciokątnej ikony i kierunku w trzech różnych rozmiarach, od dużego do małego.
Kilka zapytań o rozmiar kontenera pomogłoby mi

Rozmiar czcionki nagłówka może być oparty na szerokości widocznego obszaru, więc ikona SVG musi być odpowiednio dostosowana tam, gdzie jej obrys działa w dowolnym rozmiarze. Możesz ustawić szerokość obrysu w stosunku do nagłówka font-size poprzez ustawienie go em jednostki. Ale jeśli masz określony zestaw rozmiarów obrysu, którego musisz się trzymać, to nie zadziała, ponieważ w przeciwnym razie skaluje się liniowo — nie ma sposobu, aby dostosować go do określonego stroke-width wartości w określonych punktach bez uciekania się do zapytań o media dotyczących szerokości widocznego obszaru.

Ale oto, co bym zrobił, gdybym miał luksus zapytań o kontenery w tamtym czasie:

.icon {
  container: icon / size; 
  width: 1em; 
  height: 1em; 
}

.icon svg {
  width: 100%; 
  height: 100%; 
  fill: none; 
  stroke: #ccc; 
  stroke-width: 0.8; 
}

@container icon (max-width: 70px) {
  .icon svg {
    stroke-width: 1.5; 
  }
}
@container icon (max-width: 35px) {
  .icon svg {
    stroke-width: 3;
  }
}

Porównaj implementacje i zobacz, jak wersja zapytania kontenera przyciąga obrys SVG do określonych szerokości, które chcę na podstawie szerokości kontenera.

Bonus: inne typy zapytań o rozmiar kontenera

OK, więc nie spotkałem się z tym w prawdziwym projekcie. Ale kiedy przeglądałem informacje na temat zapytań o kontenery, zauważyłem, że istnieją dodatkowe rzeczy, które możemy zapytać o kontener, które są związane z rozmiarem kontenera lub wymiarami fizycznymi.

Większość przykładów, które widziałem, dotyczy zapytania width, max-width, min-width, height, block-size, inline-size tak jak robiłem przez cały ten artykuł.

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Ale MDN przedstawia jeszcze dwie rzeczy możemy zapytać przeciwko. Jeden jest orientation co ma sens, ponieważ używamy go cały czas w zapytaniach o media. Nie inaczej jest w przypadku zapytań kontenerowych:

@media screen (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

@container info-card (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Inny? Jego aspect-ratio, Uwierz lub nie:

@container info-card (aspect-ratio: 3/2) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Oto edytowalne demo do zabawy z obydwoma przykładami:

Nie znalazłem jeszcze dobrego zastosowania dla żadnego z nich. Jeśli masz jakieś pomysły lub czujesz, że mogłoby to pomóc w twoich projektach, daj mi znać w komentarzach!

Znak czasu:

Więcej z Sztuczki CSS