Mozilla Hacks: Grupowanie selektorów za pomocą -moz-any()

Poniższa notka pierwotnie pojawiła się w blogu Davida Barona (a następnie w Mozilla Hacks). Jak większość treści z MozHacks, zarówno oryginalny artykuł, jak i poniższe tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

Funkcjonalność opisana poniżej pojawiła się w Mozilla Central (trunku) i obecnie dostępna jest tylko w conocnych testowych kompilacjach Firefoksa.

Grupowanie selektorów za pomocą -moz-any() w Firefoksie 4

Ostatniej nocy (tj. 23 kwietnia – przyp. tłum.) włączyłem do hg obsługę grupowania selektorów przy użyciu :-moz-any(). Umożliwia to stosowanie alternatywy pomiędzy kombinatorami, dzięki czemu nie trzeba dla każdego różniącego się kawałka selektora powtarzać wielokrotnie podobnych selektorów („any” po angielsku oznacza „dowolny”, tak więc zapis :-moz-any(ol, dir, ul) można czytać jako „dowolny spośród ol, dir i ul” – przyp. tłum.). Obsługa :-moz-any() pozwoliła nam na przykład zamianę tej regułki we wbudowanym w przeglądarkę domyślnym arkuszu stylów:

/* potrójnie (lub bardziej) zagnieżdżone listy nieuporządkowane
   wyświetają prostokąt przy każdym elemencie */
ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
menu ol menu, menu ul menu, menu menu menu, menu dir menu,
menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
  list-style-type: square;
}

na taką:

/* potrójnie (lub bardziej) zagnieżdżone listy nieuporządkowane
   wyświetają prostokąt przy każdym elemencie */
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
  list-style-type: square;
}

Teoretycznie można to nawet uprościć do postaci:

/* potrójnie (lub bardziej) zagnieżdżone listy nieuporządkowane
   wyświetają prostokąt przy każdym elemencie */
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir)
    :-moz-any(ul, menu, dir) {
  list-style-type: square;
}

…ale działałoby to wolniej, jako że taka regułka nie wpadłaby do kubełka ze znacznikami. (Jeśli :-moz-any() stanie się popularne, możemy dodać dodatkowy kod, dzięki któremu będzie to równie szybkie, ale na razie tego nie zrobiliśmy).

:-moz-any() może zawierać selektory zawierające wiele prostych selektorów (zgodnie z definicją prostych selektorów ze specyfkacji CSS 3 Selectors, w odróżnieniu od CSS 2.1), ale nie może zawierać kombinatorów ani pseudoelementów. Można zatem napisać: :-moz-any(p.warning.new, p.error, div#topnotice) albo :-moz-any(:link, :visited).external:-moz-any(:active, :focus), ale nie można wstawić div p ani div > p czy też :first-letter wewnątrz :-moz-any().

Przedrostek -moz- jest tu obecny z dwóch powodów. Po pierwsze, to tylko propozycja i nie znalazła się jeszcze w żadnej specyfikacji. Po drugie, nie jest to jeszcze kompletna konstrukcja, ponieważ na razie nie obsługuje poprawnie specyficzności.

Ciekawostka: -moz-any() przyda się w kontekście sekcji i nagłówków w HTML 5. Jako że elementy section, article, aside i nav mogą być zafnieżdżane, stylowanie wszystkich elementów h1 na różnych poziomach zagnieżdżenia może być – przy dotychczasowej składni – poważnie skomplikowane.

/* Poziom 0 */
h1 {
  font-size: 30px;
}
/* Poziom 1 */
section h1, article h1, aside h1, nav h1 {
  font-size: 25px;
}
/* Poziom 2 */
section section h1, section article h1, section aside h1, section nav h1,
article section h1, article article h1, article aside h1, article nav h1,
aside section h1, aside article h1, aside aside h1, aside nav h1,
nav section h1, nav article h1, nav aside h1, nav nav h1, {
  font-size: 20px;
}
/* Poziom 3 */
/* ...nawet o tym nie myśl! */

Zastosowanie -moz-any() znacznie upraszcza ten kod:

/* Poziom 0 */
h1 {
  font-size: 30px;
}
/* Poziom 1 */
-moz-any(section, article, aside, nav) h1 {
  font-size: 25px;
}
/* Poziom 2 */
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav) h1 {
  font-size: 20px;
}
/* Poziom 3 */
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav)
-moz-any(section, article, aside, nav) h1 {
  font-size: 15px;
}

2 thoughts on “Mozilla Hacks: Grupowanie selektorów za pomocą -moz-any()

  1. Świetny pomysł. Chciałbym zobaczyć ten selektor w oficjalnej specyfikacji. Mam wiec nadzieje, ze innym tez się spodoba.

  2. Niesamowite, bo tydzięń temu potrzebowałem coś bardzo podobnego:

    a b c d1 e1 f g, a b c d2 e2 f g {
    }

    i chciałem zapisać to jako coś takiego

    a b c (d1 e1, d2 e2) f g {
    }

    Co nie tylko jest krótsze i ułatwia poprawki, ale jest porostu wygodne.

    Widzę, że teraz będę mógł to zrobić :)

    a b c :-mod-any(d1 e1, d2 e2) f g {
    }

Leave a reply to witek Cancel reply