2009-06-23 11 views
139

¿Por qué display:block;width:auto; en mi entrada de texto no se comporta como un div y llena el ancho del contenedor?Entrada con pantalla: el bloque no es un bloque, ¿por qué no?

Tenía la impresión de que un div es simplemente un elemento de bloque con ancho automático. En el siguiente código, ¿no deberían el div y la entrada tener dimensiones idénticas?

¿Cómo obtengo la entrada para completar el ancho? El ancho del 100% no funcionará, porque la entrada tiene relleno y un borde (lo que provoca un ancho final de 1   píxel + 5   píxeles + 100% + 5   píxeles + 1   píxeles). Los anchos fijos no son una opción, y estoy buscando algo más flexible.

Preferiría una respuesta directa a una solución alternativa. Esto parece una peculiaridad de CSS y su comprensión puede ser útil más adelante.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <title>width:auto</title> 

     <style> 
     div, input { 
      border: 1px solid red; 
      height: 5px; 
      padding: 5px; 
     } 
     input, form { 
      display: block; 
      width: auto; 
     } 
     </style> 
    </head> 

    <body> 
     <div></div> 
     <form> 
      <input type="text" name="foo" /> 
     </form> 
    </body> 
</html> 

Debo señalar que ya puedo hacer esto con las soluciones de la envoltura. Además de este atornillar con la semántica de la página y las relaciones del selector de CSS, estoy tratando de comprender la naturaleza del problema y si se puede superar cambiando la naturaleza de la ENTRADA.

Ok, esto es VERDADERO extraño! Descubrí que la solución es simplemente agregar max-width:100% a una entrada con width:100%;padding:5px;. Sin embargo, esto genera aún más preguntas (que formularé en otra pregunta), pero parece que el ancho utiliza el modelo de caja de CSS normal y el ancho máximo usa el modelo de caja de bordes de Explorer de Internet  . Qué extraño.

Ok, esto último parece ser un bug en Firefox 3. Internet Explorador     8 y Safari 4   límite del ancho máximo de 100% + + acolchado de frontera que es lo que la especificación dice que hacer. Finalmente, Internet   Explorer obtuvo algo bueno.

¡Dios mío, esto es increíble! En el proceso de jugar con esto, y con la ayuda de los venerables gurús Dean Edwards y Erik Arvidsson, logré juntar tres soluciones separadas para hacer un verdadero ancho de navegador cruzado de 100% en elementos con relleno y bordes arbitrarios. Ver la respuesta a continuación. Esta solución no requiere ningún marcado HTML adicional, solo una clase (o selector) y un comportamiento opcional para el explorador heredado de Internet  .

+0

