Pierwsze kroki z zapytaniami dotyczącymi stylu

Możliwość wysyłania zapytań dotyczących rozmiaru wbudowanego elementu nadrzędnego i wartości jednostek zapytań w kontenerze osiągnęła stabilną obsługę we wszystkich nowoczesnych wyszukiwarkach.

Obsługa przeglądarek

  • 105
  • 105
  • 110
  • 16

Źródło

Specyfikacja komponentu obejmuje jednak nie tylko zapytania dotyczące rozmiaru, ale także umożliwia wysyłanie zapytań dotyczących wartości stylu elementu nadrzędnego. Od wersji 111 Chromium będzie można zastosować ograniczenie stylów do wartości właściwości niestandardowych i wypytać element nadrzędny z wartością właściwości niestandardowej.

Obsługa przeglądarek

  • 111
  • 111
  • x
  • x

Źródło

Dzięki temu mamy jeszcze większą kontrolę nad stylami w CSS i umożliwiamy lepsze oddzielenie logiki aplikacji i warstwy danych od jej stylów.

Specyfikacja modułu przechowywania CSS poziomu 3, która obejmuje zapytania dotyczące rozmiarów i stylów, pozwala pobierać dowolne style z elementu nadrzędnego, w tym pary właściwości i wartości, np. font-weight: 800. Jednak podczas wdrażania tej funkcji zapytania dotyczące stylu działają tylko z wartościami niestandardowych właściwości CSS. Nadal jest to bardzo przydatne przy łączeniu stylów i oddzielaniu danych od projektu. Przyjrzyjmy się korzystaniu z zapytań dotyczących stylu z niestandardowymi właściwościami CSS:

Wprowadzenie do zapytań dotyczących stylu

Załóżmy, że mamy taki kod HTML:

<ul class="card-list">
  <li class="card-container">
    <div class="card">
      ...
    </div>
  </li>
</ul>

Aby korzystać ze stylów zapytań, musisz najpierw skonfigurować element kontenera. Wymaga to nieco innego podejścia w zależności od tego, czy zapytanie dotyczy bezpośredniego, czy pośredniego rodzica.

Zapytanie dotyczące bezpośrednich elementów nadrzędnych

Diagram zapytania dotyczącego stylu.

W przeciwieństwie do zapytań dotyczących stylów nie musisz stosować izolacji do elementu .card-container za pomocą właściwości container-type ani container, aby usługa .card mogła wysyłać zapytania dotyczące stylów bezpośredniego elementu nadrzędnego. Musimy jednak zastosować style (w tym przypadku wartości właściwości niestandardowych) do kontenera (w tym przypadku .card-container) lub dowolnego elementu zawierającego element, który określamy w DOM. Nie możemy zastosować stylów, o które pytamy bezpośrednio w elemencie, którego styl określamy za pomocą tego zapytania, ponieważ mogłoby to spowodować zapętlenie.

Aby wysłać zapytanie bezpośrednio do rodzica, możesz napisać:

/* styling .card based on the value of --theme on .card-container */
@container style(--theme: warm) {
  .card {
    background-color: wheat;
    border-color: brown; 
    ...
  }
}

Jak widzisz, zapytanie stylu opakowuje zapytanie za pomocą atrybutu style(). Ma to na celu odróżnienie wartości rozmiaru od stylów. Możesz np. wpisać zapytanie @container (min-width: 200px) { … } dotyczące szerokości kontenera. Spowoduje to zastosowanie stylów, jeśli kontener nadrzędny ma szerokość co najmniej 200 pikseli. min-width może jednak być także właściwością CSS i zapytać o wartość CSS min-width, korzystając z zapytań dotyczących stylu. Dlatego użyj kodu style(), aby podkreślić różnicę: @container style(min-width: 200px) { … }.

Stosowanie stylu stylów nadrzędnych niebezpośrednich

Jeśli chcesz utworzyć zapytania dotyczące stylów elementu, który nie jest bezpośrednim elementem nadrzędnym, musisz nadać mu właściwość container-name. Na przykład możemy zastosować style do elementu .card na podstawie stylów elementu .card-list, podając wartość container-name w elemencie .card-list i odwołując się do niej w zapytaniu dotyczącym stylu.

/* styling .card based on the value of --moreGlobalVar on .card-list */
@container cards style(--moreGlobalVar: value) {
  .card {
    ...
  }
}

Ogólnie sprawdzoną metodą jest nadanie nazw kontenerów, aby ułatwić Ci zrozumienie zapytań i ułatwienie dostępu do nich. Może się to przydać na przykład wtedy, gdy chcesz bezpośrednio zmieniać styl elementów w elemencie .card. Bez nazwanego kontenera w systemie .card-container nie mogą wysyłać zapytań dotyczących tego kontenera.

W praktyce jednak wszystkie te rozwiązania mają sens. Przyjrzyjmy się kilku przykładom:

Style zapytań w praktyce

Obraz demonstracyjny z kilkoma kartami produktów, niektórymi z tagami „nowe” lub „mało na stanie” i kartą z informacjami o niskiej dostępności na czerwonym tle.

