Про retina и @media: как решить вопрос кроссбраузерной вёрстки | OTUS

Курсы

Программирование
Microservice Architecture
-5%
React.js Developer
-4%
C++ Developer. Professional
-5%
Scala-разработчик
-8%
Backend-разработчик на PHP
-9%
Алгоритмы и структуры данных
-9%
Python Developer. Basic
-12%
Golang Developer. Professional
-5%
HTML/CSS
-11%
C# ASP.NET Core разработчик
-5%
Kotlin Backend Developer
-8%
iOS Developer. Professional
-8%
Java Developer. Professional Web-разработчик на Python MS SQL Server Developer Android Developer. Basic Разработчик программных роботов (RPA) на базе UiPath и PIX Highload Architect Reverse-Engineering. Professional Vue.js разработчик Node.js Developer Интенсив «Оптимизация в Java» Супер-практикум по использованию и настройке GIT Symfony Framework Java Developer. Basic Unity Game Developer. Professional Супер-интенсив Azure
Инфраструктура
Microservice Architecture
-5%
Экспресс-курс «IaC Ansible»
-10%
Administrator Linux.Basic
-10%
Мониторинг и логирование: Zabbix, Prometheus, ELK
-10%
Экспресс-курс «CI/CD или Непрерывная поставка с Docker и Kubernetes»
-30%
Administrator Linux. Professional
-6%
Экcпресс-курс «ELK»
-10%
Экспресс-курс по управлению миграциями (DBVC)
-10%
Базы данных Network engineer Разработчик программных роботов (RPA) на базе UiPath и PIX Highload Architect Разработчик голосовых ассистентов и чат-ботов VOIP инженер Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Супер-интенсив "Tarantool"
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Про retina и @media

JS_Deep_6.07_Site.png

Retina — это зарегистрированный компанией Apple товарный знак. Под эти знаком выпускаются дисплеи (включая дисплеи мобильных устройств) с очень высоким разрешением экрана и маленьким размером пикселей. Сейчас это название «приклеилось» просто ко всем таким дисплеям.

Подобное высокое разрешение создало ряд проблем, включая веб-разработку: 100 физических пикселей на обычном экране и на Retina будут иметь абсолютно разный размер. Чтобы сайты не превратились в крошечные квадратики, а расцвели красками на Retina, было принято простое решение: теперь пиксели делятся на логические и физические.

Логические пиксели, это как раз те пиксели, которые фигурируют в разметке, и они не обязаны совпадать с физическими, которые их будут отображать. На классических Retina-дисплеях каждому логическому пикселю соответствует квадрат 2x2 физических пикселей.

Таким образом, данный блок:

.some-block {
  width: 100px;
  height: 100px;
}

на обычных дисплеях будет иметь размер 100x100 физических пикселей, а на экранах Retina — 200x200 пикселей.

А вот теперь начинаются проблемы

Особенно, если это не просто блок, а картинка, и причём растровая:

.some-image {
  background: url(http://via.placeholder.com/100x100) 100px 100px;
  width: 100px;
  height: 100px;
}

Данная картинка будет иметь размер 100x100 физических пикселей на обычных дисплеях, и целых 200x200 физических пикселей при разрешении всего 100x100. Такие изображения будут «размытыми». Предположим, что мы поставили разрешение 200x200:

.some-image {
  background: url(http://via.placeholder.com/200x200) 100px 100px;
  width: 100px;
  height: 100px;
}

Да, теперь на Retina-экранах картинка выглядит превосходно, но при открытии на обычных устройствах мы будем загружать ненужные данные. И что же делать?

Выход есть — @media-запросы!

.some-image {
  background: url(http://via.placeholder.com/100x100) 100px 100px;
  width: 100px;
  height: 100px;
}

@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .some-image {
    background: url(http://via.placeholder.com/200x200) 100px 100px;
  }
}

Оставим читателям вопрос, почему здесь фигурируют dpi. Но это запрос работает для Retina-устройств. И данный сайт прекрасно будет смотреться и достаточно быстро загружаться.

Что ещё?

Существуют также устройства с промежуточным количеством пикселей на один логический. Более того, этому помогают опции масштабирования как в самом браузере, так и операционной системе. Поэтому правильный работающий @media-query выглядит немного иначе:

@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {

или даже так

@media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {

Заключение

Собственно, всех этих штук вполне достаточно для красивого отображения сайта на подобных устройствах. Ну и с использованием CSS-препроцессоров этот @media-query можно вынести в константу и код выглядит уже не таким страшным.

Например, с less всё будет выглядеть таким образом:

@retina: ~"only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi)";

.some-image {
  background: url(http://via.placeholder.com/100x100) 100px 100px;
  width: 100px;
  height: 100px;

  @media @retina {
    background: url(http://via.placeholder.com/200x200) 100px 100px;
  }
}

Есть вопрос? Напишите в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
1 комментарий
1

Использую в scss такой миксин:

@mixin retina($density: 2) {
  @media only screen and (-webkit-min-device-pixel-ratio: $density),
  only screen and (min--moz-device-pixel-ratio: $density),
  only screen and (-o-min-device-pixel-ratio: #{$density}/1),
  only screen and (min-device-pixel-ratio: $density),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: $density dppx) {
    @content;
  }
}
body {
    background-image: url(./img/bg.jpg);
    @include retina {
        background-image: url(./img/bg@2x.jpg);
    }
}
Для комментирования необходимо авторизоваться