Как выровнять флажки и их метки последовательно в кросс-браузерах

Это одна из незначительных проблем CSS, которая постоянно беспокоит меня. Как люди вокруг Stack Overflow вертикально выравнивают checkboxes и labels последовательно кросс-браузер? Всякий раз, когда я правильно выравниваю их в Safari (обычно используя vertical-align: baseline на input), они полностью отключены в Firefox и IE. Исправьте это в Firefox, и Safari и IE неизбежно испортятся. Я трачу на это время каждый раз, когда пишу код. форма.

вот стандартный код, с которым я работаю:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

Я обычно использую сброс Эрика Мейера, поэтому элементы формы относительно чисты от переопределений. С нетерпением ждем любых советов или трюков, которые вы можете предложить!

30 ответов


после более чем часа настройки, тестирования и пробования разных стилей разметки, я думаю, что у меня может быть достойное решение. Требования к этому конкретному проекту были:

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

прежде чем я войду в любое объяснение, я просто дам вам код:

label {
  display: block;
  padding-left: 15px;
  text-indent: -15px;
}
input {
  width: 13px;
  height: 13px;
  padding: 0;
  margin:0;
  vertical-align: bottom;
  position: relative;
  top: -1px;
  *overflow: hidden;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

вот рабочий пример, в JSFiddle.

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

Примечание:

  • на *overflow объявление является встроенным IE hack (звезда-свойство hack). И IE 6 и 7 заметят это, но Safari и Firefox будут правильно игнорировать его. Я думаю, что это может быть действительный CSS, но вам все равно лучше с условными комментариями; просто использовал его для простоты.
  • насколько я могу судить, только vertical-align оператор, который был согласован между браузерами, был vertical-align: bottom. Установка этого, а затем относительно позиционирования вверх вела себя почти одинаково в Safari, Firefox и IE только с одним или двумя пикселями несоответствия.
  • основная проблема в работе с выравниванием заключается в том, что IE вставляет кучу таинственного пространства вокруг входных элементов. Это не обивка или поля, и это чертовски настойчиво. Установка ширины и высоты на флажке, а затем overflow: hidden по какой-то причине отрезает дополнительное пространство и позволяет позиционированию IE действовать очень аналогично в Safari и Firefox.
  • в зависимости от вашего размера текста вам, несомненно, нужно настроить относительное позиционирование, ширину, высоту и т. д., чтобы все выглядело правильно.

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


иногда для вертикального выравнивания требуется два встроенных (span, label,input и т. д...) элементы рядом друг с другом, чтобы работать должным образом. Следующие флажки правильно расположены по вертикали в IE, Safari, FF и Chrome, даже если размер текста очень мал или велик.

они все плавают рядом друг с другом на одной строке, но nowrap означает, что весь текст метки всегда остается рядом с флажком.

недостатком являются дополнительные бессмысленные теги SPAN.

.checkboxes label {
  display: block;
  float: left;
  padding-right: 10px;
  white-space: nowrap;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

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

.checkboxes label {
  display: block;
  float: left;
  padding-right: 10px;
  padding-left: 22px;
  text-indent: -22px;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

работает с один карандаш решение, у меня есть то, что работает для меня и проще:

input[type=checkbox], input[type=radio] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}

input[type=radio] {
  bottom: 2px;
}
<label>
  <input type="checkbox">
  Label text
</label>

отображает пиксель за пикселем то же самое в Safari (чья базовая линия я доверяю), и Firefox и IE7 проверяют как хорошо. Он также работает для различных размеров шрифта этикетки, больших и малых. Теперь для фиксации базовой линии IE на выборках и входах...


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

input {
    vertical-align: -2px;
}

ссылка


попробовать vertical-align: middle

также ваш код кажется, что он должен быть:

<form>
    <div>
        <input id="blah" type="checkbox"><label for="blah">Label text</label>
    </div>
</form>

попробуйте мое решение, я попробовал его в IE 6, FF2 и Chrome, и он отображает пиксель за пикселем во всех трех браузерах.

* {
  padding: 0px;
  margin: 0px;
}
#wb {
  width: 15px;
  height: 15px;
  float: left;
}
#somelabel {
  float: left;
  padding-left: 3px;
}
<div>
  <input id="wb" type="checkbox" />
  <label for="wb" id="somelabel">Web Browser</label>
</div>

единственное идеально рабочее решение для меня:

input[type=checkbox], input[type=radio] {
    vertical-align: -2px;
    margin: 0;
    padding: 0;
}

протестировано сегодня в Chrome, Firefox, Opera, IE 7 и 8. Пример: Скрипка


Я обычно использую высоту строки, чтобы настроить вертикальное положение моего статического текста:

