Переменные в CSS

7 Февраль 2008

Давайте помечтаем вместе с Йенсом Майертом (Jens Meiert) о реализации механизма переменных в CSS: CSS: Selector Variables. Суть предложенного решения проста: мы просто задаём псевдоним группе селекторов: @E = F и дальше используем его в коде, избегая лишних повторений.

Типичный код до использования переменных:

  1. .messages-list .highlighted,
  2. .messages-list .highlighted LI {
  3. overflow:hidden;
  4. }
  5. .messages-list .highlighted LI .email,
  6. .messages-list .highlighted LI .phone {
  7. cursor:pointer;
  8. }

Теперь объявляем переменные:

  1. @list = .messages-list .highlighted;
  2. @list-item = @list LI;

…и получаем:

  1. @list,
  2. @list-item {
  3. overflow:hidden;
  4. }
  5. @list-item .email,
  6. @list-item .phone {
  7. cursor:pointer;
  8. }

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

  1. .messages-list {
  2. .highlighted {
  3. LI {
  4. .email,
  5. .phone {
  6. cursor:pointer;
  7. }
  8. }
  9. }
  10. }

…правда становится не очень ясно, куда, при такой форме записи, вставлять правила для вышестоящих селекторов. Видимо, в отдельных конструкциях. Может и у вас есть свои предложения по оптимизации CSS, не противоречащие духу самого языка?

ps: а вот уже черновики возможной спецификации CSS Variables и Symbolic constants

