HTML-Eingabetextfeld mit einer Breite von 100% überläuft Tabellenzellen

105

Weiß jemand, warum die Eingabeelemente mit einer Breite von 100% über den Zellenrand der Tabelle hinausgehen?

In dem einfachen Beispiel unten, in dem das Eingabefeld über den Zellenrand der Tabelle geht, ist das Ergebnis schrecklich. Dies wurde getestet und geschieht auf die gleiche Weise: Firefox, IE7 und Safari.

Macht es für dich Sinn? Vermisse ich etwas, wissen Sie über eine mögliche Lösung Bescheid?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    
<html><head>    
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <!-- don't use closing slash in meta tag, it breaks HTML4.01 transitional -->
   <title>Test input text in table</title>
   <style type="text/css">      
      table {border-top: 1px solid #ff0000; border-left: 1px solid #ff0000;}
      table td {border-right: 1px solid #00ff00; border-bottom: 1px solid #00ff00;}
      input[type="text"] {width: 100%;} /* removing this would make input not to go over cells border, but they would be too short, I want them to fit cells size */
   </style>    
</head><body>

<table cellpadding="0" cellspacing="0">
   <tr>
      <td><p>column one hello babe babe babe</p></td>
      <td><p>column two hello babe more</p></td>
      <td><p>column three hello babe more and more</p></td>
   </tr>
   <tr>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
   </tr>
</table>

</body></html>
Marco Demaio
quelle
1
Ich würde vorschlagen, dass Sie, wenn Sie nur eine Tabelle zur Darstellung der Eingaben verwenden, zu a formmit den labels und inputs in einem uloder wechseln ol. das ist zumindest etwas semantischer. Natürlich sollten Sie ein verwenden form, auch wenn Sie sich an das halten table.
David sagt, Monica wieder einsetzen

Antworten:

215

Sie können die CSS3- box-sizingEigenschaft verwenden, um die externe Auffüllung und den Rand einzuschließen:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}
Preis
quelle
1
Traurig zu sagen, aber leider geht IE 7 nicht richtig mit der Boxgröße um. Versuchen Sie Folgendes in IE 7 ... css3.info/preview/box-sizing oder siehe css-tricks.com/box-sizing
AnthonyVO
@AnthonyVO: true, die einzige Problemumgehung für IE7 besteht darin, mithilfe von IE-bedingten Kommentaren <!--[if lt IE 8]>undinput[type="text"] {width:95%}
Marco Demaio
24

Der Breitenwert berücksichtigt keine Rahmen oder Auffüllungen:

http://www.htmldog.com/reference/cssproperties/width/

Sie erhalten 2 Pixel Polsterung auf jeder Seite plus 1 Pixel Rand auf jeder Seite.
100% + 2 * (2px + 1px) = 100% + 6px, was mehr als der 100% ige untergeordnete Inhalt des übergeordneten td ist.

Sie haben die Möglichkeit:

  • Entweder Einstellung box-sizing: border-box;wie pro @ pricco Antwort ;
  • Oder verwenden Sie 0 Rand und Polsterung (unter Vermeidung der zusätzlichen Größe).
ANeves
quelle
weiter zu Sr pts Antwort könnten Sie die Auffüllung und den Rand auf 0px setzen, dann sollten die 100% funktionieren.
Mauro
In der Tat, auch ohne Polsterung für td - sehr gut hinzugefügt.
ANeves
1
Wenn das Auffüllen ein Problem verursacht, können Sie das text-indentAuffüllen vor der Vorderkante des Texts und das line-heightvertikale Auffüllen simulieren (obwohl das Beibehalten des vertikalen Auffüllens die Breite ohnehin nicht beeinflussen würde).
David sagt, Monica am
14

Das Problem mit Dingen wie width:95%; ist, dass sie in breiten flexiblen Layouts nicht richtig aussehen (weil 5% dann wie 30 Pixel sein können).

Die folgenden Lösungen funktionieren sehr gut für mich (getestet in Firefox, IE 9, Safari):

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
</tr>
</table>

(fügte die Farben hinzu, um das Erkennen der richtigen Polsterung zu erleichtern)

Der Trick besteht darin, die Eingabe mit zwei Divs zu versehen. Die äußere hat einen 3px-Rand (wodurch sie 3px kleiner als die td ist), die innere hat einen 3px-Abstand. Dies macht den Eingang 6px kleiner als den td, womit Sie beginnen wollten.

Ich bin mir über die Mechanik nicht sicher, aber es funktioniert.

In diesem einfachen Beispiel funktioniert es auch mit nur einem Div mit rechtem Rand 6. Bei meiner Webanwendung funktioniert jedoch nur die obige Lösung.

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
</tr>
</table>
Andreas
quelle
Es funktioniert (upvoted +1). Seltsamerweise habe ich vor jedem <Eingang> Text eingefügt und "Leerzeichen: Nowrap" hinzugefügt, um sie in derselben Zeile zu halten. Dann haben die drei <Eingaben> die Tabellenzellen übergelaufen, wenn ich alles "Leerzeichen: Nowrap" entferne geht wieder. Seltsam.
Jose Manuel Abarca Rodríguez
8

Das Problem wurde bereits zuvor erläutert, daher werde ich nur wiederholen: Die Breite berücksichtigt keine Rahmen und Auffüllungen. Eine mögliche Antwort auf diese Frage, die nicht besprochen wurde, die mir aber geholfen hat, ist, Ihre Eingaben zu verpacken. Hier ist der Code, und ich werde gleich erklären, wie dies hilft:

<table>
  <tr>
    <td><div style="overflow:hidden"><input style="width:100%" type="text" name="name" value="hello world" /></div></td>
  </tr>
</table>

Der DIV, der den EINGANG umhüllt, hat weder eine Polsterung noch einen Rand. Das ist die Lösung. Ein DIV wird auf die Größe seines Containers erweitert, berücksichtigt aber auch Rand und Polsterung. Jetzt kann der INPUT problemlos auf die Größe seines Containers erweitert werden, da er randlos und ohne Pad ist. Beachten Sie auch, dass der Überlauf des DIV auf ausgeblendet eingestellt ist. Es scheint, dass Elemente standardmäßig außerhalb ihres Containers liegen können, wobei der Standardüberlauf sichtbar ist. Dies stellt nur sicher, dass die Eingabe in ihrem Container bleibt und nicht versucht, durchzustechen.

Ich habe dies in Chrome und in Fire Fox getestet. Beide scheinen diese Lösung gut zu respektieren.

UPDATE : Da ich gerade eine zufällige Abwertung erhalten habe, möchte ich sagen, dass ein besserer Weg, um mit Überlauf umzugehen, das von pricco beschriebene CSS3-Attribut zur Boxgrößenbestimmung ist:

.myinput {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}

Dies scheint von den großen Browsern ziemlich gut unterstützt zu werden und ist nicht "hacky" wie der Überlauftrick. Bei aktuellen Browsern mit diesem Ansatz gibt es jedoch einige kleinere Probleme (siehe http://caniuse.com/#search=box-sizing Bekannte Probleme).

David Peterson
quelle
3
Ein kurzer Hinweis: overflow: hidden;Der Inhalt "sticht" immer noch genauso auf die Außenseite des Felds durch, wird jedoch abgeschnitten, anstatt angezeigt zu werden, sodass er andere Inhalte nicht überlappt.
ANeves
2

Ich weiß, dass diese Frage 3 Jahre alt ist, aber das Problem besteht weiterhin für aktuelle Browser und die Leute kommen immer noch hierher. Die Lösung für jetzt ist calc () :

input {
    width: calc(100% - 12px); /* IE 9,10 , Chrome, Firefox */
    width: -webkit-calc(100% - 12px); /*For safari 6.0*/
}

Es wird von den meisten modernen Browsern unterstützt.

Trojaner
quelle
1

Das Problem ist auf das Eingabeelement-Box-Modell zurückzuführen. Ich habe erst kürzlich eine gute Lösung für das Problem gefunden, als ich versuchte, meine Eingabe für mobile Geräte auf 100% zu halten.

Schließen Sie Ihre Eingabe mit einem anderen Element ein, z. B. einem div. Wenden Sie dann das gewünschte Styling für Ihre Eingabe auf das Wrapper-Div an. Beispielsweise:

<div class="input-wrapper">
 <input type="text" />
</div>

.input-wrapper {
    border-raius:5px;
    padding:10px;
}
.input-wrapper input[type=text] {
    width:100%;
    font-size:16px;
}

Geben Sie .input-wrapper abgerundete Ecken usw., was auch immer Sie für Ihre Eingabe wünschen, und geben Sie dann die Eingabebreite 100% an. Sie haben Ihre Eingabe schön mit einem Rand usw. aufgefüllt, aber ohne den störenden Überlauf!

Hallodom
quelle
1

Ich habe dieses Problem behoben, beginnend mit der Antwort von @ hallodom. Alle meine Eingaben waren in li enthalten, also musste ich nur den li-Überlauf einstellen: versteckt, damit dieser überschüssige Eingabeüberlauf entfernt wird.

.ie7 form li {
  width:100%;
  overflow:hidden;
}

.ie7 input {
  width:100%;
}
chet
quelle
1

statt dieser Marge kämpfen Sie einfach

input{
    width:100%;
    background:transparent !important;
}

Auf diese Weise ist der Zellenrand sichtbar und Sie können die Hintergrundfarbe der Zeilen steuern

Bortunac
quelle
0

Nehmen Sie die "http://www.w3.org/TR/html4/loose.dtd" aus der DOCTYPE-Deklaration heraus und beheben Sie Ihr Problem.

Prost! :) :)

