Elemento de entrada de estilo para llenar el ancho restante de su contenedor

197

Digamos que tengo un fragmento html como este:

<div style="width:300px;">
    <label for="MyInput">label text</label>
    <input type="text" id="MyInput" />
</div>

Este no es mi código exacto, pero lo importante es que hay una etiqueta y una entrada de texto en la misma línea en un contenedor de ancho fijo. ¿Cómo puedo diseñar la entrada para llenar el ancho restante del contenedor sin envolver y sin conocer el tamaño de la etiqueta?

Joel Coehoorn
fuente
Sé que la pregunta fue hace mucho tiempo, pero agregaré una buena solución que, por supuesto, no está desactualizada.
danijar

Respuestas:

138

Por mucho que todos odien las tablas para el diseño, ayudan con cosas como esta, ya sea usando etiquetas de tabla explícitas o usando display: table-cell

<div style="width:300px; display:table">
    <label for="MyInput" style="display:table-cell; width:1px">label&nbsp;text</label>
    <input type="text" id="MyInput" style="display:table-cell; width:100%" />
</div>
cobbal
fuente
¿Funcionaría esto con IE6? De lo contrario, podría tener que definir una pequeña tabla para esto :(
Joel Coehoorn
no estoy seguro, yo diría que hacer una prueba rápida para ver lo que hacen, pero no tienen fácil acceso a IE
cobbal
Está bien: esto me señaló hacia algo que funciona.
Joel Coehoorn el
42
¿Te gustaría compartir a Joel?
John
10
De acuerdo, debe compartir su solución real con el resto de nosotros, y marcarla como la respuesta en su lugar, como es, esto es un poco molesto.
BrainSlugs83
155

Aquí hay una solución simple y limpia sin usar JavaScript o hacks de diseño de tabla. Es similar a esta respuesta: el ancho de entrada automático del texto de entrada se llena al 100% con otros elementos flotantes

Es importante ajustar el campo de entrada con un intervalo que es display:block. Lo siguiente es que el botón tiene que venir primero y el campo de entrada segundo.

Luego puede flotar el botón a la derecha y el campo de entrada llena el espacio restante.

form {
    width: 500px;
    overflow: hidden;
    background-color: yellow;
}
input {
    width: 100%;
}
span {
    display: block;
    overflow: hidden;
    padding-right:10px;
}
button {
    float: right;
}
<form method="post">
     <button>Search</button>
     <span><input type="text" title="Search" /></span>
</form>

Un violín simple: http://jsfiddle.net/v7YTT/90/

Actualización 1: si su sitio web está dirigido solo a navegadores modernos, sugiero usar cuadros flexibles . Aquí puedes ver el soporte actual .

Actualización 2: Esto incluso funciona con múltiples botones u otros elementos que comparten el total con el campo de entrada. Aquí hay un ejemplo .

danijar
fuente
Sin embargo, esto cambia el html: el elemento que desea al final aparece primero en el html.
Joel Coehoorn
@ JooCoehoorn, eso es correcto. Es su decisión si prefiere eso en lugar de usar una tabla o no.
danijar
2
Esto funciona muy bien. Use float: left en lugar de right para crear un etiquetador de estilo facebook o algo similar.
hobberwickey
1
¡Esto funciona muy bien! ¿Pero alguien puede explicar la lógica detrás de cómo funciona esto?
Sherlock
1
Esta es una mala respuesta. Parece que funciona si lo miras, pero prueba el violín. En realidad, es cortar la mitad del cuadro de entrada, pero no se puede saber a menos que comience a probarlo. El objetivo es ajustar el cuadro de entrada al ancho del área de visualización, no truncarlo. Si intenta hacer cualquier estilo (esquinas redondeadas, un borde, justificación correcta del texto), esto falla completamente.
Roger Hill
55

Sugiero usar Flexbox:

¡Sin embargo, asegúrese de agregar los prefijos de proveedor adecuados!

form {
  width: 400px;
  border: 1px solid black;
  display: flex;
}

input {
  flex: 2;
}

input, label {
  margin: 5px;
}
<form method="post">
  <label for="myInput">Sample label</label>
  <input type="text" id="myInput" placeholder="Sample Input"/>
</form>

Leishman
fuente
La pregunta es muy antigua ... probablemente así es como lo haría hoy. Si tengo la oportunidad de probarlo y funciona con todos los navegadores que necesitaba, actualizaré la respuesta aceptada. Sin embargo, probablemente pasará mucho tiempo antes de que pueda probar esto. Ahora estoy en el equipo de administración de sys, ya no hago tantas cosas web.
Joel Coehoorn
¿Podría dar un ejemplo usando a label? Estaría especialmente interesado en cómo el código HTML de la pregunta original se podría usar layouted border-box...
lacco
44
¿Por qué flex: 2y no flex: 1?
Iulius Curt
42

Utilice flexbox para esto. Tienes un contenedor que va a flexionar a sus hijos en una fila. El primer niño toma su espacio según sea necesario. El segundo se flexiona para tomar todo el espacio restante:

<div style="display:flex;flex-direction:row">
    <label for="MyInput">label&nbsp;text</label>
    <input type="text" id="MyInput" style="flex:1" />
</div>

basarat
fuente
¡Choca esos cinco! :) Una cosa que vale la pena agregar (en el contexto de muchos de nosotros que todavía estamos adoptando el modelo flexbox): que INPUT estará en FORMULARIO, que a su vez puede terminar en el contenedor flexible general (p. Ej., Con otras cosas que no son de forma) ), y luego ya no funcionará, porque el comportamiento flexible solo se aplica a los descendientes directos (es decir, elementos secundarios). Por lo tanto, ¡el FORMULARIO también debe ser un contratista flexible!
Sz.
flex-direction ya está rowpredeterminado, no tiene que especificarlo.
Fabian Picone
flex para la victoria (de nuevo); respuesta muy relevante en 2019
secretwep
17

