Come posso fare una larghezza del TextArea al 100% senza traboccare quando il riempimento è presente nei CSS?


426

Ho il seguente snippet CSS e HTML in fase di rendering.

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>

Il problema è che l'area di testo finisce per essere 8px più ampia (2px per il bordo + 6px per il riempimento) rispetto al genitore. C'è un modo per continuare a usare il bordo e il riempimento ma limitando la dimensione totale della textareaalla larghezza del genitore?


A proposito c'è un buon articolo per questo di Jeffrey Way su tutsplus qui: net.tutsplus.com/tutorials/html-css-techniques/… Forse aiuterà qualcuno;)
Qualcuno

Risposte:


664

Perché non dimenticare gli hack e farlo con i CSS?

Uno che uso frequentemente:

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

Vedi il supporto del browser qui .


22
Non posso credere che abbia funzionato. Ma lo ha fatto. CSS non è mai così facile. :-)
Nate Bird,

1
Questa deve essere una delle cose più belle che ho trovato da un po '. Grazie, c'è qualche possibilità che ci sia un modo per farlo anche in IE7?
Jeremy A. West,

47
Tieni presente che vorrai comunque utilizzare larghezza: 100% in combinazione con il riquadro.
Tyler,

3
Le vecchie versioni di Internet Explorer non utilizzano solo il comportamento del riquadro?
Peter Hedberg,

3
qualcuno può spiegarlo per favore, dove va questa lezione? un div che circonda la textarea?
Kooang

81

La risposta a molti problemi di formattazione CSS sembra essere "aggiungi un altro <div>!"

Quindi, in questo spirito, hai provato ad aggiungere un div wrapper a cui vengono applicati il ​​bordo / imbottitura e quindi a inserire l'area di testo al 100% di larghezza all'interno di quello? Qualcosa di simile (non testato):

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>


1
Ho finito per allontanarmi dall'utilizzo di% larghezze. Credo che il tuo approccio funzionerebbe altrettanto bene però. Grazie!
Eric Schoonover,

5
Non dimenticare di aggiungere "." alla classe textwrapper.
Chris Porter,

3
@Chris: grazie e risolto. Sono leggermente sorpreso che ci sia voluto quasi un anno e mezzo perché qualcuno lo
catturasse

2
Come appariranno le barre di scorrimento della textarea in questo caso?
Daniel LeCheminant,

1
In Chrome, quando focalizzi l'elemento textarea, questo viene evidenziato automaticamente e se crei un'imbottitura per il wrapper div, questa imbottitura sarà visibile e due bordi saranno visibili a causa di ciò. Uno dall'hightlighting e un altro dal bordo .textwrapper: 1px solido # 999999;
Qualcuno il

22

consideriamo l' output finale reso all'utente di ciò che vogliamo ottenere: un'area di testo imbottita con un bordo e un'imbottitura, le cui caratteristiche sono che facendo clic passano il focus sulla nostra area di testo e il vantaggio di una larghezza automatica del 100% tipico degli elementi a blocchi.

Secondo me, l'approccio migliore consiste nell'utilizzare il più possibile soluzioni di basso livello per raggiungere il massimo supporto dei browser. In questo caso l'unico HTML potrebbe funzionare bene, evitando l'uso di Javascript (che comunque amiamo tutti).

Il tag LABEL viene in nostro aiuto perché ha tale comportamento e può contenere gli elementi di input a cui deve rivolgersi. Il suo stile predefinito è quello degli elementi in linea, quindi, dando all'etichetta uno stile di visualizzazione a blocchi possiamo avvalerci della larghezza automatica al 100% che include imbottitura e bordi, mentre l'area di testo interna non ha bordi, nessuna imbottitura e una larghezza del 100% .

Dando un'occhiata alle specifiche del W3C, altri vantaggi che possiamo notare sono:

  • non è necessario alcun attributo "for": quando un tag LABEL contiene l'input target, focalizza automaticamente l'input figlio quando viene cliccato;
  • se un'etichetta esterna per l'area di testo è già stata progettata, non si verificano conflitti, poiché un determinato input può avere una o più etichette.

