W3C CSS грамматика, странности синтаксиса - PullRequest
10 голосов
/ 08 августа 2011

Я смотрел на синтаксис CSS здесь и здесь , и я был поражен, увидев, как производство токенов и грамматика были завалены объявлениями пробелов.Обычно пробел определяется один раз в лексере и пропускается, чтобы его больше никогда не было видно.Так же комментарии.

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

Реальные UA, которые анализируют CSS, действительно реализованы в соответствии с этой (этими) грамматиками?

РЕДАКТИРОВАТЬ: причина вопроса - фактически различные реализации LESS.less.js не понимает последовательные комментарии, а lessc.exe не понимает комментарии внутри селекторов.В этом отношении они даже не могут правильно проанализировать CSS, как это определено.Итак, я пошел посмотреть, что такое настоящая грамматика CSS и ...

1 Ответ

25 голосов
/ 18 августа 2011

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


Скажем, у нас есть следующая базовая разметка:

<html>
    <head>
        <style type="text/css">
            .blueborder { width:200px; height:200px; border: solid 2px #00f; }
            .redborder  { width:100px; height:100px; margin:50px; border: solid 2px #f00; }
        </style>
    </head>

    <body>
        <div class="blueborder">
            <div class="redborder"></div>
        </div>
    </body>

</html>

Здесь нет ничего особенного, кроме div внутри div, с некоторыми стилями, чтобы вы могли увидеть разницу между ними.

Теперь давайте добавим еще один класс и идентификатор для внешнегоdiv:

<div class="blueborder MyClass" id="MyDiv">
    <div class="redborder"></div>
</div>

Если я хочу задать фон для external div следующим образом:

.MyClass#MyDiv { background: #ccc; }

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

.MyClass #MyDiv { background: #ccc; }

... который НЕ стилизует внешний div.

Чтобы увидеть, как они анализируются по-разному, вы можете посмотреть, как селектируются токены:

Example1:

.MyClass#MyDiv -> DELIM IDENT HASH

Example2:

.MyClass #MyDiv -> DELIM IDENT S HASH

Если бы мыигнорируя пробелы (как это обычно делают компиляторы), мы пропустили бы эту разницу.


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

Однако они не решили сделать это, и потребность в пробелахартефакт этого решения.

...