Доброго времени суток, коллеги!
Давно задавался вопросом, как оптимизировать и сделать более удобным код используя
создает достаточно крупные файлы. Конечно, можно написать миксин вроде respond-to(tablet), его многие используют и выглядит он приятней и удобней чем выше описанный вариант, но основную проблему он не решает. В крупных проектах получим уйму
И как же все таки получить читаемый, ну или как минимум файл в два или даже в три раза меньше? Такой вопрос я задавал себе, и пришел к ответу:
«Сделать возможным прописывать все разрешения в одну строку, т.е. не дублировать значения.»
В итоге должно получиться что-то вроде
где первое значение [1em] — для всех экранов, а второе [0.8em] для экранов меньше 1024px. Согласитесь, такой вариант значительно упрощает жизнь и уменьшает файл в разы, легко описывает правило для всех разрешений.
На первый вопрос ответ найден. А вот другой вопрос, как этого добиться? Первая мысль была написать модуль для Gulp, который бы переносил значения из [] в
Поэтому я решил что
Тепер вызвать миксин можно таким образом:
CSS:
Вроде бы как получили нужный результат, но так только кажется, без дополнительных модулей для Gulp не обошлось. Когда я описал несколько правил
в итоге получил не лучший CSS:
От дублирования
Результат:
Так намного лучше, но все равно не хорошо, так как каждое значение описывается повторно с новым элементом body. В решении этой проблемы мне помог модуль gulp-minify-css, описание здесь.
И вуаля:
Получаем идеальный css используя минимум строк в Sass. Я использую Gulp+Sass, но для любителей Less+Webpack или Sass+Compass, или в любой другой связке, думаю не будет проблем переписать миксин и найти нужные модули.
Сам я сразу протестировал свой вариант на не столь крупном проекте, но все же править пришлось достаточно много, в результате я остался доволен процессом. Единственное что, не очень удобно, при использовании большого количества разрешений появляется такого рода код:
В таком случае по началу немного теряешься и не всегда понятно для какого экрана правишь, но это не было проблемой или неудобством для меня (открыл, проверил, поменял). В случае если у вас 2-3 разрешения, выглядеть все будет читабельно и лаконично, хоть и не привычно по началу.
Данным миксином я добился желаемого результата, все варианты экранов в одну строку. Конечно код сыроват, и возмножно что-то подобное уже написанно кем-то куда лучше чем это сделал я, но я не нашел, может плохо искал. В любом случае буду рад услышать ваше мнение по данному методу. Может кто-то знает что-то по-лучше, или знает как приукрасить данный метод, пишите. Возможно я написал полную ересь, и вы никогда не будете исользовать данный метод потому что… В таком случае прошу обосновать почему, для меня важно понять насколько может быть полезен/бесполезен данный метод.
P.S.
Для тех кто решил опробовать, хочу уточнить что если вы используете сокращенные свойства типа
Всем спасибо за внимание, и заранее за комментарии!
Давно задавался вопросом, как оптимизировать и сделать более удобным код используя
@media screen. Ибо кодbody{font-size: 1em;} @media screen and (max-width: 1024px){ body{font-size: 0.8em;} }
создает достаточно крупные файлы. Конечно, можно написать миксин вроде respond-to(tablet), его многие используют и выглядит он приятней и удобней чем выше описанный вариант, но основную проблему он не решает. В крупных проектах получим уйму
@include и разобраться не то чтобы сложно, но приходится много карулесить по файлу, в поисках нужного класса или вложения. И как же все таки получить читаемый, ну или как минимум файл в два или даже в три раза меньше? Такой вопрос я задавал себе, и пришел к ответу:
«Сделать возможным прописывать все разрешения в одну строку, т.е. не дублировать значения.»
В итоге должно получиться что-то вроде
body{font-size: [1em, 0.8em]}
где первое значение [1em] — для всех экранов, а второе [0.8em] для экранов меньше 1024px. Согласитесь, такой вариант значительно упрощает жизнь и уменьшает файл в разы, легко описывает правило для всех разрешений.
На первый вопрос ответ найден. А вот другой вопрос, как этого добиться? Первая мысль была написать модуль для Gulp, который бы переносил значения из [] в
@media screen… Но такой вариант не очень хорош, так как во-первых, это достаточно сложный процесс. Нужно многое продумать, уметь делать не конфликтующие модули, в общем, в моем случае это проблематично. Во-вторых, такой синтаксис не воспримет ни один idea, и подобные выходки будут подчеркиваться красным, что тоже не есть хорошо.Поэтому я решил что
@mixin в Sass вариант подходящий, хоть и не такой изящный и читабельный как использование []. И так, вот что у меня получилось:/*Прописываем массив нужных размеров*/ $screens: (all, 1024, 640); @mixin media($property, $values){ /*разбиваем введенные значения в цикле*/ @for $i from 1 through length($values) { /*Проверяем, если значение прописано как '' тогда пропускаем его*/ @if nth($values, $i) != ''{ @if nth($screens, $i) == 'all'{ /*Если это первое значение, тогда значение пропишется без @media screen */ #{$property}: unquote(#{nth($values, $i)}); } @else { /*иначе помещаем свойство в @media screen с соответствующим индексом*/ @media screen and (max-width: nth($screens, $i) + 'px') { #{$property}: unquote(#{nth($values, $i)}); } } } } }
Тепер вызвать миксин можно таким образом:
body{ @include media(font-size, (1em, 0.8em)); }
CSS:
body{font-size: 1em;} @media screen only (max-width: 1024px){ body{font-size: 0.8em;} }
Вроде бы как получили нужный результат, но так только кажется, без дополнительных модулей для Gulp не обошлось. Когда я описал несколько правил
body{ @include media(font-size, (1em, 0.8em, 0.6em)); @include media(color, (black, green, red)); } .class{ @include media(display, (none, block, none)); }
в итоге получил не лучший CSS:
body{font-size: 1em;} @media screen only (max-width: 1024px){ body{font-size: 0.8em;} } @media screen only (max-width: 640px){ body{font-size: 0.6em;} } body{color: black;} @media screen only (max-width: 1024px){ body{color: green;} } @media screen only (max-width: 640px){ body{color: red;} } .class{display:none;} @media screen only (max-width: 1024px){ .class{display:block;} } @media screen only (max-width: 640px){ .class{display:none;} }
От дублирования
@media screen only (max-width: 1024px) нужно как-то избавляться. Для этого я установил модуль для Gulp — gulp-group-css-media-queries, описание по установке здесьРезультат:
body{font-size: 1em;} body{color: black;} .class{display: none;} @media screen only (max-width: 640px){ body{font-size: 0.6em;} body{color: red;} .class{display: none;} } @media screen only (max-width: 1024px){ body{font-size: 0.8em;} body{color: green;} .class{display: block;} }
Так намного лучше, но все равно не хорошо, так как каждое значение описывается повторно с новым элементом body. В решении этой проблемы мне помог модуль gulp-minify-css, описание здесь.
И вуаля:
body{ font-size: 1em; color: black; } .class{display: none;} @media screen only (max-width: 640px){ body{ font-size: 0.6em; color: red; } .class{display: none;} } @media screen only (max-width: 1024px){ body{ font-size: 0.8em; color: green; } .class{display: block;} }
Получаем идеальный css используя минимум строк в Sass. Я использую Gulp+Sass, но для любителей Less+Webpack или Sass+Compass, или в любой другой связке, думаю не будет проблем переписать миксин и найти нужные модули.
Сам я сразу протестировал свой вариант на не столь крупном проекте, но все же править пришлось достаточно много, в результате я остался доволен процессом. Единственное что, не очень удобно, при использовании большого количества разрешений появляется такого рода код:
.class{ @include media(color, (red, '', '', '', green, black)); @include media(width, (50%, '', '', '', '', 100%)); }
В таком случае по началу немного теряешься и не всегда понятно для какого экрана правишь, но это не было проблемой или неудобством для меня (открыл, проверил, поменял). В случае если у вас 2-3 разрешения, выглядеть все будет читабельно и лаконично, хоть и не привычно по началу.
Вывод
Данным миксином я добился желаемого результата, все варианты экранов в одну строку. Конечно код сыроват, и возмножно что-то подобное уже написанно кем-то куда лучше чем это сделал я, но я не нашел, может плохо искал. В любом случае буду рад услышать ваше мнение по данному методу. Может кто-то знает что-то по-лучше, или знает как приукрасить данный метод, пишите. Возможно я написал полную ересь, и вы никогда не будете исользовать данный метод потому что… В таком случае прошу обосновать почему, для меня важно понять насколько может быть полезен/бесполезен данный метод.
P.S.
Для тех кто решил опробовать, хочу уточнить что если вы используете сокращенные свойства типа
маrgin: 0 auto;, тогда «0 auto» обязательно нужно взять в кавычки, иначе получите margin: 0;Всем спасибо за внимание, и заранее за комментарии!
