LESS.JS Redudancy в CSS, использование миксинов вместо селекторного наследования?

Я использую less.js с некоторым регулярным использованием mixins. Например. У меня есть базовый класс "gradientBlack", как это.

.gradientBlack {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5a5a5a), color-stop(60%, #333333), color-stop(100%, #000000));
    background: -webkit-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -o-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -ms-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5a5a5a', endColorstr='#000000', GradientType=0 );
    background: linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
} 

Затем я повторно использую этот класс при нескольких определениях, таких как

h3 {
    .gradientBlack;
    ...
}
.darkBox {
    .gradientBlack;
    ...
}

Недостатком такого подхода является то, что он раздувает CSS с избыточными определениями. Например. вычисленный CSS может выглядеть примерно так.

h3 {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5a5a5a), color-stop(60%, #333333), color-stop(100%, #000000));
    //... and maybe some more (redundant) definitions

}

.darkBox {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5a5a5a), color-stop(60%, #333333), color-stop(100%, #000000));
    //... and maybe some more (redundant) definitions
}

Для кого-то вроде меня, который использует много градиентов, roundCorners и т.д., это быстро складывается.

Вопрос (отредактированный)

Я узнал, что известное имя для этого раздела наследование селектора (см. Sass) и как похоже, сейчас это не реализовано. Использование и преимущества обсуждаются здесь здесь. Вычисленный css этого синтаксиса может выглядеть следующим образом.

h3,
.darkBox,
.gradientBlack {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    ...
}

Тем не менее, я был бы признателен за любые предложения, когда нужно беспокоиться и когда это не делать, - а также любые другие рекомендации по теме, как действовать, если наследование выбора не является вариантом.

Ответ 1

Я думаю, что есть несколько вопросов, которые следует учитывать:

  • Размер таблицы стилей
  • Эффективность исполнения таблицы стилей (как быстро выполняется браузер)
  • Поддержание работоспособности таблицы стилей
  • Поддержание работоспособности разметки (html)

Подход, который защищает Марк Геммилл (в/3), действительно Николь Салливан Объектно-ориентированный CSS. Я использовал этот шаблон перед тем, как переключиться на Sass, и по-прежнему считаю его полезным, но я думаю, что способ Sass/Less приводит к более удобному CSS и более удобной разметке - нет необходимости посыпать презентационные классы во всей разметке.

Я думаю, что @extend (наследование селектора) является одним из основных преимуществ, с которыми Sass имеет более Меньше и уменьшает избыточность в скомпилированной таблице стилей.

Для меня преимущества более удобного CSS и разметки перевешивают все недостатки немного большей таблицы стилей. Я думаю, вы обнаружите, что если вы сохраните селектора эффективными (не гнездайте в Less/Sass больше, чем вам нужно), и объедините и свести к минимуму производительность, производительность будет меньше, чем вы могли себе представить.

Ответ 2

Вы можете определить свой mixin, а затем передать переменные, которые вы хотите переопределить, когда вы его вызываете.

Это пример формы менее веб-сайта:

.box-shadow (@x: 0, @y: 0, @blur: 1px, @alpha) {
  @val: @x @y @blur rgba(0, 0, 0, @alpha);

  box-shadow:         @val;
  -webkit-box-shadow: @val;
  -moz-box-shadow:    @val;
}

Итак, когда вы это называете, вы можете сделать что-то вроде

div.header {
  .box-shadow(5px,5px,2px,.5);
}

Таким образом, вы можете иметь 1 mixin, но каждый раз, когда вы его вызываете, вы можете передавать ему разные атрибуты.

Надеюсь, что это поможет.

Ответ 3

Недавно я начал использовать меньше css, и этот точный вопрос тоже приходил на ум. Мой ответ:

1/Фактический сгенерированный css - это не что иное, как точка, поскольку вы вряд ли будете смотреть на нее (за исключением, возможно, для отладки вашего меньшего кода), поэтому, если в выводе есть избыточность, с тем, что я считаю синтаксисом, который намного лучше понять и поддерживать.

2/Недостаток, как вы описали, заключается в том, что если вы пройдете в менее css класс стиля вокруг mixin, вы раздуваются размером вашего вывода css. Если вы используете less css в интерфейсе, и он генерирует css в браузере, это не вызывает беспокойства. Однако, если вы предварительно генерируете свой css, тогда возникает вопрос о том, как эти эффекты разбухают при загрузке. Если ваш css файл не станет огромным, и/или ваш сайт делает очень большой объем, я бы не стал беспокоиться об этом.

3/Альтернатива передаче стиля класса в виде mixin (или с использованием наследования селектора) в меньше css - это просто используйте class inheritance в своем html, поэтому вместо этого в вашем меньшем файле:

.gradientBlack {
    ...
}

h3 {
    .gradientBlack;
    ...
}
.darkBox {
    .gradientBlack;
    ...
}
td.dark {
    .gradientBlack;
    ...
}

Вы просто определяете .gradientBlack в своей таблице стилей, а затем ссылаетесь на класс непосредственно в html:

<h3 class="gradientBlack"></h3>
<div class="darkBox gradientBlack></div>
<td class="dark gradientBlack"></td>

Я думаю, что в конце концов, помимо вопроса времени загрузки, нижняя строка - это то, что делает ваш код более понятным и поддерживаемым в вашей конкретной ситуации. У меня более 100 строк в моем сгенерированном css, если это облегчит понимание less css.

Ответ 4

Как насчет этого?

h3, .darkBox, td.dark {
    .gradientBlack;
}
h3, {
    /*other styles here*/
}
.darkBox {
    /*other styles here*/
}
td.dark {
    /*other styles here*/
}

В качестве альтернативы вы можете использовать CSS minifier и посмотреть, дает ли он приемлемый размер без ущерба для чистоты вашего файла LESS.

Ответ 5

Я использую lessphp (который может отличаться от less.js в этом примере), но я заметил, что если я объявлю mixin, как будто он имеет пустой список параметров, он никогда не будет генерировать блок стиля.

Итак, измените это:

.gradientBlack {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5a5a5a), color-stop(60%, #333333), color-stop(100%, #000000));
    background: -webkit-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -o-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -ms-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5a5a5a', endColorstr='#000000', GradientType=0 );
    background: linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
}

Для этого:

.gradientBlack() {
    background: #333333;
    background: -moz-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5a5a5a), color-stop(60%, #333333), color-stop(100%, #000000));
    background: -webkit-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -o-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    background: -ms-linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5a5a5a', endColorstr='#000000', GradientType=0 );
    background: linear-gradient(top, #5a5a5a 0%, #333333 60%, #000000 100%);
}

и используйте его следующим образом:

h3 {
    .gradientBlack();
    ...
}
.darkBox {
    .gradientBlack();
    ...
}

и он не будет генерировать неиспользуемый блок.