- PVSM.RU - https://www.pvsm.ru -
Приветствую!
Примерно месяц назад я написал статью, в которой выдвинул идею об оптимизации @media screen
. Идея заключается в том, чтобы иметь возможность писать значения для всех экранов в одну строку. Более подробно можете почитать по ссылке [1]. Большинство комментариев — это критика относительно реализации, к сожалению идей никто не подкинул. Но если посмотреть с другой стороны, из каждой критики можно вытащить идею, поэтому опираясь на мнение читателей, я поставил себе цель написать миксин, который:
@media
);
Давайте посмотрим, что у меня вышло (репозиторий Github [2])!
Синтаксис
.class{
@include media($properties, $orientation);
}
Миксин media поддерживает два параметра $properties и $orientation.
$properties — массив css правил.
$orientation — ориентация экрана (необязательный).
.class{
@include media((
width: 100%;
height: (lg: 800px, md: 600px, sm: 300px),
transform: (all: translateX(100px) translateY(100px), sm: translateX(50px) translateY(50px)),
color: (sm-md: $white, md-lg: $gray),
font-size: (320: 12px, min-480: 18px, 480-md: 24px, print: 14pt)
));
}
Давайте разберем код подробней…
Параметр $properties является массивом, поэтому все свойства берутся в ().
width: 100%;
Обычное правило для всех экранов. компилируется в
.class{
width: 100%;
}
Интересное дальше:
height: (lg: 800px, md: 600px, sm: 300px)
Здесь мы описываем высоту для экранов с максимальной шириной lg, md и sm (задаются разработчиком, об этом позже).
Результат компиляции:
@media only screen and (max-width: 1024px) {
.class{
height: 800px;
}
}
@media only screen and (max-width: 768px) {
.class{
height: 600px;
}
}
@media only screen and (max-width: 640px) {
.class{
height: 300px;
}
}
Так же обратите внимание на код ниже:
transform: (all: translateX(100px) translateY(100px), sm: translateX(50px) translateY(50px))
В данном примере присутствует экран all, я думаю вы догадались, что это все экраны. Есть принципиальная разница между all и обычным правилом, как width: 100%. Но об этом так же немного позже.
color: (sm-md: $white, md-lg: $gray)
Здесь я постарался максимально гибко соединить диапазоны экранов между min-width
и max-width
. Т.е. код, представленный выше скомпилирует минимальную ширину sm (640) — максимальную ширину md (768), и для экранов в этом диапазоне задаст белый цвет текста, или серый для md (768) — lg (1024).
Скомпилированный вариант:
.class{
@media only screen and (min-width: 768px) and (max-width: 1024px) {
color: gray;
}
}
.class{
@media only screen and (min-width: 640px) and (max-width: 768px) {
color: white;
}
}
Так же бывают случаи, когда мы не можем опираться только на заданные экраны. Поэтому есть возможность задавать кастомную ширину динамически. Так же если вам внезапно понадобится указать вместо максимальной ширины минимальную, или наоборот, такая возможность так же присутствует:
font-size: (880: 12px, min-480: 18px, 480-md: 24px, print: 14pt)
Первый экран max-width: 880px. По умолчанию ширина проставляется именно максимальная (так же легко поменять). Для этого экрана получим font-size: 12px;
Второй экран min-480 указывает на то, что будем отталкиваться от минимальной ширины экрана 480px (приставка min-), и в итоге получим font-size: 18px
для всех экранов шире 480px.
480-md — создаст кастомный минимальный размер 480px и максимальный md (768). Т.е. это вариант диапазона экранов, как в предыдущем примере, только с произвольным значением.
Обратите внимание, что если написать 480-768 мы получим экран -288px, т.е. знак "-" отработает как минус. Поэтому такой пример стоит взять в кавычки «480-768», если конечно вы намерено не писали операцию с "-" (кстати +, *, / так же будет работать).
print: 14pt
print — является неизменным параметром и предназначен для печати:
@media print {
.class{
font-size: 14pt;
}
}
Надеюсь на данном этапе все понятно… Если нет, с радостью разъясню в комментариях.
Тут все намного проще. Есть два варианта ориентации экрана landscape и portrait. Собственно, в случае необходимости, вторым параметром прописываем именно эти значения.
.class{
@include media((
width: 100%;
height: (all: 100%, md: 50%)
), portrait);
}
В итоге мы получим:
.class{
width: 100%;
}
@media only screen and (orientation:portrait){
.class{
height: 100%;
}
}
@media only screen and (max-width: 768px) and (orientation:portrait){
.class{
height: 50%;
}
}
На этом примере можно четко увидеть разницу между all и стандартным правилом. В случае width: 100% правило при любых обстоятельствах подпадает под все экраны. В случае all — все экраны с ориентацией portrait/landscape.
Две стандартные переменные, которые нужно отредактировать — это $breakpoints и $media-direction. Вот как они выглядят по умолчанию:
$breakpoints: (
lg: 1024,
md: 768,
sm: 640
) !default; //- размеры экранов
$media-direction: max !default; - направление по умолчанию (max/min)
Т.е. для того чтобы создать себе нужное количество экранов с нужными названиями, размерами и первоначальным направлением (min/max) необходимо создать новые переменные в удобном для вас месте:
$breakpoints: (
desktop: 1280,
ipad: 1024,
tablet: 768,
mobile: 640
);
$media-direction: min;
Этого достаточно чтобы начать работу.
Как еще можно использовать данный миксин?
Если параметр $properties поместить в переменную, тогда можно получить отличную функцию. Например:
$title-style: (
line-height: (lg: 24px, md: 20px, sm: 16px),
font-size: (lg: 20px, md: 16px, sm: 12px;),
text-align: (all: left, sm: center)
...
)
.block{
h2{
color: gray;
@include media($title-style);
}
h3{
color: black;
@include media($title-style, landscape);
}
}
Получаем своего рода extend класс. Согласитесь, это может быть очень удобно.
@media screen
для всех экранов, диапазоны экранов, минимальную/максимальную ширину динамически, в любой момент есть возможность прописать кастомную ширину, а так же не отходя от кода настраивать правила для печати.@include mixin
для разных экранов. На данный момент такую возможность реализовать в приведенном выше миксине посредством Sass в принципе невозможно. Насколько это критично, я оставлю вам на размышление, решайте сами, стоит ли жертвовать подобной функцией или нет. Лично для меня это вообще не критично, так как я не могу припомнить, чтобы я вообще когда-нибудь прописывал @include mixin
внутри @media screen
.Думаю, цель достигнута. Миксин получился достаточно удобным и лаконичным.
Если вы со мной не согласны, пишите комментарии. В любом случае с удовольствием выслушаю ваш совет по улучшению данного миксина, или попробую извлечь что-то полезное из вашей критики.
P.S. Скачать миксин вы можете в репозитории Github по ссылке [2]. _mixin.scss — тот файл, который вам нужен. Так же файл package.json содержит в себе плагины для Gulp, которые было бы неплохо подключить:
@media screen
;Уверен, что для webpack или для любого другого сборщика, вы без труда найдете аналоги.
Спасибо за внимание!
Автор: Долгалев Евгений
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/html/276899
Ссылки в тексте:
[1] по ссылке: https://habrahabr.ru/post/350466/
[2] репозиторий Github: https://github.com/Dolgik89/-media-screen
[3] Источник: https://habrahabr.ru/post/352686/?utm_source=habrahabr&utm_medium=rss&utm_campaign=352686
Нажмите здесь для печати.