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

<p>селекторы css подбираются движками браузера справа налево. поэтому они сначала находят детей, а затем проверяют своих родителей, чтобы убедиться, что они соответствуют остальным частям правила.</p><ol> <li>почему это?</li> <li>это только потому, что в спецификации сказано?</li> <li>влияет ли это на возможный макет, если он был оценен слева направо?</li> </ol><p>для меня самый простой способ сделать это - использовать селекторы с наименьшим количеством элементов. поэтому сначала идентификаторы (так как они должны возвращать только 1 элемент). тогда, возможно, классы или элемент, который имеет наименьшее количество узлов - например, на странице может быть только один промежуток, поэтому перейдите непосредственно к этому узлу с любым правилом, которое ссылается на промежуток.</p><p>вот несколько ссылок, подтверждающих мои претензии</p><ol> <li> <a href="http://code.google.com/speed/page-speed/docs/rendering.html">http://code.google.com/speed/page-speed/docs/rendering.html</a> </li> <li> <a href="https://developer.mozilla.org/en/writing\_efficient\_css">https://developer.mozilla.org/en/writing\_efficient\_css</a> </li> </ol><hr><p>похоже, что это сделано таким образом, чтобы не смотреть на всех детей родителя (которых может быть много), а не на всех родителей ребенка, который должен быть одним. даже если dom является глубоким, он будет рассматривать только один узел на уровень, а не несколько при сопоставлении rtl. <a href="https://stackoverflow.com/questions/4130045/is-it-easier-faster-to-parse-css-selectors-ltr-or-rtl">проще/быстрее оценивать css-селекторы ltr или rtl?</a> </p>

<p>помните, что когда браузер выполняет сопоставление селектора, у него есть один элемент (тот, для которого он пытается определить стиль) и все ваши правила и их селекторы, и ему необходимо найти, какие правила соответствуют элементу. это отличается от обычной вещи jquery, скажем, когда у вас есть только один селектор, и вам нужно найти все элементы, которые соответствуют этому селектору.</p><p>если у вас был только один селектор и только один элемент для сравнения с этим селектором, то слева направо в некоторых случаях имеет больше смысла. но это определенно <em> не </em> ситуация браузера. браузер пытается отобразить gmail или что-то еще, и у него есть тот <code><span></code>, который он пытается стилизовать, и более 10000 правил, которые gmail вставляет в свою таблицу стилей (я не придумываю это число).</p><p>в частности, в ситуации, когда браузер просматривает большинство селекторов, которые он считает <em>, не совпадают </em> с соответствующим элементом. таким образом, проблема состоит в том, чтобы решить, что селектор не соответствует так быстро, как это возможно; если это требует дополнительной работы в соответствующих случаях, вы все равно выигрываете из-за всей работы, которую вы сохраняете в случаях, которые не совпадают.</p><p>если вы начнете с простого сопоставления самой правой части селектора с вашим элементом, скорее всего, он не будет совпадать, и все готово. если он совпадает, вам придется выполнять больше работы, но только пропорционально глубине вашего дерева, которая в большинстве случаев не так велика.</p><p>с другой стороны, если вы начнете с сопоставления самой левой части селектора ... с чем вы сравниваете его? вы должны начать ходить по dom, ища узлы, которые могут ему соответствовать. просто обнаружение, что ничто не соответствует этой самой левой части, может занять некоторое время.</p><p>так что браузеры совпадают справа; это дает очевидную отправную точку и позволяет очень быстро избавиться от большинства кандидатов на выбор. вы можете увидеть некоторые данные по адресу <a href="http://groups.google.com/group/mozilla.dev.tech.layout/browse\_thread/thread/b185e455a0b3562a/7db34de545c17665">http://groups.google.com/group/mozilla.dev.tech.layout/browse\_thread/thread/b185e455a0b3562a/7db34de545c17665</a> (хотя обозначение сбивает с толку), но в итоге для gmail, в частности два года назад, для 70% пар (правило, элемент) вы могли решить, что правило не соответствует, просто изучив части тега/класса/id самого правого селектора для правила. соответствующий показатель для набора тестов производительности загрузки страниц mozilla составил 72%. так что действительно стоит попытаться избавиться от этих 2/3 всех правил так быстро, как вы можете, а затем беспокоиться только о соответствии оставшейся 1/3.</p><p>также обратите внимание, что браузеры уже делают другие оптимизации, чтобы не пытаться даже соответствовать правилам, которые определенно не будут соответствовать. например, если у крайнего правого селектора есть идентификатор, и этот идентификатор не совпадает с идентификатором элемента, то в gecko вообще не будет попытки сопоставить этот селектор с этим элементом: набор "селекторов с идентификаторами", которые предпринимаются исходит из поиска по хеш-таблице идентификатора элемента. так что это 70% правил, которые имеют довольно хорошие шансы на то, что <em> все еще </em> не совпадают после рассмотрения только тега/класса/идентификатора самый правый селектор.</p>

<p>разбор справа налево, также называемый <strong>анализ снизу вверх</strong> на самом деле эффективен для браузера.</p><p>учтите следующее:</p><pre><code>#menu ul li a { color: #00f; } </code></pre><p>браузер сначала проверяет <strong><code>a</code></strong>, затем <strong><code>li</code></strong>, затем <strong><code>ul</code></strong>, а затем <strong><code>#menu</code></strong>.</p><p>это потому, что браузер сканирует страницу, ему просто нужно посмотреть текущий элемент/узел и все предыдущие узлы/элементы, которые он сканировал.</p><p>следует отметить, что <strong>браузер начинает обработку в тот момент, когда он получает полный тег/узел</strong> и ему не нужно ждать всю страницу, за исключением случаев, когда он находит скрипт, в этом случае он временно приостанавливается и завершает выполнение скрипта и затем идет вперед.</p><p>если это происходит наоборот, это будет неэффективно, потому что браузер обнаружил элемент, который он сканировал при первой проверке, но затем был вынужден продолжить просмотр документа для всех дополнительных селекторов. для этого браузер должен иметь весь html и, возможно, должен сканировать всю страницу, прежде чем он начнет рисовать css.</p><p>это противоречит тому, как большинство парсов разбирает дом. там дом построен, и ему не нужно сканировать всю страницу, просто найдите первый элемент и затем продолжайте сопоставлять другие внутри него.</p>

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