La forma más fácil de lograr esto sería:

CSS:

label{ float: left; }

span
{
    display: block;
    overflow: hidden;
    padding-right: 5px;
    padding-left: 10px;
}

span > input{ width: 100%; }

HTML:

<fieldset>
    <label>label</label><span><input type="text" /></span>
    <label>longer label</label><span><input type="text" /></span>
</fieldset>

Parece que: http://jsfiddle.net/JwfRX/

embestida
fuente
Esto funciona bien para mi. El desbordamiento evita que las cosas se envuelvan, el relleno derecho evita que el lado derecho se corte.
Prof. Von Lemongargle
PD: con un navegador moderno, recomendaría usar flex-box como se describe anteriormente por leishman ...
llange
4

Un truco muy fácil es usar una CSS calcfórmula. Todos los navegadores modernos, IE9, una amplia gama de navegadores móviles deberían admitir esto.

<div style='white-space:nowrap'>
  <span style='display:inline-block;width:80px;font-weight:bold'>
    <label for='field1'>Field1</label>
  </span>
  <input id='field1' name='field1' type='text' value='Some text' size='30' style='width:calc(100% - 80px)' />
</div>
Quien
fuente
44
Esto supone que conoce el ancho exacto de la etiqueta o que está dispuesto a soportar más espacio.
Nelson Rothermel
2

puedes probar esto:

div#panel {
    border:solid;
    width:500px;
    height:300px;
}
div#content {
	height:90%;
	background-color:#1ea8d1; /*light blue*/
}
div#panel input {
	width:100%;
	height:10%;
	/*make input doesnt overflow inside div*/
	-webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
	/*make input doesnt overflow inside div*/
}
<div id="panel">
  <div id="content"></div>
  <input type="text" placeholder="write here..."/>
</div>

Andik
fuente
mejor método hoy
yota
0

Si estás usando Bootstrap 4:

<form class="d-flex">
  <label for="myInput" class="align-items-center">Sample label</label>
  <input type="text" id="myInput" placeholder="Sample Input" class="flex-grow-1"/>
</form>

Mejor aún, use lo que está integrado en Bootstrap:

  <form>
    <div class="input-group">
      <div class="input-group-prepend">
        <label for="myInput" class="input-group-text">Default</label>
      </div>
      <input type="text" class="form-control" id="myInput">
    </div>
  </form>

https://jsfiddle.net/nap1ykbr/

DharmaTurtle
fuente