¿Puedo evitar que los cuadros de texto de 100% de ancho se extiendan más allá de sus contenedores?

181

Digamos que tengo un cuadro de texto que quiero llenar una línea completa. Le daría un estilo como este:

input.wide {display:block; width: 100%}

Esto causa problemas porque el ancho se basa en el contenido del cuadro de texto. Los cuadros de texto tienen margen, bordes y relleno de forma predeterminada, lo que hace que un cuadro de texto con un ancho del 100% sea más grande que su contenedor.

Por ejemplo, aquí a la derecha:

ingrese la descripción de la imagen aquí

¿Hay alguna forma de hacer que un cuadro de texto llene el ancho de su contenedor sin expandirse más allá?

Aquí hay un ejemplo de HTML para mostrar lo que quiero decir:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <style type="text/css">
        #outer{border: 1px solid #000; width: 320px; margin: 0px;padding:0px}
        #inner{margin: 20px; padding: 20px; background: #999;border: 1px solid #000;}
        input.wide {display:block; margin: 0px}
        input.normal {display:block; float: right}
    </style>
</head>
<body>
    <div id="outer">
        <div id="inner">
            <input type="text" class="wide" />
            <input type="text" class="normal" />
            <div style="clear:both;"></div>
        </div>
    </div>
</body>
</html>

Si se ejecuta esto, puede ver mirando el cuadro de texto "normal" que el cuadro de texto "ancho" sobresale más allá del contenedor. El cuadro de texto "normal" flota hasta el borde real del contenedor. Estoy tratando de hacer que el cuadro de texto "ancho" llene su contenedor, sin expandirse más allá del borde como lo es el cuadro de texto "normal".

Dan Herbert
fuente

Respuestas:

87

Lo que puede hacer es eliminar los "extras" predeterminados en input:

input.wide {display:block; width:100%;padding:0;border-width:0}

Esto mantendrá el inputinterior de su contenedor. Ahora, si quieres los bordes, envuélvelos inputen a div, con los bordes establecidos en el div(de esa manera también puedes quitar los display:blockdel input). Algo como:

<div style="border:1px solid gray;">
 <input type="text" class="wide" />
</div>

Editar: Otra opción es, en lugar de eliminar el estilo del input, compensarlo en el envoltorio div:

input.wide {width:100%;}

<div style="padding-right:4px;padding-left:1px;margin-right:2px">
  <input type="text" class="wide" />
</div>

Esto le dará resultados algo diferentes en diferentes navegadores, pero no se superpondrán al contenedor. Los valores en el div dependen de qué tan grande es el borde inputy cuánto espacio desea entre inputel borde.

Hilbrand Bouwkamp
fuente
3
Esta es una solución muy creativa. El único problema que tengo con él es que no puedo definir un esquema en el cuadro de texto cuando gana el foco a menos que use JavaScript para cambiar el borde del contenedor.
Dan Herbert
@DanHerbert, tienes razón, ese es un gran defecto de UX de este método
Baumr
275

¿Hay alguna forma de hacer que un cuadro de texto llene el ancho de su contenedor sin expandirse más allá?

Sí: al usar la propiedad CSS3 'box-sizing: border-box', puede redefinir qué significa 'ancho' para incluir el relleno y el borde externos.

Desafortunadamente, debido a que es CSS3, el soporte no es muy maduro, y como el proceso de especificaciones aún no está terminado, mientras tanto tiene diferentes nombres temporales en los navegadores. Entonces:

