Alinhar etiquetas no formulário ao lado da entrada


136

Eu tenho um cenário de formulário muito básico e conhecido, no qual preciso alinhar os rótulos ao lado das entradas corretamente. No entanto, eu não sei como fazê-lo.

Meu objetivo seria que os rótulos estejam alinhados ao lado das entradas do lado direito. Aqui está um exemplo de imagem do resultado desejado.

insira a descrição da imagem aqui

Fiz um violino para sua conveniência e para esclarecer o que tenho agora - http://jsfiddle.net/WX58z/

Snippet:

<div class="block">
    <label>Simple label</label>
    <input type="text" />
</div>
<div class="block">
    <label>Label with more text</label>
    <input type="text" />
</div>
<div class="block">
    <label>Short</label>
    <input type="text" />
</div>

Respostas:


189

Uma solução possível:

  • Dê os rótulos display: inline-block;
  • Dê a eles uma largura fixa
  • Alinhar texto à direita

Isso é:

label {
  display: inline-block;
  width: 140px;
  text-align: right;
}​
<div class="block">
    <label>Simple label</label>
    <input type="text" />
</div>
<div class="block">
    <label>Label with more text</label>
    <input type="text" />
</div>
<div class="block">
    <label>Short</label>
    <input type="text" />
</div>

JSFiddle


4
Como eu faço isso funcionar se alguns dos rótulos são caixas de seleção ou botões de opção? Os rótulos desses elementos terminam com a mesma largura fixa que os rótulos da caixa de texto, o que não é desejado. Existe uma maneira de fazer isso sem uma largura fixa na etiqueta?
Rebecca Meritz

@RebeccaMeritz Você quer dizer quando a marcação tem a caixa de seleção primeiro e o rótulo depois? Você pode adicionar uma classe a ambas e estilizá-las separadamente. Talvez você deva fazer uma nova pergunta sobre isso.
bfavaretto

2
Como fazer isso responsivo? E como lidar com o i18n? Quero dizer que os rótulos de texto têm tamanhos diferentes em idiomas diferentes, portanto, temo que essa configuração de preenchimento de largura fixa não funcione se o texto for longo.
Azimute

@ Azimuth Atualmente, você pode querer usar a grade CSS.
precisa saber é o seguinte

1
como está marcando a largura fixa, deve ser dinâmico, com base na largura máxima da etiqueta.
Samyak Jain

27

Embora as soluções aqui sejam viáveis, a tecnologia mais recente criou o que eu acho que é uma solução melhor. O CSS Grid Layout nos permite estruturar uma solução mais elegante.

O CSS abaixo fornece uma estrutura de "configurações" de duas colunas, na qual se espera que a primeira coluna seja um rótulo alinhado à direita, seguido por algum conteúdo na segunda coluna. Conteúdo mais complicado pode ser apresentado na segunda coluna, envolvendo-o em um <div>.

[Como uma observação lateral: uso CSS para adicionar o ':' que segue cada rótulo, pois esse é um elemento estilístico - minha preferência.]

/* CSS */

div.settings {
    display:grid;
    grid-template-columns: max-content max-content;
    grid-gap:5px;
}
div.settings label       { text-align:right; }
div.settings label:after { content: ":"; }
<!-- HTML -->

<div class="settings">
    <label>Label #1</label>
    <input type="text" />

    <label>Long Label #2</label>
    <span>Display content</span>

    <label>Label #3</label>
    <input type="text" />
</div>


1
Ei, você pode adicionar um violino, por favor?
Stan Stan

Sim, atualizei a resposta para usar snippets.
David Rutherford

Com qual versão e plataforma do Chrome você está tendo problemas?
David Rutherford

1
Solução ideal! Funciona bem agora no Chrome 73.
Philipp Michalski

Impressionante! Se você substituir a definição de colunas acima por grid-template-columns: max-content 1fr;, a segunda coluna usará toda a largura restante. Este é para mim o Santo Graal de tais layouts, onde nenhuma largura de coluna ou conteúdo deve ser especificada e tudo se encaixa perfeitamente no espaço disponível, automaticamente.
Jeff-h