Zapytania dotyczące stylu są szczególnie przydatne, gdy masz komponent wielokrotnego użytku z wieloma odmianami lub gdy nie masz kontroli nad wszystkimi stylami, ale chcesz wprowadzić zmiany w określonych przypadkach. Ten przykład pokazuje zestaw kart usług, które mają ten sam komponent karty. Niektóre karty produktów zawierają dodatkowe szczegóły lub uwagi, np. „Nowe” lub „Mało na stanie”, które są wyświetlane przez właściwość niestandardową o nazwie --detail. Jeśli produkt jest w magazynie, otrzyma on głębokie czerwone tło. Tego typu informacje są prawdopodobnie renderowane przez serwer i można je zastosować na kartach za pomocą stylów wbudowanych:

 <div class="product-list">
  <div class="product-card-container" style="--detail: new">
    <div class="product-card">
      <div class="media">
        <img .../>
      <div class="comment-block"></div>
    </div>
  </div>
  <div class="meta">
    ...
  </div>
  </div>
  <div class="product-card-container" style="--detail: low-stock">
    ...
  </div>
  <div class="product-card-container">
    ...
  </div>
  ...
</div>

Na podstawie tych uporządkowanych danych możesz przekazywać wartości do funkcji --detail i stosować niestandardowe style CSS za pomocą tej właściwości:

@container style(--detail: new) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'New';
    border: 1px solid currentColor;
    background: white;
    ...
  }
}

@container style(--detail: low-stock) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'Low Stock';
    border: 1px solid currentColor;
    background: white;
    ...
  }
  
  .media-img {
    border: 2px solid brickred;
  }
}

Powyższy kod pozwala nam zastosować element dla --detail: low-stock i --detail: new, ale być może w bloku kodu jest pewne zbędne elementy. Obecnie nie można wysyłać zapytań dotyczących tylko obecności elementu --detail za pomocą parametru @container style(--detail), które umożliwiłoby lepsze udostępnianie stylów i zmniejszenie liczby powtórzeń. Ta funkcja jest obecnie omawiana w grupie roboczej.

Karty pogodowe

W poprzednim przykładzie do zastosowania stylów użyto 1 właściwości niestandardowej z wieloma możliwymi wartościami. Możesz je jednak ze sobą połączyć, używając wielu właściwości niestandardowych i wysyłając do nich zapytania. Oto przykład karty pogody:

Wersja demonstracyjna kart pogodowych.

Aby dostosować styl gradientów i ikon tła tych kart, określ cechy pogody, np. „pochmurnie”, „deszczowo” lub „słonecznie”:

@container style(--sunny: true) {
  .weather-card {
    background: linear-gradient(-30deg, yellow, orange);
  }
  
  .weather-card:after {
    content: url(<data-uri-for-demo-brevity>);
    background: gold;
  }
}

W ten sposób możesz nadać każdej karcie styl, zgodnie z jej unikalnymi cechami. Stylizację możesz też tworzyć w przypadku kombinacji cech (właściwości niestandardowych), korzystając z kombinatora and tak samo jak w przypadku zapytań o media. Na przykład dzień, w którym jest pochmurno i słonecznie, wyglądałby tak:

@container style(--sunny: true) and style(--cloudy: true) {
    .weather-card {
      background: linear-gradient(24deg, pink, violet);
    }
  
  .weather-card:after {
      content: url(<data-uri-for-demo-brevity>);
      background: violet;
  }
}

Oddzielenie danych od projektu

W obu wersjach demonstracyjnych zasadniczo warto oddzielić warstwę danych (element DOM, który byłby renderowany na stronie) od zastosowanych stylów. Style są zapisywane jako możliwe warianty pasujące do stylu komponentów, a punkt końcowy może wysyłać dane, których używa do określania stylu komponentu. Możesz użyć jednej wartości (w pierwszym przypadku wartości --detail) lub wielu zmiennych, jak w drugim przypadku (ustawienie --rainy, --cloudy lub --sunny. Najlepsze w tym jest to, że możesz też łączyć te wartości. Sprawdzenie obu tych elementów (--sunny i --cloudy) może pokazać styl częściowo zachmurzony.

Wartości właściwości niestandardowych można aktualizować za pomocą JavaScriptu podczas konfigurowania modelu DOM (tj. podczas tworzenia komponentu w platformie) lub aktualizować w dowolnym momencie za pomocą metody <parentElem>.style.setProperty('--myProperty’, <value>). I

Oto przykład, w którym za pomocą kilku wierszy kodu aktualizuje się --theme przycisku i stosuje style za pomocą zapytań dotyczących stylu oraz tej właściwości niestandardowej (--theme):

Dostosuj kartę za pomocą zapytań dotyczących stylu, kod JavaScript używany do aktualizowania wartości właściwości niestandardowych to:

const themePicker = document.querySelector('#theme-picker')
const btnParent = document.querySelector('.btn-section');

themePicker.addEventListener('input', (e) => {
  btnParent.style.setProperty('--theme', e.target.value);
})

Funkcje opisane w tym artykule to dopiero początek. Od zapytań dotyczących kontenerów możesz oczekiwać więcej funkcji, które pomogą Ci tworzyć dynamiczne, elastyczne interfejsy. Jeśli chodzi o zapytania dotyczące stylu, nadal jest kilka nierozwiązanych problemów. Jedna z nich to implementacja zapytań dotyczących stylów CSS poza właściwościami niestandardowymi. Wbudowane rozwiązanie wkracza już w specyfikację na obecnym poziomie, ale nie zostało jeszcze wdrożone w żadnej przeglądarce. Ocena kontekstu wartości logicznych powinna zostać dodana do bieżącego poziomu specyfikacji po rozwiązaniu nierozwiązanego problemu, a zapytania dotyczące zakresów są planowane na następnym poziomie specyfikacji.