Vedi le specifiche del W3C per informazioni più dettagliate.

Esempio semplice:

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

Il padding e il bordo degli elementi .textareaContainer sono quelli che vogliamo dare alla textarea. Prova a modificarli per modellarlo come desideri. Ho dato un'imbottitura e bordi grandi e visibili all'elemento .textareaContainer per farti vedere il loro comportamento quando si fa clic.


Non sono sicuro di ciò che si nascondono tra i browser, ma mi è piaciuto l'approccio. +1
HRJ,

15

Se non ti preoccupi troppo della larghezza dell'imbottitura, questa soluzione manterrà anche l'imbottitura in percentuale.

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

Non perfetto, ma otterrai un'imbottitura e la larghezza si aggiunge al 100%, quindi va tutto bene


12

Mi sono imbattuto in un'altra soluzione qui che è così semplice: aggiungi padding-right al contenitore di textarea. Ciò mantiene il margine, il bordo e l'imbottitura nell'area di testo, evitando il problema che Beck ha sottolineato sull'evidenziazione della messa a fuoco che Chrome e Safari mettono intorno all'area di testo.

L'imbottitura del contenitore a destra dovrebbe essere la somma del margine, del bordo e dell'imbottitura effettivi su entrambi i lati dell'area di testo, più l'eventuale imbottitura che altrimenti si potrebbe desiderare per il contenitore. Quindi, per il caso nella domanda originale:

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>

1
+1 Funzionerà con più browser rispetto alle istruzioni CSS3. La sfortunata verità è che il mondo ha ancora bisogno di div wrapper.
BenSwayne,

Mi piace molto questa risposta. Fa si che lo snap dell'area di testo si adatti senza numeri percentuali magici inferiori al 100%. È possibile utilizzare il riempimento su tutti i lati del wrapper per forzare l'area di testo a muoversi all'interno e rimanere all'interno del genitore. L'altezza minima e l'altezza devono essere anche al 100% sull'involucro. La textarea può quindi essere impostata al 100% con la stessa imbottitura per adattare perfettamente tutto.
justdan23,

9

Questo codice funziona per me con IE8 e Firefox

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

Ha funzionato anche in Chrome.
Sanjeev,

5

Puoi utilizzare la proprietà di ridimensionamento delle caselle, supportata da tutti i principali browser conformi agli standard e IE8 +. Avrai comunque bisogno di una soluzione alternativa per IE7. Leggi di più qui .


@DavidJohnstone: E poiché non stai più sviluppando siti per IE7 o precedenti, questa è LA soluzione :)
Jonatan Littke,

2

No, non puoi farlo con i CSS. Questo è il motivo per cui Microsoft ha inizialmente introdotto un altro modello di scatola , e forse più pratico . Il modello a scatola che alla fine ha vinto, rende poco pratico mescolare percentuali e unità.

Non penso che sia giusto per te esprimere anche il riempimento e la larghezza dei bordi in percentuale del genitore.


2

Stavo cercando una soluzione di styling in linea anziché una soluzione CSS, e questa è la migliore che posso fare per una textarea reattiva:

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

1

Se lo pad e lo offset in questo modo:

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

il lato destro dell'area di testo si allinea perfettamente con il lato destro del contenitore, e il testo all'interno dell'area di testo si allinea perfettamente con il testo del corpo nel contenitore ... e il lato sinistro dell'area di testo "sporge" un po '. a volte è più bello.



1

Per le persone che usano Bootstrap, textarea.form-control può portare anche a problemi di dimensionamento di textarea. Chrome e Firefox sembrano utilizzare altezze diverse con il seguente CSS Bootstrap:

textarea.form-conrtol{
    height:auto;
}

1

Risolvo spesso quel problema con calc(). Devi solo dare alla textarea una larghezza del 100% e una certa quantità di riempimento, ma devi sottrarre la spaziatura totale sinistra e destra della larghezza del 100% che hai dato alla textarea:

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

O se vuoi dare un bordo alla textarea:

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

0

Che ne dici di margini negativi?

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

0

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.