Alinee las etiquetas en forma junto a la entrada

136

Tengo un escenario de forma muy básico y conocido donde necesito alinear las etiquetas junto a las entradas correctamente. Sin embargo, no sé cómo hacerlo.

Mi objetivo sería que las etiquetas estén alineadas junto a las entradas en el lado derecho. Aquí hay un ejemplo de imagen del resultado deseado.

ingrese la descripción de la imagen aquí

He hecho un violín para su conveniencia y para aclarar lo que tengo ahora: http://jsfiddle.net/WX58z/

Retazo:

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

Stan
fuente

Respuestas:

189

Una posible solución:

  • Dar las etiquetas display: inline-block;
  • Darles un ancho fijo
  • Alinear texto a la derecha

Es decir:

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

bfavaretto
fuente
44
¿Cómo hago que esto funcione si algunas de las etiquetas son casillas de verificación o botones de opción? Las etiquetas para estos elementos terminan con el mismo ancho fijo que las etiquetas del cuadro de texto que no se desea. ¿Hay alguna manera de hacer esto sin un ancho fijo en la etiqueta?
Rebecca Meritz
@RebeccaMeritz ¿Quiere decir cuándo el marcado tiene la casilla de verificación primero y la etiqueta después? Puede agregar una clase a ambos y diseñarlos por separado. Quizás deberías hacer una nueva pregunta al respecto.
bfavaretto
2
¿Cómo hacer que esto responda? ¿Y cómo lidiar con i18n? Quiero decir que las etiquetas de texto tienen diferente longitud en diferentes idiomas, por lo tanto, me temo que esa configuración de ancho de relleno fijo no funcionará si el texto es largo.
Azimuth
@Azimuth Hoy en día, es posible que desee utilizar la cuadrícula CSS en su lugar.
bfavaretto
1
Esto marca el ancho fijo, debe ser dinámico, basado en el ancho máximo de la etiqueta.
Samyak Jain
27

Si bien las soluciones aquí son viables, la tecnología más reciente ha hecho lo que creo que es una mejor solución. CSS Grid Layout nos permite estructurar una solución más elegante.

El CSS a continuación proporciona una estructura de "configuración" de 2 columnas, donde se espera que la primera columna sea una etiqueta alineada a la derecha, seguida de algún contenido en la segunda columna. Se puede presentar contenido más complicado en la segunda columna envolviéndolo en un <div>.

[Como nota al margen: uso CSS para agregar el ':' que rastrea cada etiqueta, ya que este es un elemento estilístico, mi preferencia.]

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

David Rutherford
fuente
1
Oye, ¿puedes agregar un violín por favor?
Stan
Sí, he actualizado la respuesta para hacer uso de fragmentos.
David Rutherford
¿Con qué versión y plataforma de Chrome tienes problemas?
David Rutherford
1
¡Solucion optima! Funciona bien ahora en Chrome 73.
Philipp Michalski
¡Increíble! Si reemplaza la definición de columnas anterior con grid-template-columns: max-content 1fr;, la segunda columna utilizará todo el ancho restante. Esto para mí es el santo grial de tales diseños, donde no se deben especificar anchos de columna o contenido, y todo encaja perfectamente en el espacio disponible, automáticamente.
jeff-h
12

Respondí una pregunta como esta antes, puedes echar un vistazo a los resultados aquí:

Crear formulario para tener campos y texto uno al lado del otro: ¿cuál es la forma semántica de hacerlo?

Entonces, para aplicar las mismas reglas a su violín, puede usar display:inline-blockpara mostrar su etiqueta y grupos de entrada uno al lado del otro, así:

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

violín actualizado

Andres Ilich
fuente
Esta es una solución muy buena, excepto por el hecho de que debe codificar el ancho de las etiquetas. Si una nueva etiqueta es demasiado larga, el diseño se rompe. Parece que debería haber una solución más robusta?
mattstuehler
8

Yo uso algo similar a esto:

<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;
}
Mike G
fuente
4

También puedes intentar usar flex-box

<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>
usuario6797117
fuente
Eso es bonito, pero no es lo que pidió. Vea la imagen en op
phorgan1
3

Sé que este es un hilo antiguo, pero una solución más fácil sería incrustar una entrada dentro de la etiqueta de esta manera:

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

Robert
fuente
Estaba buscando una solución para esto (incluya la entrada dentro de la etiqueta) pero con texto alineado
Natim
0

Aquí está el ancho de las etiquetas genéricas para todas las etiquetas de formulario. Nada arregla el ancho.

llame a la calculadora setLabelWidth con todas las etiquetas. Esta función cargará todas las etiquetas en la interfaz de usuario y descubrirá el ancho máximo de la etiqueta. Aplique el valor de retorno de la siguiente función a todas las etiquetas.

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

        };
Samyak Jain
fuente
0

Puedes hacer algo como esto:

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 esto ayude ! :)

Rakonjac
fuente