Lucian
quelle
Meinen Sie mit http://www.w3.org/TR/html4/strict.dtdStrict? ref. w3.org/QA/2002/04/valid-dtd-list.html Auf jeden Fall ist dies keine Option, da eine Änderung des DOCTYPE jetzt wahrscheinlich das Rendern vieler anderer Stufs auf Webseiten beeinflussen würde.
Marco Demaio
0

Mit etwas Javascript können Sie die genaue Breite des enthaltenen TD ermitteln und diese dann direkt dem Eingabeelement zuweisen.

Das Folgende ist rohes Javascript, aber jQuery würde es sauberer machen ...

var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        el.style.width = pEl.offsetWidth;
    }
}

Die Probleme mit dieser Lösung sind:

1) Wenn Ihre Eingaben in einem anderen Element wie einem SPAN enthalten sind, müssen Sie eine Schleife erstellen und den TD finden, da Elemente wie SPANs die Eingabe umbrechen und ihre Größe anzeigen, anstatt auf die Größe des TD beschränkt zu sein.

2) Wenn Sie Auffüllungen oder Ränder auf verschiedenen Ebenen hinzugefügt haben, müssen Sie diese möglicherweise explizit von [pEl.offsetWidth] subtrahieren. Abhängig von Ihrer HTML-Struktur, die berechnet werden kann.

