Jakie są zasady nakładania się zapytań o media w CSS?

89

Jak dokładnie rozdzielić zapytania o media, aby uniknąć nakładania się?

Na przykład, jeśli weźmiemy pod uwagę kod:

@media (max-width: 20em) {
    /* for narrow viewport */
}

@media (min-width: 20em) and (max-width: 45em) {
    /* slightly wider viewport */
}

@media (min-width: 45em) {
    /* everything else */
}

Co się stanie we wszystkich obsługiwanych przeglądarkach, dokładnie przy 20em i 45em?

Widziałem, jak ludzie używają: rzeczy takie jak 799px, a następnie 800px, ale co z szerokością ekranu 799,5 piksela? (Oczywiście nie na zwykłym wyświetlaczu, ale na siatkówkowym?)


Najbardziej ciekawi mnie tutaj odpowiedź, biorąc pod uwagę specyfikację.

Baumr
źródło
1
Twój obecny tytuł pytania nie pasuje do tego, o co pytasz. Wygląda na to, że pierwsza linijka treści twojego pytania pasowałaby lepiej jako tytuł :)
BoltClock
@BoltClock, dzięki jak zawsze - zamieniłem je; ale jak zinterpretowałeś „oddzielanie zapytań o media”?
Baumr
1
@Baumr: Dobre pytanie - właściwie nie do końca rozumiem, co przez to rozumiesz. Resztę pytania rozumiem i piszę odpowiedź.
BoltClock
1
Zakładałbym, że gdybyś miał szerokość dokładnie 20em, to najpierw zastosowałby max-width: 20emdefinicje, a następnie zastosowałby również min-width: 20emdefinicje.
użytkownik
1
@Baumr, uważam, że to po prostu kaskadowe to samo, co ogólne deklaracje CSS. Ponieważ szerokość 20em spełnia oba zapytania, zastosowane zostaną obie definicje zapytań.
użytkownik

Odpowiedzi:

109

Jakie są zasady nakładania się zapytań o media w CSS?

Kaskada.

@mediareguły są przezroczyste dla kaskady, więc jeśli dwie lub więcej @mediareguł jest zgodnych w tym samym czasie, przeglądarka powinna zastosować style we wszystkich pasujących regułach i odpowiednio rozwiązać kaskadę. 1

Co się stanie we wszystkich obsługiwanych przeglądarkach, dokładnie przy 20em i 45em?

Przy szerokości dokładnie 20em zarówno pierwsze, jak i drugie zapytanie o media będą zgodne. Przeglądarki będą stosować style w obu @mediaregułach i odpowiednio kaskadowo, więc jeśli są jakieś sprzeczne reguły, które należy zastąpić, wygrywa ta, która została ostatnio zadeklarowana (uwzględniając określone selektory !importantitp.). Podobnie w przypadku drugiego i trzeciego zapytania o media, gdy widoczny obszar ma dokładnie 45em szerokości.

Biorąc pod uwagę Twój przykładowy kod, z dodanymi pewnymi rzeczywistymi regułami stylu:

@media (max-width: 20em) {
    .sidebar { display: none; }
}

@media (min-width: 20em) and (max-width: 45em) {
    .sidebar { display: block; float: left; }
}

Gdy obszar roboczy przeglądarki ma dokładnie 20em szerokości, oba te zapytania o media zwrócą wartość true. Kaskadowo display: blocknadpisuje display: nonei float: leftbędzie obowiązywać na dowolnym elemencie z klasą .sidebar.

Możesz o tym myśleć jako o stosowaniu reguł, tak jakby zapytań o media nie było na początku:

.sidebar { display: none; }
.sidebar { display: block; float: left; }

Inny przykład tego, jak ma miejsce kaskada, gdy przeglądarka dopasowuje dwa lub więcej zapytań o media, można znaleźć w tej drugiej odpowiedzi .

Ostrzegamy jednak, że jeśli masz deklaracje, które nie pokrywają się w obu @mediaregułach, wszystkie te reguły będą miały zastosowanie. To, co się tutaj dzieje, to zjednoczenie deklaracji w obu @mediaprzepisach, a nie tylko ta ostatnia całkowicie unieważniająca pierwszą ... co prowadzi nas do wcześniejszego pytania:

Jak dokładnie rozdzielić zapytania o media, aby uniknąć nakładania się?

Jeśli chcesz uniknąć nakładania się, wystarczy napisać zapytania o media, które wzajemnie się wykluczają.

