html - titulo - Como alinhar caixas de seleção e seus rótulos de forma consistente entre navegadores




titulo html (20)

Este é um dos problemas menores de CSS que me atormentam constantemente. Como as pessoas ao redor do Stack Overflow alinham as checkboxes e seus labels consistente entre os navegadores ? Sempre que eu os alinhá-los corretamente no Safari (geralmente usando vertical-align: baseline na input ), eles estão completamente fora do Firefox e do IE. Corrigi-lo no Firefox e Safari e IE são inevitavelmente bagunçados. Eu perco tempo com isso toda vez que eu codifico um formulário.

Aqui está o código padrão com o qual trabalho:

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

Eu costumo usar o reset de Eric Meyer, então os elementos de formulário são relativamente limpos de substituições. Ansioso para algumas dicas ou truques que você tem para oferecer!


Às vezes, o alinhamento vertical precisa de dois elementos inline (span, label, input, etc ...) próximos uns dos outros para funcionar corretamente. As caixas de seleção a seguir são centralizadas corretamente no IE, Safari, FF e Chrome, mesmo que o tamanho do texto seja muito pequeno ou grande.

Eles flutuam um ao lado do outro na mesma linha, mas o nowrap significa que todo o texto do rótulo fica sempre ao lado da caixa de seleção.

A desvantagem são as tags SPAN extras sem sentido.

.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>

Agora, se você tivesse um texto de rótulo muito longo que precisasse ser agrupado sem envolver na caixa de seleção, usaria o preenchimento e o recuo de texto negativo nos elementos de rótulo:

.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>


A única solução perfeita para mim é:

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

Testado hoje no Chrome, Firefox, Opera, IE 7 e 8. Exemplo: Fiddle


Agora que o flexbox é suportado em todos os navegadores modernos, algo como isso parece uma abordagem mais fácil para mim.

<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>


Aqui está a demonstração completa da versão com prefixo:

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>


Após mais de uma hora de ajustes, testes e tentativas de diferentes estilos de marcação, acho que posso ter uma solução decente. Os requisitos para este projeto em particular foram:

  1. As entradas devem estar em sua própria linha.
  2. As entradas da caixa de seleção precisam se alinhar verticalmente com o texto da etiqueta de maneira semelhante (se não de forma idêntica) em todos os navegadores.
  3. Se o texto da etiqueta for agrupado, ele precisa ser recuado (portanto, não coloque abaixo da caixa de seleção).

Antes de entrar em qualquer explicação, vou dar o código:

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>

Aqui está o exemplo de trabalho no JSFiddle .

Este código assume que você está usando um reset como o de Eric Meyer, que não sobrescreve as margens de entrada do formulário e o preenchimento (portanto, colocando margens e preenchimentos de preenchimento no CSS de entrada). Obviamente, em um ambiente ao vivo, você provavelmente estará aninhando / substituindo coisas para suportar outros elementos de entrada, mas eu queria manter as coisas simples.

Coisas para observar:

  • A declaração *overflow é um hack inline do IE (o hack da propriedade da estrela). Tanto o IE 6 quanto o 7 o notarão, mas o Safari e o Firefox irão ignorá-lo. Eu acho que pode ser CSS válido, mas você ainda está melhor com comentários condicionais; apenas usou para simplificar.
  • Pelo que sei, a única instrução de vertical-align que era consistente nos navegadores era vertical-align: bottom . Definir isso e, em seguida, posicionar-se relativamente para cima se comportou quase de forma idêntica no Safari, Firefox e IE com apenas um ou dois pixels de discrepância.
  • O principal problema em trabalhar com alinhamento é que o IE coloca um monte de espaço misterioso em torno dos elementos de entrada. Não é preenchimento ou margem, e é muito persistente. Definir uma largura e altura na caixa de seleção e, em seguida, overflow: hidden por algum motivo corta o espaço extra e permite que o posicionamento do IE aja de forma muito semelhante ao Safari e Firefox.
  • Dependendo do tamanho do seu texto, sem dúvida você precisará ajustar o posicionamento relativo, a largura, a altura e assim por diante para fazer as coisas parecerem corretas.

Espero que isso ajude alguém! Eu não tentei essa técnica específica em nenhum outro projeto que não aquele em que eu estava trabalhando esta manhã, então definitivamente vá atrás se você encontrar algo que funcione de forma mais consistente.


Codifique a altura e a largura da caixa de seleção, remova o preenchimento e aumente a altura e as margens verticais para igual à altura da linha da etiqueta. Se o texto do rótulo estiver in-line, flutue a caixa de seleção. O Firefox, o Chrome e o IE7 + renderizam o seguinte exemplo de forma idêntica: http://www.kornea.com/css-checkbox-align


