2015-04-24 3 views
4

Может ли кто-нибудь объяснить это поведение в FF?Элемент блока внутри встроенного блока действует странно в Firefox

Fiddle: http://jsfiddle.net/4mrt8wq3/

<style> 
    .b { display: inline-block; } 
    #a { display: block; } 
</style> 

<div class="b"> 
    <label>xxxxxxxxxx</label> 
    <input type="text" id="a"/> 
</div> 
<div class="b"> 
    <label>xxxxxxxxxx</label> 
    <div>/</div> 
</div> 

Только в светлячок, первый DIV позиционируется одна строка ниже, чем второй. Он корректно работает в Chrome и IE (по крайней мере, IE11). По какой-то причине блок-блок внутри встроенного блока обертывается под вторым элементом.

Использование переполнения: скрытый в первом div исправляет проблему, но второй div затем слегка помещается с примерно 4 или 5 пикселями поля над ним. Размещение переполнения, скрытое на обоих, приводит к правильной визуализации.

Я не ищу для решения проблемы, как я уже нашел один, но я в недоумении объяснить поведение ... Может кто-нибудь объяснить, почему это делает это?

ответ

5

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

Во втором div с классом «b» внутренний div сам содержит поле строки для хранения символа '/'. Затем он дает базовый уровень для второго div с классом «b».

Эта базовая линия должна выровнять уровень с базовым уровнем первого div с классом «b». Возникает вопрос: где базовая линия последней строки строки в этом div?

Сделав сам элемент ввода display:block, Firefox¹ считает, что элемент ввода «заменен», его содержимое непрозрачно для CSS, поэтому элемент ввода никогда не создается элементом ввода. Таким образом, последняя строка первого div с классом «b» - это та, которая содержит метку, и выравнивает уровень с линией символа «/».

Хром имеет другой вид. Chrome рассматривает входной элемент как внутреннюю структуру, видимую для CSS, поэтому внутренности элемента образуют поле строки, базовая линия которого становится базовой линией первого div с классом «b», и это тот, который выровнен по уровню с '/' персонаж.

Когда вы добавляете `overflow: hidden ', он влияет на базовую линию встроенных блоков таким образом, что их базовые линии перестают быть базовыми линиями последнего содержащегося в них строкового поля и становятся крайним краем элемента.


Какое поведение является правильным, неясно. Это зависит от истории и несколько фальсифицированного понятия замененных элементов. В первые дни браузеров рендеринг некоторых элементов был делегирован внешним системам, либо базовой операционной системе, либо подключаемому модулю. В частности, это верно для элемента ввода, где рендеринг выполнялся вызовами O/S. У O/S не было понятия CSS, поэтому правила должны были быть определены, чтобы позволить эффектно черным ящикам взаимодействовать с остальной частью страницы. Такие элементы были классифицированы как «замещенные» элементы.

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

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

Насколько далеко они продвигаются в этом отношении, недостаточно четко указано. Спецификация HTML5 не распознает элементы формы как замещенные элементы и предполагает, что они будут отображаться как встроенный блок, что сделало бы поведение Chrome правильным, но существует множество способов, которыми все браузеры, включая Chrome, просто не ведут себя таким образом , С точки зрения обратной совместимости со старым веб-контентом поведение Firefox более надежное.

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


¹ Для меня, IE11 ведет себя как Firefox. Opera 28 (blink engine, например Chrome) ведет себя как Chrome. Opera 12 (предварительный движок) ведет себя как Firefox.

+0

Это очень интересно. Вопрос в том, какой из них правильный? –

+0

Так что вы говорите, что встроенный блок обрабатывает все содержимое как одну строку с одной базой? –

+0

Подождите ... Часть, которую я тогда не понимаю, это. div с элементом/является элементом уровня блока, точно так же, как и вход. Так почему же один «непрозрачный», а другой нет? Не заменены ли элементы ввода? –

0

Ваша проблема в том, что переполнение переполнения спецификации: скрытое изменение базового положения встроенного блока. Firefox реализует то, что говорит спецификация. У Chrome нет.

Решение:

<style> 
    .b { display: inline-block; 
    vertical-align: top; /*add this line */ 
    } 
    #a { display: block; } 
</style> 
+0

_ "Я не ищу решение проблемы" _ – j08691

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