3) Wenn die Größe der Tabellenspalten dynamisch ist, führt das Ändern der Größe eines Elements in einigen Browsern zu einem Reflow der Tabelle, und Sie erhalten möglicherweise einen schrittweisen Effekt, wenn Sie die Eingabegrößen nacheinander "korrigieren". Die Lösung besteht darin, der Spalte bestimmte Breiten entweder als Prozentsätze oder Pixel zuzuweisen ODER die neuen Breiten zu sammeln und danach festzulegen. Siehe den Code unten ..

var inputs = document.getElementsByTagName('input');
var newSizes = [];
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        newSizes.push( { el: el, width: pEl.offsetWidth });
    }
}

// Set the sizes AFTER to avoid stepping...
for (var i = 0; i < newSizes.length; i++)
{
    newSizes[i].el.style.width = newSizes[i].width;
}
AnthonyVO
quelle
0

Ich habe das Problem durch Bewerbung gelöst box-sizing:border-box; zu den Tabellenzellen selbst, außer dasselbe mit der Eingabe und dem Wrapper zu tun.

Vanco
quelle
0

Ich habe das Problem damit gelöst

tr td input[type=text] {
  width: 100%;
  box-sizing: border-box;
  -webkit-box-sizing:border-box;
  -moz-box-sizing: border-box;
  background:transparent !important;
  border: 0px;
}
Kevin Muchwat
quelle
-1

Normalerweise setze ich die Breite meiner Eingaben auf 99%, um dies zu beheben:

input {
    width: 99%;
}

Sie können auch die Standardstile entfernen. Dadurch wird jedoch weniger deutlich, dass es sich um ein Textfeld handelt. Ich werde jedoch trotzdem den Code dafür zeigen:

input {
    width: 100%;
    border-width: 0;
    margin: 0;
    padding: 0;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

Ad @ m

kirb
quelle
-2

Das Problem liegt im border-widthEingabeelement. Versuchen Sie in Kürze, margin-leftdas Eingabeelement auf einzustellen -2px.

table input {
  margin-left: -2px;
}
Burek Pekaric
quelle
glaube nicht. das verschiebt nur die Box nach links und zerstört den linken Rand
cc junge