Pamiętaj, że przedrostki min-i max-oznaczają „minimum włącznie” i „maksimum włącznie”; oznacza to (min-width: 20em)i (max-width: 20em)będą pasować do widocznego obszaru o szerokości dokładnie 20em.

Wygląda na to, że masz już przykład, który prowadzi nas do Twojego ostatniego pytania:

Widziałem, jak ludzie używają: rzeczy takie jak 799px, a następnie 800px, ale co z szerokością ekranu 799,5 piksela? (Oczywiście nie na zwykłym wyświetlaczu, ale na siatkówkowym?)

Tego nie jestem do końca pewien; wszystkie wartości pikseli w CSS są pikselami logicznymi i ciężko mi było znaleźć przeglądarkę, która zgłosiłaby ułamkową wartość piksela dla szerokości obszaru roboczego. Próbowałem eksperymentować z niektórymi ramkami iframe, ale nie byłem w stanie niczego wymyślić.

Z moich doświadczeń wydaje Safari na iOS zaokrągla wszystkie ułamkowe wartości pikseli, aby zapewnić, że albo jeden max-width: 799pxi min-width: 800pxbędzie pasował, nawet jeśli rzutnia jest naprawdę 799.5px (który najwyraźniej mecze były).


1 Chociaż nic z tego nie jest wyraźnie określone ani w module Reguł warunkowych, ani w module Kaskada (z których ten ostatni jest obecnie przeznaczony do przepisania), zakłada się, że kaskada przebiega normalnie, ponieważ specyfikacja mówi po prostu, aby stosować style w dowolnym i wszystkie @mediareguły, które pasują do przeglądarki lub mediów.

BoltClock
źródło
2
@Baumr: Nie ma problemu, chociaż jeszcze nie skończyłem - przegapiłem twoje pytanie dotyczące nakładających się zapytań o media. Zaktualizowałem odpowiedź i nazywam to nocą. No i po prostu dla zabawy: zapytania o media to jeden z moich ulubionych tematów w CSS, ale nie mogę znieść terminu RWD;)
BoltClock
BoltClock, to chyba pierwszy raz, kiedy użyłem "RWD" - twoje chłodne przyjęcie zostało zauważone, haha! Dobranoc, ale kiedy wrócisz, sprawdź aktualizację pierwotnego pytania. A teraz spójrz na twoją aktualizację ...
Baumr
BoltClock, czy powinienem wyjąć tę aktualizację i zrobić z niej własne pytanie? Czuję, że robię to zagmatwane
Baumr
@Baumr: Tak, tak jest znacznie lepiej.
BoltClock
BoltClock: Wyciągnąłem go i umieściłem w, miejmy nadzieję, bardziej zwięzłym pytaniu: Jak uniknąć nakładania się zapytań medialnych? - jeśli masz jakieś sugestie dotyczące edycji, aby były bardziej odpowiednie dla innych osób, udostępnij. PS Nie pozwala mi @ you w komentarzach.
Baumr
6

Próbowałem zgodnie z zaleceniami tutaj:

@media screen and (max-width: calc(48em - 1px)) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

ale okazało się, że to nie był dobry pomysł, ponieważ nie działa teraz w Chrome ani na moim pulpicie Ubuntu, ani na moim telefonie z Androidem. (jak wyjaśniono tutaj: calc () nie działa w zapytaniach o media ) Ale znalazłem lepszy sposób ...

@media screen and (max-width: 47.9999em) {
    /*mobile styles*/
}
@media screen and (min-width: 48em) {
    /*desktop styles*/
}

i bam!

Pierre-Verthume Larivière
źródło
To powinna być akceptowana odpowiedź. BoltClock dostarczył pedantycznej odpowiedzi, ale ta odpowiedź jest najbardziej przydatna!
John Henckel,
2

calc()może być użyty do obejścia tego, (min-width: 50em and max-width: calc(50em - 1px)będzie poprawnie ułożony), ale słaba obsługa przeglądarki i nie polecam tego.

@media (min-width: 20em) and (max-width: calc(45em - 1px)) {
    /* slightly wider viewport */
}

Informacje:

Niektórzy inni wspomnieli, że nieużywanie emjednostki pomogłoby w zestawianiu zapytań.

Milche Patern
źródło
4
calc()nie jest częścią specyfikacji zapytania o media i nie będzie działać.
Jason T Featheringham