12

Respondeu a uma pergunta como essa antes, você pode dar uma olhada nos resultados aqui:

Criando formulário para ter campos e texto próximos um do outro - qual é a maneira semântica de fazer isso?

Portanto, para aplicar as mesmas regras ao seu violino, você pode usar display:inline-blockpara exibir seus grupos de rótulo e entrada lado a lado, da seguinte maneira:

CSS

input {
    margin-top: 5px;
    margin-bottom: 5px;
    display:inline-block;
    *display: inline;     /* for IE7*/
    zoom:1;              /* for IE7*/
    vertical-align:middle;
    margin-left:20px
}

label {
    display:inline-block;
    *display: inline;     /* for IE7*/
    zoom:1;              /* for IE7*/
    float: left;
    padding-top: 5px;
    text-align: right;
    width: 140px;
}

violino atualizado


Essa é uma solução muito boa, exceto pelo fato de que você deve codificar a largura dos rótulos. Se um novo rótulo for muito longo - o layout será interrompido. Parece que deveria haver uma solução mais robusta?
mattstuehler

8

Eu uso algo semelhante a este:

<div class="form-element">
  <label for="foo">Long Label</label>
  <input type="text" name="foo" id="foo" />
</div>

Estilo:

.form-element label {
    display: inline-block;
    width: 150px;
}

4

Você também pode tentar usar a caixa flexível

<head><style>
body {
    color:white;
    font-family:arial;
    font-size:1.2em;
}
form {
    margin:0 auto;
    padding:20px;
    background:#444;
}
.input-group {
    margin-top:10px;
    width:60%;
    display:flex;
    justify-content:space-between;
    flex-wrap:wrap;
}
label, input {
    flex-basis:100px;
}
</style></head>
<body>

<form>
    <div class="wrapper">
        <div class="input-group">
            <label for="user_name">name:</label>
            <input type="text" id="user_name">
        </div>
        <div class="input-group">
            <label for="user_pass">Password:</label>
            <input type="password" id="user_pass">
        </div>
    </div>
</form>

</body>
</html>

Isso é bonito, mas não o que ele pediu. Veja a foto em op
phorgan1 /

3

Eu sei que este é um thread antigo, mas uma solução mais fácil seria incorporar uma entrada no rótulo da seguinte maneira:

<label>Label one: <input id="input1" type="text"></label>


Eu estava procurando por uma solução para este (incluem a entrada no interior do rótulo), mas com texto alinhado
Natim

0

Aqui está a largura dos rótulos genéricos para todos os rótulos de formulário. Nada fixa largura.

chame a calculadora setLabelWidth com todos os rótulos. Esta função carregará todos os rótulos na interface do usuário e descobrirá a largura máxima do rótulo. Aplique o valor de retorno da função abaixo a todos os rótulos.

     this.setLabelWidth = function (labels) {
            var d = labels.join('<br>'),
                dummyelm = jQuery("#lblWidthCalcHolder"),
                width;
            dummyelm.empty().html(d);
            width = Math.ceil(dummyelm[0].getBoundingClientRect().width);
            width = width > 0 ? width + 5: width;
            //this.resetLabels(); //to reset labels.
            var element = angular.element("#lblWidthCalcHolder")[0];
            element.style.visibility = "hidden";
            //Removing all the lables from the element as width is calculated and the element is hidden
            element.innerHTML = "";
            return {
                width: width,
                validWidth: width !== 0
            };

        };

0

Você pode fazer algo assim:

HTML:

<div class='div'>
<label>Something</label>
<input type='text' class='input'/>
<div>

CSS:

.div{
      margin-bottom: 10px;
      display: grid;
      grid-template-columns: 1fr 4fr;
}

.input{
       width: 50%;
}

Espero que isto ajude ! :)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.