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

Взгляните на этот jsfiddle: http://jsfiddle.net/ZNddz/

.intro:first-letter {
    font-size: 130px;
}
span.letter {
    background-color: red;
    font-size: 30px;
}
p {
    font-size: 80px;
}

Первое правило состоит из одного селектора классов и одного pseudo-element selector = 11

Второе правило состоит из одного селектора классов .letter и одного селектора тэгов span= 11

Оба правила имеют одинаковую специфичность, поэтому разумно полагать, что победителем должен быть последний стиль. Очевидно, это не так. Поэтому я решил добавить свойство background-color ко второму правилу и, как вы видите, имеет высоту 30 пикселей.

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

Ответ 1

Я выхожу из этого, что оба правила не выбирают один и тот же элемент.

Это связано с тем, что .intro соответствует элементу p, тогда как span.letter является потомком .intro. Как уже упоминалось, специфика не имеет значения, когда селектора соответствуют различным элементам. Но так как каждый селектор соответствует некоторому элементу, применяются оба правила, в результате чего ваш красный фон действует, на span.letter.

Но это слишком странно, что я хочу получить официальное объяснение этому.

spec содержит некоторые примеры, которые очень похожи на то, что у вас есть: элемент уровня блока, который начинается с элемента inline-level который содержит текст и стили, применяемые к элементу уровня блока, псевдоэлемент :first-letter на элементе уровня блока и его дочерний элемент встроенного уровня. Во всех примерах псевдоэлемент :first-letter всегда является самым внутренним потомком в терминах структуры форматирования; это означает, что он вложен в дочерний элемент inline-уровня.

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

Следующий CSS будет создавать начальную буквенную надписью с каплями для двух строк:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
 <HEAD>
  <TITLE>Drop cap initial letter</TITLE>
  <STYLE type="text/css">
   P              { font-size: 12pt; line-height: 1.2 }
   P::first-letter { font-size: 200%; font-style: italic;
                    font-weight: bold; float: left }
   SPAN           { text-transform: uppercase }
  </STYLE>
 </HEAD>
 <BODY>
  <P><SPAN>The first</SPAN> few words of an article
    in The Economist.</P>
 </BODY>
</HTML>

Этот пример может быть отформатирован следующим образом:

Вымышленная последовательность тегов:

<P>
<SPAN>
<P::first-letter>
T
</P::first-letter>he first
</SPAN> 
few words of an article in the Economist.
</P>

Обратите внимание, что теги псевдоэлементов ::first-letter упираются в содержимое (т.е. начальный символ), в то время как начальный тег псевдо-элемента:: первая строка вводится сразу после начального тега элемента блока.

В вашем случае объявления font-size применяются как обычно, но поскольку .intro:first-letter вложен в span.letter, он использует свое собственное значение font-size. Если вы использовали относительное значение оно было бы рассчитано на основе span.letter, и если бы вы не включили стиль font-size вообще он просто наследует его от span.letter.

Обратите внимание, что псевдо-элемент :first-letter не применяется к элементам линейного уровня (это относится только к встроенным блокам):

В CSS псевдоэлемент ::first-letter применяется к блочным контейнерам, таким как блок, элемент списка, элемент table-cell, table-caption и inline-block.

Встроенный блок (тот, который сгенерирован с помощью display: inline) не является блоком контейнера блоков. (Пример окна встроенного уровня, который является блочным контейнером, является встроенным блоком.)

Если браузер применяет псевдоэлемент к строке, то он нарушает спецификацию. Хотя нет никаких указаний на то, что должно произойти, когда у вас есть правило :first-letter для контейнера блоков и потокового потомка в виде строки, поскольку он говорит, что он не применяется к строкам, в идеале браузер должен всегда игнорировать правило, ориентированное на встроенный бокс потомок. По-видимому, Chrome думает иначе; см. ответ Danield.

Ответ 2

Я выхожу из этого, что оба правила не выбирают один и тот же элемент.

Правильно. Вы не должны это делать. Просто откройте элемент проверки.

Учитывая следующую разметку:

<p class="intro first"><span class="letter">L</span>sometext</p>

Следующий код устанавливает псевдо-элемент :first-letter в теге <p>:

.intro:first-letter {
    font-size: 130px;
}

Следующий код устанавливает font-size в элементе span

span.letter {
    background-color: red;
    font-size: 30px;
}

Код в span не переопределяет код на <p> - потому что они нацеливаются на различные свойства.

Если бы я установил псевдо-элемент first-letter в span - тогда он переопределит код на <p>

Здесь jsFiddle как доказательство

Итак, вы видите, что здесь нет проблем с конкретностью.