duplicado exacto de [http://stackoverflow.com/questions/628500/can-i-stop-100-width-text-boxes-from-extending-beyond-their-containers ] (http://stackoverflow.com/questions/628500/can-i-stop-100-width-text-boxes-from-extinging-beyond-their-containers) –

+5

@SleepyCod que no es un duplicado exacto. Esta pregunta aborda el problema de los elementos de 'entrada' que aparentemente no cumplen con la especificación CSS 2.1, mientras que la pregunta a la que se vincula pregunta cómo evitar el desbordamiento de cajas que ocurre perfectamente dentro de los límites de la especificación CSS 2.1. Tanto las preguntas como sus soluciones se superponen, pero llamarlas duplicados exactos es simplemente ** incorrecto. ** – amn

Respuesta

123

Mira lo que yo ca con una solución que usa el estilo box-sizing:border-box relativamente desconocido de CSS   3. Esto permite un ancho "verdadero" del 100% en cualquier elemento independientemente del relleno y/o bordes de esos elementos.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 

     <title>Cross-browser CSS box-sizing:border-box</title> 

     <style type="text/css"> 
      form {display:block; margin:0; padding:0; width:50%; border:1px solid green; overflow:visible} 
      div, input {display:block; border:1px solid red; padding:5px; width:100%; font:normal 12px Arial} 

      /* The voodoo starts here */ 
      .bb { 
       box-sizing: border-box; /* CSS 3 rec */ 
       -moz-box-sizing: border-box; /* Firefox 2 */ 
       -ms-box-sizing: border-box; /* Internet Explorer 8 */ 
       -webkit-box-sizing: border-box; /* Safari 3 */ 
       -khtml-box-sizing: border-box; /* Konqueror */ 
      } 
     </style> 

     <!-- The voodoo gets scary. Force Internet Explorer 6 and Internet Explorer 7 to support Internet Explorer 5's box model --> 
     <!--[if lt IE 8]><style>.bb {behavior:url("boxsizing.htc");}</style><![endif]--> 
    </head> 

    <body> 
     <form name="foo" action="#"> 
      <div class="bb">div</div> 
      <input class="bb" size="20" name="bar" value="field"> 
     </form> 
    </body> 
</html> 

Esta solución es compatible con Internet   Explorador de   6 e Internet   Explorador de   7 a través de un comportamiento escrito por Erik Arvidsson con algunos ajustes de Dean Edwards para apoyar porcentaje y otros anchos no de píxeles.

Working example
Behaviour (boxsizing.htc)

+12

Rechazaría esta respuesta 1000 veces si pudiera. –

+2

Usted, señor, es un genio. – GeReV

+0

Esto parece una solución increíble, pero no funciona en IE8 (los cuadros div y de campo no son lo suficientemente amplios). ¿Sabes si ha habido alguna actualización de este método? ¡Gracias! – rocketmonkeys

5

Su mejor opción es envolver la entrada en un div con su borde, los márgenes, etc., y tienen la entrada en el interior con un ancho de 100% y sin fronteras, sin márgenes, etc.

Por ejemplo,

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <title>width:auto</title> 

     <style> 
      div { 
       border: 1px solid red; 
       padding: 5px; 
      } 
      input, form { 
       display: block; 
       width: 100%; 
      } 
     </style> 
    </head> 

    <body> 
     <form> 
      <div><input type="text" name="foo" /></div> 
     </form> 
    </body> 
</html> 
+0

Sí, funcionará, pero eso es más una solución que una respuesta. Estoy tratando de establecer por qué la entrada parece ignorar el comportamiento del bloque. – SpliFF

+2

Jonathan, por favor perdone mi aparente rudeza aquí, pero vine aquí buscando la respuesta correcta (tm), y también leí gustosamente la parte en la que @SpliFF menciona específicamente que preferiría una "respuesta directa a una solución alternativa, pero aún agrega otra redundante (como en, repetido muchas veces tanto en SO como en otras partes de Internet) responda, aparentemente ignorando el contrato de la pregunta. ¿Puedo preguntarle - ** por qué? ** Gracias de antemano. - Verdaderamente suyo. – amn

7

La razón por la que esto sucede es que el tamaño de una entrada de texto está determinado por su tamaño de atributo. agregue size = "50" dentro de la entrada <etiqueta>. Luego cámbialo a size = "100" - ¿ves lo que quiero decir?

Sospecho que hay una solución mejor, pero la única que me viene a la mente es algo que encontré en la pregunta "Características ocultas de HTML" en SO: Use un div editable por contenido, en lugar de una entrada. Pasar la entrada del usuario al formulario adjunto (si eso es lo que necesita) puede ser un poco complicado.

Hidden features of HTML

+7

I ' Tengo curiosidad por saber cómo las personas de CSS justifican esto. Si el ancho puede anular el tamaño de forma explícita con píxeles/porcentaje, no veo por qué debería seguir respetándolo cuando el elemento es un bloque. – SpliFF

+1

Sin embargo, ocurre lo mismo con 'button' ¿Qué no tiene un atributo 'size'? – zanona

+0

Una pregunta que se centra más en la parte" por qué es el estándar como este "como esta respuesta: http://stackoverflow.com/questions/4567988/what-is-it -en-el-css-dom-que-pr events-an-input-box-with-display-block-from-ex El principal reclamo es que es porque 'input' es un elemento reemplazado. –

1

Se podría fingir, como esto:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <title>width:auto</title> 

     <style> 
     div, #inputWrapper { 
      border: 1px solid red; 
     } 
     #topDiv { 
      padding: 5px; 
      height: 5px; 
     } 
     form { 
      display: block; 
     } 
     #inputWrapper { 
      overflow: hidden; 
      height: 15px; 
     } 
     input { 
      display: block; 
      width: 100%; 
      border-style: none; 
      padding-left: 5px; 
      padding-right: 5px; 
      height: 15px; 
     } 
     </style> 
    </head> 

    <body> 
     <div id="topDiv"></div> 
     <form> 
      <div id="inputWrapper"> 
      <input type="text" name="foo" /> 
      </div> 
     </form> 
    </body> 
</html> 
+1

He hecho el enfoque falso en el pasado, pero para ser sincero, me estoy cansando de eso. Terminé con todo tipo de hacks retardados, como usar un 99% de ancho para obtener entradas y seleccionar para que coincida. Realmente quiero una manera de tratar una entrada como un div y esperaba que hubiera pasado por alto algo. – SpliFF

+2

también su entrada desbordará inputWrapper porque todavía tiene ancho: 100% con un relleno interno. – SpliFF

1

También usted podría fingir, como esto:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
     <title>width:auto</title> 

     <style> 

      .container { 
       width:90%; 
      } 

      .container div{ 
       border: 1px solid red; 
       padding: 5px; 
       font-size:12px; 
       width:100%; 
      } 

      input{ 
        width:100%; 
       border: 1px solid red; 
       font-size:12px; 
       padding: 5px; 
      } 

      form { 

       margin:0px; 
       padding:0px; 
      } 

     </style> 
    </head> 

    <body> 
     <div class="container"> 
      <div> 
       asdasd 
      </div> 
      <form action=""> 
       <input type="text" name="foo" /> 
      </form> 
     </div> 
    </body> 
</html> 
+1

misma probabilidad que la anterior, tiene un relleno interno con un ancho del 100%. Eso se desbordará. – SpliFF

+0

puede hacer esto con javascript – AlexC

1

Prueba esto:

form { padding-right: 12px; overflow: visible; } 
input { display: block; width: 100%; } 
+1

que dejó fuera el relleno de entrada y el borde. Estaba por decir que estás equivocado hasta que me di cuenta de lo que estás haciendo. Ahora entiendo lo que Merkuro estaba tratando de hacer (su código aún está mal, pero el concepto casi estaba allí). El relleno de derecha cambia el significado de 100% por 12px (borde más relleno de entrada).Sin embargo, el inconveniente de este enfoque es que todos los demás niños de forma se ven afectados por el relleno y también necesitan compensarlo. – SpliFF

Cuestiones relacionadas