Почему браузеры соответствуют селекторам CSS справа налево?

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

  1. почему это?
  2. это просто потому, что спецификация говорит?
  3. влияет ли это на конечный макет, если он был оценен слева направо?

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

вот несколько ссылок на плечах претензии

  1. http://code.google.com/speed/page-speed/docs/rendering.html
  2. https://developer.mozilla.org/en/Writing_Efficient_CSS

похоже, что это сделано таким образом, чтобы избежать необходимости смотреть на всех детей родителя (которых может быть много), а не все родители ребенка, который должен быть одним. Даже если DOM глубок, он будет смотреть только на один узел на уровне, а не на несколько соответствие RTL. легче / быстрее оценить селекторы CSS LTR или RTL?

3 ответов


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

Если у вас был только один селектор и только один элемент для сравнения с этим селектором, то слева направо в некоторых случаях имеет смысл. Но это решительно не ситуацию браузера. Браузер пытается оказать Gmail или любой и имеет один <span> Он пытается стиль и правила 10,000 + Gmail помещает в свою таблицу стилей (я не придумываю это число).

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

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

С другой стороны, если вы начинаете с сопоставления самой левой части селектора... с чем вы его сравниваете? Вы должны начать ходить по DOM, ища узлы, которые могут соответствовать ему. Просто открытие, что нет ничего, что соответствовало бы этой самой левой части, может занять некоторое время.

таким образом, браузеры совпадают справа; это дает очевидную отправную точку и позволяет очень быстро избавиться от большинства селекторов кандидатов. Вы можете увидеть некоторые данные на http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (хотя нотация сбивает с толку), но в результате для Gmail, в частности, два года назад, для 70% пар (правило, элемент) вы могли бы решить, что правило не соответствует, просто изучив части тега/класса/id самого правого селектора для Правила. Соответствующее число для набора тестов производительности Pageload Mozilla составило 72%. Так что это действительно стоит пытаясь избавиться от этих 2/3 всех правил так быстро, как вы можете, а затем беспокоиться только о соответствии оставшейся 1/3.

обратите внимание также, что есть другие оптимизации, которые браузеры уже делают, чтобы избежать даже попыток соответствия правилам, которые определенно не будут совпадать. Например, если самый правый селектор имеет идентификатор и этот идентификатор не соответствует идентификатору элемента, то в Gecko вообще не будет попытки сопоставить этот селектор с этим элементом: набор "селекторов с идентификаторами", которые попытка происходит из поиска hashtable в ID элемента. Таким образом, это 70% правил, которые имеют довольно хороший шанс соответствовать этому еще не совпадают после рассмотрения только тега / класса / id самого правого селектора.


разбор справа налево, также называемый анализ снизу вверх на самом деле эффективным для браузера.

рассмотрим следующее:

#menu ul li a { color: #00f; }

браузер сначала проверяет a, потом li, потом ul, а потом #menu.

Это потому, что браузер просматривает страницу, ее просто нужно посмотреть на текущий элемент/узел и все предыдущие узлы / элементы, которые он сканировал.

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

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

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


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

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