2014-02-14 1 views
6

http://jsfiddle.net/G46dK/Список с вложенным `переполнением-x: скрытым` списком счетчиков/точкой - почему/это ошибка?

<ol> 
    <li> 
     <p> 
      Moo 
    <li> 
     <p class="overflow-hidden"> 
      Moo 
    <li> 
     <p class="overflow-hidden"> 
      Moo 
    <li> 
     <p> 
      Moo 
</ol> 

с сопроводительными CSS:

p.overflow-hidden { 
    overflow-x: hidden; 
} 

Вы ожидали бы что-то вроде

  1. Moo
  2. Moo
  3. Moo
  4. Moo

но на моем Safari и Chrome ... "2." и "3." скрыты (но их «Moo» все еще есть):

Ordered list missing some counts

Почему переполнение влияет на список счетчик/точку на всех? Это на теге <p>, который находится внутри списка ... ах, это больно моему мозгу> <

Я теряю рассудок, или это ошибка?

Если это не ошибка ... это кто-нибудь, кто может это объяснить?

Я представлял себе "2." относится к li, тогда как overflow-x: hidden применяется к ребенку p. Таким образом, несмотря на то, что "2." находится за пределами p ... у него нет никаких отношений с overflow-x: hidden, и поэтому его следует оставить незатронутым - но это не так. В чем дело?

+1

+1 для обнаружения интересного явления. И поведение в IE10 еще более странное: оно добавляет вертикальный запас к классу p. Не знаю, почему это так. (Если вы не видите IE, вот скриншот: http://i.stack.imgur.com/EtBaA.png) –

+0

overflow-y имеет тот же эффект, что и мои тесты. Я предполагаю, что это ошибка браузера, да. –

+0

Большое спасибо за это, я столкнулся с той же ошибкой в ​​webapp. И это даже не новая проблема, которая существует уже много лет. Я открыл https://code.google.com/p/chromium/issues/detail?id=344941 – rbu

ответ

8

Ваше понимание верно; номер списка (известный в CSS как список , маркер) должен существовать вне p, а не внутри него. Это должно быть так, даже если вы укажете list-style-position: inside, потому что, как вы сказали, вы применяете переполнение к p, а не li.

В каждом элементе списка создается основной блок-блок для его дочерних элементов и еще один поле для размещения маркера. Детальные элементы должны быть отображены в основном блоке блока. От CSS2.1 spec:

В CSS 2.1 предлагается базовое визуальное форматирование списков. Элемент с «display: list-item» генерирует principal block box для содержимого элемента и, в зависимости от значений типа «стиль списка» и «стиль списка-стиля», возможно, также поле маркера в качестве визуальной индикации, что элемент - элемент списка.

Немного более подробное объяснение основных блоков блоков можно найти here.

В вашем случае каждый li создает блок главного блока и поле маркера. Элементы p.overflow-hidden должны находиться в основном блоке блока и не влиять на маркер. Вот сырой ASCII арт-схема, чтобы показать, что я имею в виду:

 
list 
marker li principal block box 
+-----+ +----------------------------+ 
|  | |+--------------------------+| 
| • | || Moo  (p block box) || 
|  | |+--------------------------+| 
+-----+ +----------------------------+ 

Теперь, спецификация кажется расплывчатой ​​о позиционировании самих маркеров коробков, но он сказал, что коробка маркера отделена от блока коробки главной когда это list-style-position - outside. Похоже, что подразумевается также, что браузер мог бы уйти с размещением маркерной коробки в главной блок-блоке, если содержание маркера фактически находится отдельно в этом поле маркера (которое, кстати, не может быть нацелено на CSS пока).

Но Safari и Chrome, похоже, делают что-то совсем другое: они, кажется, помещают маркерную коробку не только в основной блок, но и в первом дочернем блоке основного блока. Вот почему он отключается, когда он расположен за пределами блока блока p: поскольку движок рендеринга видит его как часть содержимого p, он видит, что он выходит из своих горизонтальных границ и отключает его. (я подозреваю, что отсекается с overflow-y: hidden, а потому, что он позиционируется за левый край, которая обычно не бывает в режиме LTR, но это просто дикое предположение.)

При добавлении list-style-position: inside в li, другие браузеров правильно сдвиньте блок p под маркером, but Safari and Chrome simply move the marker into the p box. Хотя CSS2.1 говорит, что он не определяет точное положение маркеров списка относительно основного блока поля элемента списка, это сказать о list-style-position: inside:

внутри
Коробка маркера помещается как первый встроенный блок в блок главного блока, перед содержимым элемента и перед любым: перед псевдоэлементами.

Это явно не то, что Safari и Chrome делают с маркерной коробкой.

Опять же, спецификация (довольно преднамеренно) не является на 100% понятной, но я бы не ожидал, что маркер списка будет дочерним элементом или будет затронут любым из дочерних элементов li способом он появляется в Safari и Chrome. Я уверен, что это неправильное поведение, то есть ошибка.

+0

Или может быть, мне просто больно, когда браузеры используют лазейки и неопределенное поведение в спецификации и отклоняются от нормы только потому, что могут. – BoltClock

+0

На яркой стороне есть новый модуль (http://dev.w3.org/csswg/css-lists) для списков CSS в разработке, в котором вводится выделенный псевдоэлемент для маркеров и определяется большая часть поведения который был перенесен CSS2.1. – BoltClock

+0

Mm это довольно расстраивает ... звучит как старая вещь Microsoft. –

2

Я нашел решение, но, к сожалению, я не могу объяснить, почему Chrome ведет себя таким образом ... Похоже, что это связано с поведением display: block.

Я изменил его на display: inline-block; и адаптировал vertical-align, чтобы сохранить отображаемый когерентный (но он не нужен).

p.overflow-hidden { 
    overflow-x: hidden; 
    vertical-align: -20px; 
    display: inline-block; 
} 

посмотреть на обновленном fiddle.

Смежные вопросы