Подтвердить что ты не робот

Что делает текст в элементе <button> вертикально центрированным?

Кажется, что есть какая-то магия вокруг элемента <button>, который я не понимаю.

Рассмотрим эту разметку:

<button class="button">Some Text</button>
<div class="button">Some Text</div>

И этот CSS:

.button{
    background: darkgrey;
    height: 40px;
    border: 2px solid grey;
    width: 100%;
    box-sizing: border-box;
    font-size: 14px;
    font-family: helvetica;
    text-align: center;
    margin-bottom: 20px;

    /*I'm aware I could use this to center it*/
    /*line-height: 40px;*/
}

Что делает текст в элементе кнопки вертикально центрированным? Предполагается, что Webkit предопределяет значение -webkit-box-align со значением center для элемента <button>. Если я установил значение initial, текст больше не будет выровнен по центру. Но это не похоже на полную магию, поскольку, с другой стороны, мне не удавалось сосредоточить текст на div, используя свойство -webkit-box-align.

Вот скрипка: http://jsfiddle.net/cburgdorf/G5Dgz/

4b9b3361

Ответ 1

Я знаю, что это пара лет, но я добавлю свои мысли после некоторого исследования к проблеме при написании таблицы стилей сброса для проекта.

ПРИМЕЧАНИЕ ** Это основано на просмотре исходного кода Firefox, потому что его было проще всего получить и прочитать. Однако, на основе аналогичного поведения в других браузерах реализация, вероятно, похожа.

Во-первых, основная проблема заключается в том, что элементы <button> - по крайней мере, в Firefox - создаются с внутренним элементом между тегом <button> и его дочерними элементами. В Firefox он называется moz-button-content и не является чем-то, что может быть достигнуто с помощью CSS и было настроено для отображения блока без наследования высоты кнопки, вы можете увидеть это объявление стиля в таблице стилей useragent:

Из "source/layout/style/res/forms.css"

*|*::-moz-button-content {
    display: block;
    /* Please keep the Multicol/Flex/Grid/Align sections below in sync with
       ::-moz-scrolled-content in ua.css and ::-moz-fieldset-content above. */
    /* Multicol container */
    -moz-column-count: inherit;
    -moz-column-width: inherit;
    -moz-column-gap: inherit;
    -moz-column-rule: inherit;
    -moz-column-fill: inherit;
    /* Flex container */
    flex-direction: inherit;
    flex-wrap: inherit;
    /* -webkit-box container (aliased from -webkit versions to -moz versions) */
    -moz-box-orient: inherit;
    -moz-box-direction: inherit;
    -moz-box-pack: inherit;
    -moz-box-align: inherit;
    /* Grid container */
    grid-auto-columns: inherit;
    grid-auto-rows: inherit;
    grid-auto-flow: inherit;
    grid-column-gap: inherit;
    grid-row-gap: inherit;
    grid-template-areas: inherit;
    grid-template-columns: inherit;
    grid-template-rows: inherit;
    /* CSS Align */
    align-content: inherit;
    align-items: inherit;
    justify-content: inherit;
    justify-items: inherit;
}

Поскольку вы не можете повлиять ни на один из стилей этого элемента, вы вынуждены добавить свой стиль в теги <button>. Это приводит ко второй проблеме: браузер жестко запрограммирован для вертикального позиционирования содержимого кнопки.

Из "источника/макета/формы/nsHTMLButtonControlFrame.cpp"

// Center child in the block-direction in the button
// (technically, inside of the button focus-padding area)
nscoord extraSpace =
    buttonContentBox.BSize(wm) - contentsDesiredSize.BSize(wm);

childPos.B(wm) = std::max(0, extraSpace / 2);

// Adjust childPos.B() to be in terms of the button frame-rect:
childPos.B(wm) += clbp.BStart(wm);

nsSize containerSize = (buttonContentBox + clbp.Size(wm)).GetPhysicalSize(wm);

// Place the child
FinishReflowChild(aFirstKid, aPresContext, contentsDesiredSize,
                  &contentsReflowInput, wm, childPos, containerSize,
                  ReflowChildFlags::Default);

Учитывая эти две проблемы, вы можете начать видеть, как кнопка заставляет контент центрироваться, рассмотрим:

   <button> tag

+------------------------+ ^
| button extra space     | |
|                        | |
+------------------------+ |
|| ::moz-button-content || | button height
||   display: block;    || |
+------------------------+ |
|                        | |
| button extra space     | |
+------------------------+ v

Если вы зададите button высоту - как 48px от вашей скрипки, текст будет центрирован, потому что элемент moz-button-content является блоком отображения и будет иметь только высоту содержимого (скорее всего, строку -высота содержимого по умолчанию), и если поместить рядом с другим элементом, вы получите следующее поведение:

* {
  box-sizing: border-box;
  margin: 0;
  border: 0;
  padding: 0;
  font-family: san-serif;
  background: none;
  font-size: 1em;
  line-height:1;
  vertical-align: baseline;
 }

button, a {
  height: 3em;
}

button {
  background: red;
}

a {
  display:inline-block;
  background: green;
 }
<button>Button content</button>
<a>Link Content</a>

Ответ 2

Вы можете использовать дополнение.

Например

padding: 20px 10px;

Ответ 3

Я думаю, что единственной причиной такого поведения является то, что Google Chrome или браузеры в целом будут использовать стили по умолчанию из вашей операционной системы.

Например, если вы сравниваете кнопку или полосу прокрутки в Google Chrome в Windows 7 и Windows 8:

  • В окнах 7 кнопка будет иметь горизонтальную линию градиента в центре вашей кнопки

  • В окнах 8 полоса прокрутки может затухать и исчезать при нажатии

Это только мое мнение, но надеюсь, что он может дать вам несколько идей:)

Ответ 4

Вы можете использовать display:table-cell; vertical-align: middle; в качестве альтернативного метода.

Ответ 5

В Mozilla Firefox я получил свойство -moz-appearance:

-moz-appareance: button;

В черновик HTML5 существует раздел рендеринга, но не детализирует размещение: S