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ę.
max-width: 20em
definicje, a następnie zastosowałby równieżmin-width: 20em
definicje.Odpowiedzi:
Kaskada.
@media
reguły są przezroczyste dla kaskady, więc jeśli dwie lub więcej@media
reguł jest zgodnych w tym samym czasie, przeglądarka powinna zastosować style we wszystkich pasujących regułach i odpowiednio rozwiązać kaskadę. 1Przy 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
@media
reguł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!important
itp.). 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: block
nadpisujedisplay: none
ifloat: left
bę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
@media
regułach, wszystkie te reguły będą miały zastosowanie. To, co się tutaj dzieje, to zjednoczenie deklaracji w obu@media
przepisach, a nie tylko ta ostatnia całkowicie unieważniająca pierwszą ... co prowadzi nas do wcześniejszego pytania:Jeśli chcesz uniknąć nakładania się, wystarczy napisać zapytania o media, które wzajemnie się wykluczają.
Pamiętaj, że przedrostki
min-
imax-
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:
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: 799px
imin-width: 800px
bę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
@media
reguły, które pasują do przeglądarki lub mediów.źródło
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!
źródło
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
em
jednostki pomogłoby w zestawianiu zapytań.źródło
calc()
nie jest częścią specyfikacji zapytania o media i nie będzie działać.