Я не прочитал все комментарии, но оставлю ссылку, может не было: https://www.youtube.com/watch?v=gMqZR3pqMjg — про культурные различия в названиях цветов, разное количество основных цветов и особый статус красного цвета во всех культурах.
Когда в школе занимался живописью, мы использовали названия красок как эталонные цвета. Например, разные оттенки желтого: «ганза желтая», «кадмий лимонный», «кадмий желтый средний», «охра желтая». Получалось довольно точно, но это проф. деформация. Обычный человек вряд ли может представить какого цвета «умбра жженая».
Я пишу в основном на Less и методику сформулировал изначально для Less. Реализация на Sass — это калька с Less методики. Да, Sass сопротивляется и то, как всё это выглядит на Sass, мне не нравится.
Я согласен, что в Sass проще избежать проблем, с которыми я встретился в Less. Достаточно обнулять переменные в начале каждого компонента. В Less так не получится. Правило №1 по прежнему в силе и для Less, и для Sass: объявлять переменные в том же файле, в котором они используются.
Насчет компонентов, которые вызываются параметрическим миксином, удобно ли это, когда параметров много? Например, у bettertext.css 11 параметров для настройки и еще 40 переменных вычисляются из них. В Less благодаря слиянию миксинов я могу переопределять не только основные параметры, но и формулы вычислений. Как сделать такое в Sass не представляю.
Я за то, чтобы усложнить компонент внутри, но сделать его проще в (пере)использовании.
& { //код } действительно проще для изоляции, чем вариант с detached ruleset, который использовал я, чтобы создать локальную область видимости на несколько селекторов:
Я стремился изолировать каждый компонент на уровне less-исходника. Изоляция даёт возможность хранить каждый такой компонент как npm-пакет и подключать их на разных проектах. В вашем примере миксин вызывается внутри компонента, но объявлен в другом файле. Без конфига компонент не может скомпилироваться.
По этой же причине @import (reference) "config"; из самого компонента выглядит крайне нежелательно. Компонент не должен ничего «спрашивать» про окружение и проект, в котором его используют. Вдруг конфиг называется по другому или его вообще не существует.
Зависит от ситуации. Профит есть и для маленьких компонентов, в тех случаях, когда в коде повторяются некоторые значения, когда из одних значений вычисляются другие, когда вы планируете использовать этот компонент в другом проекте и там его надо будет перенастроить, когда вы хотите сделать скины/темы оформления компонента.
//global config
$glob-text-color: white;
$glob-bg-color: darkblue;
$bg-color: $glob-bg-color;
$text-color: $glob-text-color;
//eof global config
//component.scss
body {
$bg-color: white !default;
$text-color: black !default;
$padding: 40px !default;
padding: $padding;
background-color: $bg-color;
color: $text-color;
}
//eof component.scss
Мы объявляем локальные переменные внутри компонентов с флагом !default. Пока мы не пытаемся их переопределить извне, всё хорошо — переменные локальные, соседним компонентам не мешают.
Чтобы переопределить их в конфиге, мы должны вызвать эти переменные в глобальной области видимости, т.к. попасть в существующую локальную область видимости из другого файла не получится.
Локальные переменные становятся глобальными и у нас сразу же возникает необходимость разделять их при помощи префиксов. Разделение по неймспейсу — это имитация инкапсуляции. Такое разделение требует значительных усилий по поддержанию порядка.
В Бутстрапе на Less так и сделано, есть переменные общего назначения без префикса, а также у каждого компонента есть свои глобальные переменные с префиксом. Но переменные всех компонентов хранятся в одном внешнем файле и общие не отличаются от компонентных по формату написания имени.
Мы запутались и не справились с поддержанием порядка в именовании. Сначала использовали общие переменные в своих компонентах, потом по невнимательности стали использовать переменные из соседних компонентов.
Значения общих переменных было менять слишком опасно — они использовались во многих местах. Каждый раз надо было лезть в файл с переменными, искать среди сотен переменных нужную, а потом проверять, а не используется ли эта переменная ещё в каких-нибудь компонентах. И если используется, то создавать новую переменную. Вменяемые имена переменных быстро закончились. Проблемы росли как снежный ком.
Далее, в вашем примере:
// ../global-config.scss
$global-padding: 10px;
// end of ../global-config.scss
// ../component-1.scss
$padding: $global-padding;
.Component-1 {
padding: $padding;
}
// end of ../component-1.scss
// ../component-2.scss
$padding: 20px;
.Component-2 {
padding: $padding;
}
// end of ../component-2.scss
$padding — объявлена в глобальной области видимости и без префикса. Значит в компоненте №3, №4 и так далее паддинг будет равен 20px. Это уже ошибка.
В примере «компонент Kotsu» переменная $wrapper-padding не локальная, она объявлена в глобальной области видимости. Кроме этого, для её определения использована переменная из другого файла. Т.е. ваш компонент не сможет скомпилироваться самостоятельно без внешнего файла, в котором объявлена переменная ekzo-space().
Я стараюсь этого избежать, мне нужно, чтобы компоненты были по-настоящему независимыми.
С мэпами новый объект полностью переопределяет дефлотный объект. Если в дефолтном конфиге три переменные, а мы переопределяем только две, то одна переменная теряется. Т.е. чтобы такой вариант переопределения работал, нужно переобъявлять все переменные. Мне такой вариант не нравится: если мы добавили в компонент новую переменную, нужно сходить в конфиг и повторно объявить её там — слишком легко ошибиться.
С переменными как параметрами миксина тоже не то. Чтобы миксин отренедерил в CSS свой код, его обязательно нужно вызвать, с параметрами или без.
В моей системе компонент достаточно заинклюдить, тогда он отрендерит CSS с дефолтными параметрами. Если нужно его настроить, перепределить нужные переменные в конфиге. В сам компонент изменения вносить не нужно.
Каждый такой компонент независимый и может скомпилироваться самостоятельно. Дополнительное преимущество — локальным переменным не нужны строгие, уникальные имена. В разных компонентах могут быть локальные переменные с одинаковыми именами.
К сожалению, так и не смог заставить себя пользоваться стилями для текстов и объектов, т.к. их нельзя упорядочить в меню. Как только стилей становится больше 10, в них просто невозможно ориентироваться. Если бы разработчики дали возможность упорядочивать стили по группам (как это сделано для символов), возможно, это было бы удобно.
Вынесите кнопку «Styled Text» в тулбар — там стили текста группируются так же как символы. Ещё я добавил туда кнопку «Symbols» и «Fonts», а все лишнее убрал. Мне стало намного удобнее.
Поддерживаю. Важно улучшать поведение не ломая доступности. Эта опция должна быть включена по-умолчанию, но с возможностью выключить изменение url, если вдруг понадобится.
А как вы планируете бороться с размытостью векторных иконок из-за «нецелых пикселей»?
Суть проблемы: даже если контуры иконки идеально попадают в пиксели, в верстке случаются моменты, когда вычисленные размеры всех блоков до иконки не являются «целопиксельными». Например, при использовании размеров в «em» или безразмерного line-height, высота блока может получиться 100,5px. И тогда иконка не будет выровнена по пикселям. То же самое по ширине.
Такое происходит в IE и Firefox, в Chrome инлайн SVG всегда попадает в пиксели.
Размытие иконки в IE
Если вставлять SVG-иконку через background-image, она всегда попадает в пиксели, но ее уже нельзя перекрашивать или анимировать.
В этом способе более сложная разметка, и многоточие не прилипает к последнему видимому слову, но пользователь, по крайней мере, будет знать, что текст не уместился.
Да, под виндой. На винде я проверил Open Sans, Segoe UI и Source Sans Pro. В Хроме только два начертания видно. В остальных браузерах — все. На маке ещё не было возможности проверить.
Вообще, этот баг заслуживает отдельного исследования. В багтрекере вебкита я его не нашел. Может, с некоторыми шрифтами работает. А с учётом того, что спецификация «не гарантирует» правильность сопоставления браузером начертания шрифта и его font-weight, то может это и не баг вовсе.
Я не прочитал все комментарии, но оставлю ссылку, может не было: https://www.youtube.com/watch?v=gMqZR3pqMjg — про культурные различия в названиях цветов, разное количество основных цветов и особый статус красного цвета во всех культурах.
Когда в школе занимался живописью, мы использовали названия красок как эталонные цвета. Например, разные оттенки желтого: «ганза желтая», «кадмий лимонный», «кадмий желтый средний», «охра желтая». Получалось довольно точно, но это проф. деформация. Обычный человек вряд ли может представить какого цвета «умбра жженая».
Если в page2.less сократить скоупы, то вы придете к тому же решению, что использую я.
Только у меня конфиг вызывается последней строкой, чтобы он переопределял нужные миксины. В документации Less так и рекомендуют делать http://lesscss.org/features/#variables-feature-default-variables
Я пишу в основном на Less и методику сформулировал изначально для Less. Реализация на Sass — это калька с Less методики. Да, Sass сопротивляется и то, как всё это выглядит на Sass, мне не нравится.
Я согласен, что в Sass проще избежать проблем, с которыми я встретился в Less. Достаточно обнулять переменные в начале каждого компонента. В Less так не получится. Правило №1 по прежнему в силе и для Less, и для Sass: объявлять переменные в том же файле, в котором они используются.
Насчет компонентов, которые вызываются параметрическим миксином, удобно ли это, когда параметров много? Например, у bettertext.css 11 параметров для настройки и еще 40 переменных вычисляются из них. В Less благодаря слиянию миксинов я могу переопределять не только основные параметры, но и формулы вычислений. Как сделать такое в Sass не представляю.
Я за то, чтобы усложнить компонент внутри, но сделать его проще в (пере)использовании.
Спасибо за пример!
& { //код }
действительно проще для изоляции, чем вариант с detached ruleset, который использовал я, чтобы создать локальную область видимости на несколько селекторов:Я стремился изолировать каждый компонент на уровне less-исходника. Изоляция даёт возможность хранить каждый такой компонент как npm-пакет и подключать их на разных проектах. В вашем примере миксин вызывается внутри компонента, но объявлен в другом файле. Без конфига компонент не может скомпилироваться.
По этой же причине
@import (reference) "config";
из самого компонента выглядит крайне нежелательно. Компонент не должен ничего «спрашивать» про окружение и проект, в котором его используют. Вдруг конфиг называется по другому или его вообще не существует.Зависит от ситуации. Профит есть и для маленьких компонентов, в тех случаях, когда в коде повторяются некоторые значения, когда из одних значений вычисляются другие, когда вы планируете использовать этот компонент в другом проекте и там его надо будет перенастроить, когда вы хотите сделать скины/темы оформления компонента.
Мне тоже не нравится медленный boilerplate-код в Sass, но !default не работает так, как мне надо. Смотрите, почему.
Демка https://codepen.io/paulradzkov/pen/WOYygN
Мы объявляем локальные переменные внутри компонентов с флагом !default. Пока мы не пытаемся их переопределить извне, всё хорошо — переменные локальные, соседним компонентам не мешают.
Чтобы переопределить их в конфиге, мы должны вызвать эти переменные в глобальной области видимости, т.к. попасть в существующую локальную область видимости из другого файла не получится.
Локальные переменные становятся глобальными и у нас сразу же возникает необходимость разделять их при помощи префиксов. Разделение по неймспейсу — это имитация инкапсуляции. Такое разделение требует значительных усилий по поддержанию порядка.
В Бутстрапе на Less так и сделано, есть переменные общего назначения без префикса, а также у каждого компонента есть свои глобальные переменные с префиксом. Но переменные всех компонентов хранятся в одном внешнем файле и общие не отличаются от компонентных по формату написания имени.
Мы запутались и не справились с поддержанием порядка в именовании. Сначала использовали общие переменные в своих компонентах, потом по невнимательности стали использовать переменные из соседних компонентов.
Значения общих переменных было менять слишком опасно — они использовались во многих местах. Каждый раз надо было лезть в файл с переменными, искать среди сотен переменных нужную, а потом проверять, а не используется ли эта переменная ещё в каких-нибудь компонентах. И если используется, то создавать новую переменную. Вменяемые имена переменных быстро закончились. Проблемы росли как снежный ком.
Далее, в вашем примере:
$padding
— объявлена в глобальной области видимости и без префикса. Значит в компоненте №3, №4 и так далее паддинг будет равен 20px. Это уже ошибка.В примере «компонент Kotsu» переменная
$wrapper-padding
не локальная, она объявлена в глобальной области видимости. Кроме этого, для её определения использована переменная из другого файла. Т.е. ваш компонент не сможет скомпилироваться самостоятельно без внешнего файла, в котором объявлена переменная ekzo-space().Я стараюсь этого избежать, мне нужно, чтобы компоненты были по-настоящему независимыми.
Я пробовал вариант с !default maps. Демка https://codepen.io/paulradzkov/pen/xrQzGE
С мэпами новый объект полностью переопределяет дефлотный объект. Если в дефолтном конфиге три переменные, а мы переопределяем только две, то одна переменная теряется. Т.е. чтобы такой вариант переопределения работал, нужно переобъявлять все переменные. Мне такой вариант не нравится: если мы добавили в компонент новую переменную, нужно сходить в конфиг и повторно объявить её там — слишком легко ошибиться.
С переменными как параметрами миксина тоже не то. Чтобы миксин отренедерил в CSS свой код, его обязательно нужно вызвать, с параметрами или без.
В моей системе компонент достаточно заинклюдить, тогда он отрендерит CSS с дефолтными параметрами. Если нужно его настроить, перепределить нужные переменные в конфиге. В сам компонент изменения вносить не нужно.
Каждый такой компонент независимый и может скомпилироваться самостоятельно. Дополнительное преимущество — локальным переменным не нужны строгие, уникальные имена. В разных компонентах могут быть локальные переменные с одинаковыми именами.
Мне в личку уже напомнили, что копипаста это нарушение правил Хабра.
Прошу прощения :)
Вынесите кнопку «Styled Text» в тулбар — там стили текста группируются так же как символы. Ещё я добавил туда кнопку «Symbols» и «Fonts», а все лишнее убрал. Мне стало намного удобнее.
Поддерживаю. Важно улучшать поведение не ломая доступности. Эта опция должна быть включена по-умолчанию, но с возможностью выключить изменение url, если вдруг понадобится.
Суть проблемы: даже если контуры иконки идеально попадают в пиксели, в верстке случаются моменты, когда вычисленные размеры всех блоков до иконки не являются «целопиксельными». Например, при использовании размеров в «em» или безразмерного line-height, высота блока может получиться 100,5px. И тогда иконка не будет выровнена по пикселям. То же самое по ширине.
Такое происходит в IE и Firefox, в Chrome инлайн SVG всегда попадает в пиксели.
Если вставлять SVG-иконку через background-image, она всегда попадает в пиксели, но ее уже нельзя перекрашивать или анимировать.
В этом способе более сложная разметка, и многоточие не прилипает к последнему видимому слову, но пользователь, по крайней мере, будет знать, что текст не уместился.
Вообще, этот баг заслуживает отдельного исследования. В багтрекере вебкита я его не нашел. Может, с некоторыми шрифтами работает. А с учётом того, что спецификация «не гарантирует» правильность сопоставления браузером начертания шрифта и его font-weight, то может это и не баг вовсе.
img
осталисьwidth
иheight
. Уже исправил. Любуйтесь пропорциональным ОпенСансом.