Com uma caixa de seleção de tipo de entrada dentro do rótulo e flutuou para a esquerda da seguinte forma:

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

isso funcionou para mim:

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;
}

Certifique-se de que a altura seja idêntica à altura da linha do (nível de bloco).


Eu acho que essa é a maneira mais fácil

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

Fiddle


Eu costumo deixar uma caixa de seleção não marcada e, em seguida, faço o seu "rótulo" um elemento separado. É uma dor, mas há muita diferença entre navegadores entre como caixas de seleção e seus rótulos são exibidos (como você percebeu) que esta é a única maneira que eu posso chegar perto de controlar como tudo parece.

Eu também acabo fazendo isso no desenvolvimento de winforms, pelo mesmo motivo. Eu acho que o problema fundamental com o controle da caixa de seleção é que são realmente dois controles diferentes: a caixa e o rótulo. Ao usar uma caixa de seleção, você está deixando para os implementadores do controle decidir como esses dois elementos são exibidos um ao lado do outro (e eles sempre entendem errado, onde errado = não o que você quer).

Eu realmente espero que alguém tenha uma resposta melhor para sua pergunta.


Eu não gosto de posicionamento relativo porque ele torna o elemento renderizado acima de tudo em seu nível (ele pode ficar em cima de algo se você tiver layout complexo).

Descobri que o vertical-align: sub faz com que as caixas de seleção pareçam alinhadas no Chrome, Firefox e Opera. Não é possível verificar o Safari, pois não tenho MacOS e o IE10 está um pouco fora, mas descobri que é uma solução boa o suficiente para mim.

Outra solução pode ser tentar criar CSS específico para cada navegador e ajustá-lo com algum alinhamento vertical em% / pixels / EMs: http://css-tricks.com/snippets/css/browser-specific-hacks/


Eu não testei completamente a minha solução, mas parece funcionar muito bem.

Meu HTML é simplesmente:

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

Em seguida, defino todas as caixas de seleção para 24px para altura e largura. Para tornar o texto alinhado, eu faço a line-height de line-height da etiqueta também 24px e atribuo vertical-align: top; igual a:

EDIT: Após o teste do IE, adicionei vertical-align: bottom; para a entrada e mudou o CSS da etiqueta. Você pode achar que precisa de um caso css do IE condicional para classificar o preenchimento - mas o texto e a caixa estão em linha.

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;
}

Se alguém achar que isso não funciona, por favor, me avise. Aqui está em ação (no Chrome e no IE - desculpas, já que screenshots foram tiradas na retina e usando paralelos para o IE):


Experimente a minha solução, eu tentei no IE 6, FF2 e Chrome e processa pixel a pixel em todos os três navegadores.

* {
  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>


Isto funciona bem para mim:

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>


Só queria adicionar à discussão sobre o atributo 'for' nos rótulos (ligeiramente offtopic):

Por favor, forneça-o, mesmo quando não for necessário, porque é muito conveniente usar a partir do javascript:

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

Isso é muito mais conveniente do que tentar descobrir se o rótulo tem a entrada aninhada, ou se a entrada está antes do rótulo, ou depois de etc. etc. E nunca é demais fornecê-lo ... então.

Apenas meus 2 centavos.


Se você estiver usando o Twitter Bootstrap, basta usar a classe da checkbox no <label> :

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

Trabalhando com a solução do One Crayon , tenho algo que funciona para mim e é mais simples:

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>

Processa pixel-por-pixel da mesma forma no Safari (cuja linha de base eu confio) e tanto o Firefox quanto o IE7 são bons. Ele também funciona para vários tamanhos de fonte de rótulo, grandes e pequenos. Agora, para corrigir a linha de base do IE em seleções e entradas ...


Uma coisa fácil que parece funcionar bem é aplicar um ajuste na posição vertical da caixa de seleção com alinhamento vertical. Ainda será variar entre os navegadores, mas a solução é descomplicada.

input {
    vertical-align: -2px;
}

Reference


tente vertical-align: middle

também seu código parece que deveria ser:

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


position: relative; tem alguns problemas no IE com z-index e animações como o slideUp / slideDown do 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');
    }
});

O estilo provavelmente precisa de ajustes dependendo do tamanho da fonte usado <label>

PS:
Eu uso o ie7js para fazer o css funcionar no IE6.


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


<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>

O truque é usar vertical-align apenas nas células da tabela ou inline-block se estiver usando tag label.





html-form