Комментарии

  1. kizu 7 Февраль 2008 / 20:40

    Во втором варианте для вышестоящих селекторов можно было бы использовать что-то вроде
    .messages-list {
    {
    lalala:lalala;
    }
    .highlighted {

    }
    }

    Хотя все-равно первый вариант экономнее, легче для чтения и его можно использовать в разных местах.

  2. Octane 7 Февраль 2008 / 20:40

    на каком-то блоге видел такую мысль, что-то похожее на описание медиатайпов существующих сейчас:

    Создаем какой-то класс таким образом:

    @article { } допустим это будет блок нашей статьи и все элементы внутри него описываем следующим образом:

    @article {

    /* свойства самого блока */
    border: 1px solid #ccc;
    background: #f0f0f0;

    /* свойства вложенных в него тегов */
    p { margin: 0; padding: 10px; }
    a:link, a:active, a:visited { text-decoration: none; }
    abbr { border-bottom: none; }

    и т.д. и т.п.

    }

    в отличие от существующего сейчас способа:

    .article {
    border: 1px solid #ccc;
    background: #f0f0f0;
    }
    .article p { margin: 0; padding: 10px; }
    .article a:link, .article a:active, .article a:visited { text-decoration: none; }
    .article abbr { border-bottom: none; }
    }

    Помоему неплохая идея, очень удобно и значительно сокращает код.

  3. pepelsbey 7 Февраль 2008 / 21:28

    Octane, а как тогда обозначать селектор @article в HTML-коде?

    kizu, свойство lalala:lalala повисает в воздухе. Имхо, не слишком удачно

  4. kizu 7 Февраль 2008 / 21:33

    Ну да, или же вводить что-то вроде псевдоселектора :self, но это тоже не совсем то.
    С переменными удобнее, хотя использование @

  5. kizu 7 Февраль 2008 / 21:37

    (недописал, сглючило %))
    …хотя импользование @ странно, т.к. оно уже есть в @media и @import, тогда уж лучше $, который много где переменные означает.

  6. pepelsbey 7 Февраль 2008 / 21:37

    Меня использование собаки немного смущает: всё-таки есть @media, @import…

    upd. Хе, ну вот и я говорю :)

  7. Octane 7 Февраль 2008 / 22:14

    >> Octane, а как тогда обозначать селектор @article в HTML-коде?

    как класс например, ну или вообще обычным способом через точку писать, иде в том чтобы понимались конструкции такого типа:

    .article {
    border: 1px solid #ccc;

    p { ... }
    a:link, a:active, a:visited { ... }
    abbr { ... }
    }

  8. Octane 7 Февраль 2008 / 22:18

    >> Octane, а как тогда обозначать селектор @article в HTML-коде?

    как класс например, ну или вообще обычным способом через точку писать, идея в том, чтобы понимались конструкции такого типа:

    .article {
    border: 1px solid #ccc;

    p { ... }
    a:link, a:active, a:visited { ... }
    abbr { ... }
    }

    оффтоп: чот не отправляются комментарии в вордпресс через toonel :(

  9. pepelsbey 7 Февраль 2008 / 22:19

    А кто такой toonel?

  10. Octane 7 Февраль 2008 / 22:35

    Бесплатный прокси для сжатия траффика toonel.net. Хм у меня на вордпрессе работает норм, на этом блоге что-то мешает отправке сообщений.

  11. Octane 7 Февраль 2008 / 22:36

    Бесплатный прокси для сжатия траффика toonel.net. Хм у меня на вордпрессе работает норм, на этом блоге что-то мешает отправке сообщений. 3 раза проверил)

  12. MT 8 Февраль 2008 / 2:00

    Я склонен подходить к вопросу с другой стороны и в качестве решения проблемы избыточного CSS-кода предпочёл бы наследование единожды определённого набора правил в рамках существующего синтаксиса CSS:

    .example {rules: values; } /* селектор (не обязательно класс), от которого будем наследовать */
    .another-1 {inherit-from: selector(.example); индивидуальные правила для .another-1; }
    .another-2 {inherit-from: selector(.example, ещё какой-нибудь селектор, и ещё); индивидуальные правила для .another-2; }

    Внутри функции "selector" через запятую может быть указано несколько селекторов, от которых следует наследовать правила; приоритеты разных значений одинаковых свойств в простейшем случае можно определять в порядке перечисления.

  13. pepelsbey 8 Февраль 2008 / 5:16

    MT, фактически ты предлагаешь ООП: базовый класс и его расширение-уточнение. Согласен — это гибко.

  14. jahson 8 Февраль 2008 / 5:43

    У Йенса и МТ хорошие предложения. Предложить бы w3c и подстегнуть процесс внесения изменений в браузеры.

    Вложенность, особенно в виде, предложенном Octane — ужасна для глаз, а с опытом приходит понимание, что как бы то ни было, но программы пишутся прежде всего для людей.

    Ну и цитату в дополнение к сказанному:
    Programs must be written for people to read, and only incidentally for machines to execute. (Abelson & Sussman)

  15. jahson 8 Февраль 2008 / 6:53

    Уточнения:

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

    Программы = код.

  16. Grigoriev 8 Февраль 2008 / 11:32

    Что-то это все начинает немного напоминать JavaScript =-)
    А раз начинает почему бы не писать CSS-функции, которые буду автоматически вызываться по названию классов и айдишников в html-коде?
    @ - обозначение функции.
    $ - условный оператор if.

    @#commentDiv (a, p, strong) {
    a(:link,:visited,:hover,:active) {
    color:#00F;
    }
    p {
    font-size:1em;
    }
    strong {
    color:#0FF;
    }
    span {
    font-size:1.5em;
    }
    $a>span {
    font-size:1em;
    }
    }

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

  17. Octane 8 Февраль 2008 / 17:14

    :D Вас наверное всякие вложенные много раз циклические и условные конструкции на таких языках как JavaScript, PHP, Perl, C++ и д.р. вообще отпугивают?) Если применять форматирование кода (делать отступы напиимер :)) то все прекрасно читаемо) или использовать подсветку синтаксиса...

  18. czerny_angel 8 Февраль 2008 / 19:26

    Оффтопик
    Вадим, а ссылочки ранее/позднее чуть ниже формы не перепутаны местами случайно?

  19. jahson 9 Февраль 2008 / 8:54

    «Вложенные много раз циклические и условные конструкции» мне говорят о том, что есть проблемы. Особенно, если вложенность превышает глубину примерно в три уровня.

    Есть много способов решать проблемы большой вложенности, и самый первый - это чёткое понимание того, что необходимо сделать. Если такого понимания нет - надо сесть и подумать.

    Форматирование кода я использую с окончания школы. С первого курса у меня сложился определённый стиль написания кода. Но при этом я прошёл все этапы - писал ужасный код, похожий на описанный вами, неправильно понимал, что хочу сделать, не думал прежде чем писать код. Время прошло - выводы сделаны и приняты на вооружение. Поэтому я очень хорошо чувствую, где код эстетичен, а где - нет. И ещё лучше чувствую, что никакие подсветки и форматирование не спасут от проблем, если вы будете писать огромные портянки кода с ужасающей вложенностью. Проблемы при этом будут самые простые, например проблемы координации - ведь очень легко забыть, где ты находишься, если не видно начала. Да и поддерживать такое чудовище я и врагу не пожелаю.

  20. jahson 9 Февраль 2008 / 9:00

    Вадим, а почему в комментариях такой маленький отступ перед абзацем? Межстрочный интервал в тексте и в коментариях одинаковый (на глаз), а вот отступ перед абзацем как-то маловат, тяжело для глаза.

  21. pepelsbey 12 Февраль 2008 / 15:42

    czerny_angel, спасибо! Плагин для вывода этих вещей дописывался в 5 утра, так что меня можно понять )

  22. keep 13 Февраль 2008 / 10:07

    оу :) спать это так приятно.

  23. warmrobot 17 Февраль 2008 / 13:19

    Про константы в CSS-файлах впервые я прочёл на 24ways.org. Автор говорит, что есть пара решений на PHP. Одно придумал аж сам Шон Инман.

    Сам не использую. :-) Ничего не могу сказать.

  24. Сергей 22 Февраль 2008 / 13:52

    Вопрос про первый вариант.
    Как его правильно реализовать? Просто в цсс написать @list = .messages-list .highlighted; разве достаточно?

  25. pepelsbey 22 Февраль 2008 / 13:57

    Сергей, пока ни один браузер не поддерживает переменные в CSS, более того — даже нет внятной спецификации, только предположения.

  26. zergius 2 Апрель 2008 / 10:18

    Было бы здорово, чтобы в CSS появилось два типа переменных - в одних будут храниться селекторы, а в других - значения свойств.
    И если первый тип здесь уже хорошо обсудили, то второй должен выглядеть следующим образом:

    $color1 = #345678;
    $color2 = #abcdef;
    ...
    #selector1 {color:$color1; background-color:$color2; border:1px solid $color1}
    #selector2 {color:$color2; background-color:$color1; border:1px solid $color2}

    Мне кажется, что такой подход гибче, чем наследование каких-то параметров из других селекторов, поскольку значение переменной можно использовать в разных правилах (как показано в моем примере)

    А еще, как мне кажется, незаслуженно зарубили идею с expression. Все-таки было бы здорово иметь возможность выставить ширину блока 100%-200px.

  27. Octane 3 Апрель 2008 / 8:27

    >> иметь возможность выставить ширину блока 100%-200px.

    Если не ошибаюсь, такая возможность будет в спецификации CSS3 без всяких expression и выглядеть будет так:

    #conteiner {
    width: calc(100% - 200px);
    }

  28. zergius 22 Апрель 2008 / 11:59

    такая возможность будет в спецификации CSS3 без всяких expression

    Ну, собственно, это и есть expression, только порезанный и называется по-другому. :)
    Нормальные браузеры будут поддерживать такой синтаксис, а для ИЕ можно будет писать expression-ы.

    Но по-настоящему полезными вычисления будут если в них можно будет использовать вычисляемые размеры других блоков. Что-то вроде:

    #container {height:calc(100%-height(#footer));}

Разрешённые теги: <a href=""> <strong> <b> <em> <i> <cite> <del>

Внимание био-роботам: если вы пришли рекламировать какой-то сайт, то у вас нет шансов — все комментарии премодерируются специально обученной обезьянкой. Всего доброго.

*
*