Почему div и кнопка с одинаковыми стилями визуализируются на разных размерах?

У меня есть страница с несколькими интерактивными элементами <div>, и я хочу изменить их на <button>, чтобы упростить их идентификацию через jQuery. Но когда я изменяю <div> на <button> s, их размер изменяется. (Я строю их как фиксированную ширину и высоту, но кнопка отображается с другой шириной и высотой, чем div.)

Здесь jsfiddle, который воспроизводит проблему: http://jsfiddle.net/AjmGY/

Вот мой CSS:

.styled {
    border: 4px solid black;
    background: blue;
    width: 100px;
    height: 100px;
}

И мой HTML:

<div class="styled"></div>
<button class="styled"></button>

Я ожидаю увидеть две коробки одинакового размера, но нижний ящик (<button>) заметно меньше. Такое поведение совместимо во всех браузерах, на которых я его пробовал: Windows (Chrome, FireFox, IE, Opera) и Android (встроенный браузер и Dolphin).

Я попробовал добавить стиль display: block; к стилю, считая, что это может сделать их рендерингом с использованием тех же правил (т.е. сделать рендеринг button как a div, так как теперь он является блочным элементом), но это никакого эффекта - кнопка осталась меньше.

По мере увеличения ширины границы разница возрастает. Похоже, что кнопка border находится внутри width, а не выше и выше ее width, как и с <div>. Насколько я понимаю, это нарушает коробку , хотя W3C действительно говорит:

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

Является ли нормальным/документированным/ожидаемым поведением для button иметь свою границу внутри своей ширины и высоты, а не снаружи? Могу ли я полагаться на это поведение?

(Моя страница использует HTML-тип документа, если это относится.)

Ответ 1

Кнопки и другие элементы управления ввода отображаются по умолчанию с помощью border-box model; т.е. содержимое, заполнение и граница суммируются до суммарного width, который вы объявляете. Они также часто имеют некоторое дополнение, добавленное браузерами произвольно в соответствии со стандартными таблицами стилей. Как вы цитируете, это приемлемое поведение, а не нарушение стандартов; он просто предназначен для рендеринга элементов управления GUI на уровне ОС.

Чтобы ваш button был того же размера, что и ваш div, размер его в соответствии с моделью содержимого (которая является "исходной моделью модели W3C) и нулевым ее дополнением:

button.styled {
    -moz-box-sizing: content-box;
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
    padding: 0;
}

jsFiddle demo