input.wide {
    width: 100%;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

La alternativa de la vieja escuela es simplemente poner una cantidad de 'relleno derecho' en el elemento adjunto <div> o <td> igual a la cantidad de relleno / borde adicional izquierdo y derecho en 'px' que crees que los navegadores tendrán dar la entrada (Típicamente 6px para IE <8.)

bobince
fuente
Esto funcionaría muy bien, excepto que no puedo usar esto porque estoy apuntando a dispositivos móviles que probablemente no admitirán esto durante años. : - \
Dan Herbert
20
Creo que los dispositivos móviles tendrán soporte HTML5 completo antes que las computadoras.
Mariano Cavallo
44
@Kindred: definitivamente no si incluye IEMobile y Blackberry en eso.
bobince
1
Sin embargo, esto tiene un gran soporte para los navegadores de escritorio: quirksmode.org/css/contents.html
logan
2
¿Cómo me tomó tanto tiempo encontrar esta increíble salsa de mantequilla? ¿Podemos hacer que esta sea la respuesta aceptada?
streetlogics
14

¡Esto resolvió mi problema!

Sin la necesidad de un div externo. Simplemente aplíquelo a su cuadro de texto dado.

box-sizing: border-box; 

Con esta propiedad "Las propiedades de ancho y alto (y las propiedades mín. / Máx.) Incluyen contenido, relleno y borde, pero no el margen"

Ver descripción de la propiedad en w3schools .

¡Espero que esto ayude a alguien!

Jack Trowbridge
fuente
Maravillosamente simple! ¡Gracias!
nurider
10

Acabo de encontrarme con este problema, y ​​la única solución que pude encontrar que funcionó en todos mis navegadores de prueba (IE6, IE7, Firefox) fue la siguiente:

  1. Envuelva el campo de entrada en dos DIV separados
  2. Establezca el DIV externo en un ancho del 100%, esto evita que nuestro contenedor desborde el documento
  3. Coloque relleno en el DIV interno de la cantidad exacta para compensar el desbordamiento horizontal de la entrada.
  4. Establezca un relleno personalizado en la entrada para que se desborde en la misma cantidad que permití en el DIV interno

El código:

<div style="width: 100%">
    <div style="padding-right: 6px;">
        <input type="text" style="width: 100%; padding: 2px; margin: 0;
                                  border : solid 1px #999" />
    </div>
</div>

Aquí, el desbordamiento horizontal total para el elemento de entrada es 6px - 2x (relleno + borde), por lo que establecemos un relleno derecho para el DIV interno de 6px.

Tobias Cohen
fuente
agregue al elemento de entrada un relleno de 8px y ya no funciona
JuHwon
7

el soporte de tamaño de caja es bastante bueno en realidad: http://caniuse.com/#search=box-sizing

Entonces, a menos que apunte a IE7, debería poder resolver este tipo de problemas usando esta propiedad. Una capa como sass o menos facilita el manejo de reglas prefijadas como esa, por cierto.

chikamichi
fuente
3

En realidad, se debe a que CSS define el 100% en relación con todo el ancho del contenedor, incluidos sus márgenes, bordes y relleno; eso significa que el espacio disponible. en su contenido es una cantidad menor al 100%, a menos que el contenedor no tenga márgenes, bordes o relleno.

Esto es contrario a la intuición y muchos lo consideran un error con el que ahora estamos atrapados . Efectivamente significa que el% de dimensiones no son buenas para nada más que un contenedor de nivel superior, e incluso entonces, solo si no tiene márgenes, bordes o relleno.

Tenga en cuenta que los márgenes, los bordes y el relleno del campo de texto se incluyen en el tamaño CSS especificado para él: son los contenedores los que arrojan las cosas.

He trabajado tolerablemente usando 98%, pero esa es una solución menos que perfecta, ya que los campos de entrada tienden a ser más cortos a medida que el contenedor se hace más grande.


EDITAR: Me encontré con esta pregunta similar : nunca he intentado la respuesta dada, y no estoy seguro si se aplica a su problema, pero parece que lo hará.

Lawrence Dol
fuente
1

Una solución que puede funcionar (funciona para mí) es aplicar un margen negativo en la entrada (cuadro de texto) ... o ancho fijo para ie7 o soltar el soporte de ie7. Esto da como resultado un ancho perfecto de píxeles ... Para mí es 7, así que agregué 3 y 4, pero aún es perfecto de píxeles ...

¡Tenía el mismo problema y odiaba tener divs adicionales para el borde, etc.!

¡Así que aquí está mi solución que parece funcionar!

Debe usar una hoja de estilo de ie7 only para evitar los starhacks.

input.text{
    background-color: #fbfbfb;
    border : solid #eee 1px;
    width: 100%;
    -box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    height: 32px;

    *line-height:32px;
    *margin-left:-3px;
    *margin-right:-4px;
    display: inline;   
    padding: 0px 0 0 5px;

}
GorilaApe
fuente
1

Si no puede usarlo box-sizing:border-box, puede intentar eliminar width:100%y poner un sizeatributo muy grande en el <input>elemento, sin embargo, el inconveniente es que debe modificar el html y no puede hacerlo solo con CSS:

<input size="1000"></input>
siddhadev
fuente
0

Si no necesita hacerlo dinámicamente (por ejemplo, su formulario tiene un ancho fijo), simplemente puede establecer el ancho de los <input>elementos secundarios al ancho de su contenedor menos cualquier decoración como relleno, margen, borde, etc.

 // the parent div here has a width of 200px:
.form-signin input[type="text"], .form-signin input[type="password"], .form-signin input[type="email"], .form-signin input[type="number"] {
  font-size: 16px;
  height: auto;
  display: block;
  width: 280px;
  margin-bottom: 15px;
  padding: 7px 9px;
}
Avishai
fuente
0

Si no puede usar el tamaño de cuadro (por ejemplo, cuando convierte HTML a PDF usando iText). Prueba esto:

CSS

.input-wrapper { border: 1px solid #ccc; padding: 0 5px; min-height: 20px; } 
.input-wrapper input[type=text] { border: none; height: 20px; width: 100%; padding: 0; margin: 0; }

HTML

<div class="input-wrapper">
     <input type="text" value="" name="city"/>
</div>
robertad
fuente
0

Esto funciona:

<div>
    <input type="text" 
        style="margin: 5px; padding: 4px; border: 1px solid; 
        width: 200px; width: calc(100% - 20px);">
</div>

El primer 'ancho' es una regla alternativa para los navegadores más antiguos.

Mo'in Creemers
fuente
0

Simplemente diseñe la entrada para compensar el relleno adicional. En el siguiente ejemplo, el relleno en la entrada sería de 10 píxeles a la izquierda y a la derecha para un desplazamiento de relleno total de 20 píxeles:

input[type=text]{
   width: calc(100% - 20px);
}
quinlo
fuente