label {
  line-height: 18px;
}
input {
  width: 13px;
  height: 18px;
  font-size: 12px;
  line-height: 12px;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

надеюсь, что это поможет.


Я не полностью протестировал свое решение, но, похоже, работает отлично.

мой HTML просто:

<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>

затем я установил все флажки в 24px по высоте и ширине. Чтобы выровнять текст, я делаю метку line-height и 24px и назначить vertical-align: top; вот так:

EDIT: после тестирования IE я добавил vertical-align: bottom; на вход и изменил CSS метки. Вы можете найти, что вам нужен условный случай IE css для сортировки заполнения - но текст и поле встроены.

input[type="checkbox"] {
    width: 24px;
    height: 24px;
    vertical-align: bottom;
}
label.checkbox {
    vertical-align: top;
    line-height: 24px;
    margin: 2px 0;
    display: block;
    height: 24px;
}

если кто-нибудь обнаружит, что это не работает, пожалуйста, сообщите мне об этом. Вот он в действии (в Chrome и IE-извинения, поскольку скриншоты были сделаны на сетчатке и с использованием параллелей для IE):

screenshot of checkboxes: Chromescreenshot of checkboxes: IE


Я думаю, что это самый простой способ

input {
    position: relative;
    top: 1px;
}

Скрипка


это хорошо работает для меня:

fieldset {
  text-align:left;
  border:none
}
fieldset ol, fieldset ul {
  padding:0;
  list-style:none
}
fieldset li {
  padding-bottom:1.5em;
  float:none;
  clear:left
}
label {
  float:left;
  width:7em;
  margin-right:1em
}
fieldset.checkboxes li {
  clear:both;
  padding:.75em
}
fieldset.checkboxes label {
  margin:0 0 0 1em;
  width:20em
}
fieldset.checkboxes input {
  float:left
}
<form>
  <fieldset class="checkboxes">
    <ul>
      <li>
        <input type="checkbox" name="happy" value="yep" id="happy" />
        <label for="happy">Happy?</label>
      </li>
      <li>
        <input type="checkbox" name="hungry" value="yep" id="hungry" />
        <label for="hungry">Hungry?</label>
      </li>
    </ul>
  </fieldset>
</form>

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

Я обнаружил, что vertical-align: sub делает флажки достаточно хорошо выровненными в Chrome, Firefox и Opera. Не могу проверить Safari, так как у меня нет MacOS и IE10 немного выключен, но я нашел, что это достаточно хорошее решение для меня.

другим решением может быть попытка сделать определенный CSS для каждого браузер и настроить его с некоторым вертикальным выравниванием в % / пикселей / EMs: http://css-tricks.com/snippets/css/browser-specific-hacks/


Теперь, когда flexbox поддерживается во всех современных браузерах, что-то вроде этого кажется мне более простым подходом.

<style>
label {
  display: flex;
  align-items: center;
}
input[type=radio], input[type=checkbox]{
  flex: none;
}
</style>
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>


вот полная версия с префиксом demo:

label {
	display: -webkit-box;
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-align: center;
	-webkit-align-items: center;
	-ms-flex-align: center;
	align-items: center;
}
input[type=radio], 
input[type=checkbox] {
	-webkit-box-flex: 0;
	-webkit-flex: none;
	-ms-flex: none;
	flex: none;
	margin-right: 10px; 
}
/* demo only (to show alignment) */
form {
  max-width: 200px
}
<form>
  <label>
    <input type="radio" checked>
    I am an aligned radio and label
  </label>
  <label>
      <input type="checkbox" checked>
    I am an aligned checkbox and label
  </label>
</form>

У меня никогда не было проблем с этим вроде этого:

<form>
  <div>
    <input type="checkbox" id="cb" /> <label for="cb">Label text</label>
  </div>
</form>

просто хотел добавить к обсуждению атрибута " for " на ярлыках (немного offtopic):

пожалуйста, поставьте его, даже если это не нужно, потому что это очень удобно использовать из javascript:

var label = ...
var input = document.getElementById(label.htmlFor);

Это намного удобнее, чем пытаться выяснить, где метка имеет вложенный вход, или где вход находится до метки или после.. так далее. И никогда не повредит поставить его.. так.

просто мои 2 цента.


если вы используете ASP.NET веб-формы вам не нужно потревожиться о DIVs и других элементах или фиксированных размерах. Мы можем выровнять <asp:CheckBoxList> текст настройки float:left к типу ввода CheckboxList в CSS.

пожалуйста, проверьте следующий код:

.CheckboxList
{
    font-size: 14px;
    color: #333333;
}
.CheckboxList input
{
    float: left;
    clear: both;
}

.Код ASPX:

<asp:CheckBoxList runat="server" ID="c1" RepeatColumns="2" CssClass="CheckboxList">
</asp:CheckBoxList>

выбранный ответ С 400 + upvotes не работал для меня в Chrome 28 OSX, вероятно, потому, что он не был протестирован в OSX или что он работал во всем, что было вокруг в 2008 году, когда на этот вопрос был дан ответ.

времена изменились, и теперь возможны новые решения CSS3. Мое решение использует pseudoelements создать пользовательский флажок. Таким образом, условия (за или против, как бы вы ни смотрели на это) следующие:

  • работает только в современных браузерах (в FF3.6+, в IE9+, хром, сафари)
  • полагается на пользовательский флажок, который будет отображаться точно так же в каждом браузере/ОС. Здесь я только что выбрал несколько простых цветов, но вы всегда можете добавить линейные градиенты и такие, чтобы дать ему больше взрыва.
  • ориентирован на определенный размер шрифта / шрифта, который при изменении вы просто измените расположение и размер флажка, чтобы он выглядел вертикально выровненным. Если правильно настроить, конечный результат все равно должно быть примерно одинаково во всех браузерах / операционных системах.
  • нет свойств вертикального выравнивания, нет поплавков
  • должен использовать предоставленную разметку в моем примере, она не будет работать, если структурирована как вопрос, однако макет будет по существу выглядеть одинаково. Если вы хотите переместить вещи, вам также придется переместить связанный CSS

HTML-код:

<form>
    <div class="checkbox">
        <input id="check_me" type=checkbox />
        <label for="check_me">Label for checkbox</label>
    </div>
</form>

ваш CSS:

div.checkbox {
    position: relative;
    font-family: Arial;
    font-size: 13px;
}
label {
    position: relative;
    padding-left: 16px;
}
label::before {
    content :"";
    display: inline-block;
    width: 10px;
    height: 10px;
    background-color: white;
    border: solid 1px #9C9C9C;
    position: absolute;
    top: 1px;
    left: 0px;
}
label::after {
    content:"";
    width: 8px;
    height: 8px;
    background-color: #666666;
    position: absolute;
    left: 2px;
    top: 3px;
    display: none;
}
input[type=checkbox] {
    visibility: hidden;
    position: absolute;
}
input[type=checkbox]:checked + label::after {
    display: block;
}
input[type=checkbox]:active + label::before {
    background-color: #DDDDDD;
}

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

jsFiddle:http://jsfiddle.net/SgXYY/6/

и если вам интересно, вот мой взгляд на переключатели:http://jsfiddle.net/DtKrV/2/

надеюсь, кто-то найдет это полезно!


<form>
    <div>
        <label style="display: inline-block">
            <input style="vertical-align: middle" type="checkbox" />
            <span style="vertical-align: middle">Label text</span>
         </label>
    </div>
</form>

трюк заключается в использовании вертикального выравнивания только в ячейках таблицы или встроенном блоке при использовании тега метки.


Если вы используете Twitter Bootstrap, вы можете просто использовать checkbox класс <label>:

<label class="checkbox">
    <input type="checkbox"> Remember me
</label>

Hardcode высота и ширина флажка, удалите его заполнение и сделайте его высоту плюс вертикальные поля равными высоте линии метки. Если текст метки встроен, установите флажок. Firefox, Chrome и IE7+ все одинаково отображают следующий пример:http://www.kornea.com/css-checkbox-align


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

<label for="id" class="checkbox">
    <input type="checkbox" id="id">
    <span>The Label</span>
</label>

это сработало для меня:

label.checkbox {
    display: block;
}
.checkbox input {
    float: left;
    height: 18px;
    vertical-align: middle;
}
.checkbox span {
    float: left;
    line-height: 18px;
    margin: 0 0 0 20px;
}

убедитесь, что высота совпадает с высотой линии (blocklevel).


input[type=checkbox]
{
    vertical-align: middle;
} 
<input id="testCheckbox" name="testCheckbox" type="checkbox">
<label for="testCheckbox">I should align</label>

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

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

Я действительно надеюсь, что у кого-то есть лучший ответ на ваш вопрос.


CSS:

.threeCol .listItem {
    width:13.9em;
    padding:.2em;
    margin:.2em;
    float:left;
    border-bottom:solid #f3f3f3 1px;
}
.threeCol input {
    float:left;
    width:auto;
    margin:.2em .2em .2em 0;
    border:none;
    background:none;
}
.threeCol label {
    float:left;
    margin:.1em 0 .1em 0;
}

HTML-код:

<div class="threeCol">
    <div class="listItem">
        <input type="checkbox" name="name" id="id" value="checkbox1" />
        <label for="name">This is your checkBox</label>
    </div>
</div>

приведенный выше код будет разместить элементы списка в threecols и просто изменить ширину, чтобы удовлетворить.


использовать просто vertical-align: sub, as pokrishka уже предложил.

Скрипка

HTML-код:

<div class="checkboxes">
    <label for="check1">Test</label>
    <input id="check1" type="checkbox"></input>
</div>

код CSS:

.checkboxes input {
    vertical-align: sub;
}

поэтому я знаю, что на это отвечали много раз, но я чувствую, что у меня есть более элегантное решение, чем те, которые уже были предоставлены. И не только 1 элегантное решение, но 2 отдельных решения, чтобы пощекотать вашу фантазию. С учетом сказанного, все, что вам нужно знать и видеть, содержится в 2 JS Fiddle, с комментариями.


Решение #1 опирается на собственный "флажок" данного браузера, хотя и с изюминкой... Содержащиеся в div, который легче кросс-браузер, с переполнением: скрытый, чтобы нарезать избыток растянутого флажка 1px (это так, что вы не можете видеть уродливые границы FF)

простой HTML: (перейдите по ссылке, чтобы просмотреть css с комментариями, блок кода должен удовлетворить stackoverflow) http://jsfiddle.net/KQghJ/

<label><div class="checkbox"><input type="checkbox" /></div> Label text</label>

решение #2 использует "Checkbox Toggle Hack" для переключения состояния CSS DIV, который был правильно расположен в браузере, и настройки с помощью простой спрайт для флажка unchecked и checked состояний. Все, что нужно, это настроить фоновое положение с указанным флажком переключения Hack. Это, на мой взгляд, более элегантное решение, поскольку у вас больше контроля над вашими флажками и радио, и вы можете гарантировать, что они выглядят одинаково в браузере.

простой HTML: (перейдите по ссылке, чтобы просмотреть CSS с комментариями, блок кода должен удовлетворить StackOverflow) http://jsfiddle.net/Sx5M2/

<label><input type="checkbox" /><div class="checkbox"></div>Label text</label>

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


Yay спасибо! Это тоже всегда сводило меня с ума.

в моем конкретном случае, это сработало для меня:

input {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    vertical-align: top;
    position: relative;
    *top: 1px;
    *overflow: hidden;
}
label {
    display: block;
    padding: 0;
    padding-left: 15px;
    text-indent: -15px;
    border: 0px solid;
    margin-left: 5px;
    vertical-align: top;
}

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


<fieldset class="checks">
    <legend>checks for whatevers</legend>
    <input type="" id="x" />
    <label for="x">Label</label>
    <input type="" id="y" />
    <label for="y">Label</label>
    <input type="" id="z" />
    <label for="z">Label</label>
</fieldset>

вы должны обернуть элементы управления сгруппированы в собственных fieldsets в любом случае, здесь она играет wrappa. установите вход / метку дисплей: блок, входной поплавок слева, метка справа, установите ширину, интервал управления с левыми / правыми полями, выровняйте текст метки соответственно.

так

fieldset.checks {
    width:200px
}
.checks input, .checks label {
    display:block;
}
.checks input {
    float:right;
    width:10px;
    margin-right:5px
}
.checks label {
    float:left;
    width:180px;
    margin-left:5px;
    text-align:left;
    text-indent:5px
}

вам, вероятно, нужно установить границу, контур и высоту линии на обоих, а также для кросс-браузерных/медиа-решений.


position: relative; имеет некоторые проблемы в IE с z-индексом и анимацией, такими как slideUp/slideDown jQuery.

CSS:

input[type=checkbox], input[type=radio] {
    vertical-align: baseline;
    position: relative;
    top: 3px;
    margin: 0 3px 0 0;
    padding: 0px;
}
input.ie7[type=checkbox], input.ie7[type=radio] {
    vertical-align: middle;
    position: static;
    margin-bottom: -2px;
    height: 13px;
    width: 13px;
}

jQuery:

$(document).ready(function () {
    if ($.browser.msie && $.browser.version <= 7) {
        $('input[type=checkbox]').addClass('ie7');
        $('input[type=radio]').addClass('ie7');
    }
});

стиль, вероятно, требует настроек в зависимости от размера шрифта, используемого в <label>

PS:
Я использую ie7js чтобы css работал в IE6.


следующее дает пиксель-идеальную согласованность между браузерами, даже IE9:

подход вполне разумный, до очевидности:

  1. создайте вход и метку.
  2. отображать их как блок, так что вы можете плавать их, как вам нравится.
  3. установите высоту и высоту линии на одно и то же значение, чтобы они центрировались и выравнивались по вертикали.
  4. на em измерений, рассчитать высоту элементов, браузер должен знать высоту шрифта для этих элементов, и он не должен быть установлен в единицах em.

Это приводит к глобально применимым общее правило:

input, label {display:block;float:left;height:1em;line-height:1em;}

С размер шрифта приспособляемые в виде полей или элементов.

#myform input, #myform label {font-size:20px;}

протестировано в последних Chrome, Safari и Firefox на Mac, Windows, Iphone и Android. И ИЕ9.

этот метод, вероятно, применим ко всем типам ввода, которые не выше одной строки текста. Примените правило типа в соответствии.