¿Cómo puedo hacer un TextArea 100% de ancho sin desbordar cuando el relleno está presente en CSS?

StackOverflow https://stackoverflow.com/questions/271067

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo el siguiente fragmento de CSS y HTML que se está representando.

textarea
{
  border:1px solid #999999;
  width:100%;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <textarea cols="2" rows="10" id="rules"/>
</div>

El problema es que el área de texto termina siendo 8px más ancha (2px para borde + 6px para relleno) que el padre. ¿Hay alguna manera de continuar usando el borde y el relleno, pero restringir el tamaño total de textarea al ancho del elemento primario?

¿Fue útil?

Solución

¿Por qué no? ¿Olvidaste los hacks y solo hazlo con CSS?

Uno que uso con frecuencia:

.boxsizingBorder {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
}

Consulte el soporte del navegador aquí .

Otros consejos

La respuesta a muchos problemas de formato CSS parece ser " agregar otro < div >! "

Entonces, en ese espíritu, ¿ha intentado agregar un divisor de envoltura al que se aplica el borde / relleno y luego poner el área de texto de 100% de ancho dentro de eso? Algo así (no probado):

textarea
{
  width:100%;
}
.textwrapper
{
  border:1px solid #999999;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <div class="textwrapper"><textarea cols="2" rows="10" id="rules"/></div>
</div>

Consideremos el resultado final presentado al usuario de lo que queremos lograr: un área de texto acolchada con un borde y un relleno, cuyas características son que al hacer clic pasan el foco a nuestra área de texto , y la ventaja de un ancho automático del 100% típico de los elementos de bloque.

El mejor enfoque en mi opinión es utilizar soluciones de bajo nivel en la medida de lo posible, para alcanzar el máximo soporte de navegadores. En este caso, el único HTML podría funcionar bien, evitando el uso de Javascript (que de todos modos todos amamos).

La etiqueta LABEL viene en nuestra ayuda porque tiene ese comportamiento y puede contener los elementos de entrada a los que debe dirigirse. Su estilo predeterminado es el de los elementos en línea, por lo que, al darle a la etiqueta un estilo de visualización de bloque, podemos aprovechar el ancho automático del 100%, incluido el relleno y los bordes, mientras que el área de texto interna no tiene borde, sin relleno y un ancho del 100% .

Echando un vistazo a los detalles específicos del W3C, otras ventajas que podemos notar son:

  • no " para " se necesita el atributo: cuando una etiqueta LABEL contiene la entrada objetivo, automáticamente enfoca la entrada secundaria cuando se hace clic;
  • si ya se ha diseñado una etiqueta externa para el área de texto, no se producen conflictos, ya que una entrada determinada puede tener una o más etiquetas.

Consulte especificaciones del W3C para obtener más información. información detallada.

Ejemplo simple:


<html>
<head>
<style type="text/css">
.container { width: 400px; border: 3px solid #f7c; }
.textareaContainer {
    display: block;
    border: 3px solid #38c;
    padding: 10px;
}
textarea { width: 100%; margin: 0; padding: 0; border-width: 0; }
</style>
</head>

<body> <div class="container"> I am the container <label class="textareaContainer"> <textarea name="text">I am the padded textarea with a styled border...</textarea> </label> </div> </body> </html>

El relleno y el borde de los elementos .textareaContainer son los que queremos dar al área de texto. Intenta editarlos para darle el estilo que quieras. Le di un relleno y bordes grandes y visibles al elemento .textareaContainer para que pueda ver su comportamiento al hacer clic.

Si no le preocupa demasiado el ancho del relleno, esta solución también mantendrá el relleno en porcentajes ...

textarea
{
    border:1px solid #999999;
    width:98%;
    margin:5px 0;
    padding:1%;
}

No es perfecto, pero obtendrá algo de relleno y el ancho se sumará al 100%, por lo que todo está bien

Encontré otra solución aquí que es tan simple: agregue el relleno derecho al contenedor del área de texto. Esto mantiene el margen, el borde y el relleno en el área de texto, lo que evita el problema que Beck señaló sobre el enfoque destacado que Chrome y Safari pusieron alrededor del área de texto.

El relleno derecho del contenedor debe ser la suma del margen efectivo, el borde y el relleno en ambos lados del área de texto, más cualquier relleno que pueda desear para el contenedor. Entonces, para el caso de la pregunta original:

textarea{
    border:1px solid #999999;
    width:100%;
    margin:5px 0;
    padding:3px;
}
.textareacontainer{
    padding-right: 8px; /* 1 + 3 + 3 + 1 */
}

<div class="textareacontainer">
    <textarea></textarea>
</div>

Este código funciona para mí con IE8 y Firefox

<td>
    <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
</td>

Puede hacer uso de la propiedad de tamaño de caja, es compatible con todos los principales navegadores compatibles con el estándar e IE8 +. Sin embargo, aún necesitará una solución para IE7. Más información aquí .

No, no puedes hacer eso con CSS. Esa es la razón por la que Microsoft presentó inicialmente otro, y quizás más práctico modelo de caja . El modelo de caja que finalmente ganó, hace que sea poco práctico mezclar porcentajes y unidades.

No creo que esté bien que usted exprese los anchos de relleno y borde en porcentaje del padre también.

Estaba buscando una solución de diseño en línea en lugar de una solución CSS, y esto es lo mejor que puedo obtener para un área de texto receptiva:

<div style="width: 100%; max-width: 500px;">
  <textarea style="width: 100%;"></textarea>
</div>

Si rellena y compensa de esta manera:

textarea
{
    border:1px solid #999999;
    width:100%;
    padding: 7px 0 7px 7px; 
    position:relative; left:-8px; /* 1px border, too */
}

el lado derecho del área de texto se alinea perfectamente con el lado derecho del contenedor, y el texto dentro del área de texto se alinea perfectamente con el texto del cuerpo en el contenedor ... y el lado izquierdo del textarea 'sobresale' un poco. a veces es más bonito.

Utilice propiedad de tamaño de cuadro :

-moz-box-sizing:border-box; 
-webkit-box-sizing:border-box; 
box-sizing:border-box;

Eso ayudará

Para las personas que usan Bootstrap, textarea.form-control también puede generar problemas de tamaño de textarea. Chrome y Firefox parecen usar diferentes alturas con el siguiente CSS de Bootstrap:

textarea.form-conrtol{
    height:auto;
}

¿Qué tal los márgenes negativos?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}

A menudo soluciono ese problema con calc(). Simplemente le da al área de texto un ancho del 100% y una cierta cantidad de relleno, pero debe restar el relleno total izquierdo y derecho del ancho del 100% que le ha dado al área de texto:

textarea {
    border: 0px;
    width: calc(100% -10px);
    padding: 5px; 
}

O si desea darle un borde al área de texto:

textarea {
    border: 1px;
    width: calc(100% -12px); /* plus the total left and right border */
    padding: 5px; 
}

* {
    box-sizing: border-box;
}

.container {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

/* Clear floats after the columns */
.row:after {
    content: "";
    display: table;
    clear: both;
}

input[type=text], select, textarea{
    width: 100%;
    padding: 12px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    resize: vertical;
}
<div class="container">
  <div class="row">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" placeholder="Your name..">
  </div>
  <div class="row">
    <label for="country">Country</label>
    <select id="country" name="country">
      <option value="australia">UK</option>
      <option value="canada">USA</option>
      <option value="usa">RU</option>
    </select>
  </div>    
  <div class="row">
    <label for="subject">Subject</label>
    <textarea id="subject" name="subject" placeholder="Write something.." style="height:200px"></textarea>
  </div>
</div>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top