web-dev-qa-db-fra.com

Zone de texte d'entrée HTML avec une largeur de 100% des cellules de tableau débordements

Est-ce que quelqu'un sait pourquoi les éléments en entrée avec une largeur de 100% vont au-dessus du bord des cellules du tableau?.

Dans l'exemple simple ci-dessous, dans la zone de saisie, accédez à la bordure de cellules du tableau, le résultat est horrible. Cela a été testé et cela se passe de la même manière sur: Firefox, IE7 et Safari.

Cela a-t-il un sens pour vous? Est-ce que quelque chose me manque, êtes-vous au courant d'une solution possible?

<!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>
100
Marco Demaio

Vous pouvez utiliser la propriété CSS3 box-sizing pour inclure le remplissage externe et la bordure:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}
199
pricco

La valeur de la largeur ne prend pas en compte la bordure ou le remplissage:

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

Vous obtenez 2px de rembourrage de chaque côté, plus 1px de bordure de chaque côté.
100% + 2 * (2px + 1px) = 100% + 6px, ce qui est supérieur au contenu enfant de 100% contenu par le parent td.

Vous avez l'option de:

  • Paramétrez box-sizing: border-box; conformément à @ réponse de pricco ;
  • Ou en utilisant 0 margin et padding (en évitant la taille supplémentaire).
23
ANeves

Le problème avec des éléments tels que width:95%; est qu’ils ne s’apparaissent pas correctement dans des mises en page flexibles larges (car 5% peut alors représenter 30 pixels).

Les solutions suivantes fonctionnent très bien pour moi (testées dans 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>

(ajout des couleurs pour faciliter le repérage du bon remplissage)

L'astuce consiste à envelopper l'entrée avec deux divs, l'extérieur a une marge de 3px (ce qui la rend 3px plus petite que le td), l'intérieur a un rembourrage de 3px. Cela rend l’entrée 6px plus petite que le td, ce qui est ce que vous vouliez commencer.

Je ne suis pas sûr de la mécanique, mais ça marche. 

Dans cet exemple simple, cela fonctionne également avec un seul div avec la marge droite 6. Toutefois, dans le cas de mon application Web, seule la solution ci-dessus fonctionne. 

<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>
14
Andreas

Le problème a été expliqué précédemment et je ne ferai que le répéter: la largeur ne tient pas compte de la bordure et du remplissage. Une réponse possible à cette question non discutée mais que j’ai trouvée m’a beaucoup aidé est de conclure vos contributions. Voici le code, et je vais expliquer comment cela aide dans une seconde:

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

Le DIV enveloppant l'ENTRÉE n'a pas de remplissage ni de bordure. C'est la solution. Une DIV étendra à la taille de son conteneur, mais elle respectera également les bordures et le remplissage. Maintenant, INPUT n'aura plus aucun problème à augmenter la taille de son conteneur car il est sans bordure et sans patin. Notez également que le débordement de la DIV est défini sur masqué. Il semble que par défaut, les éléments peuvent tomber en dehors de leur conteneur avec le débordement par défaut de visible. Cela garantit simplement que l'entrée reste dans son conteneur et ne tente pas de passer à travers.

J'ai testé cela dans Chrome et Fire Fox. Les deux semblent bien respecter cette solution.

UPDATE: Étant donné que je viens d'avoir un vote par ordre aléatoire, j'aimerais vous dire que le meilleur moyen de gérer les débordements consiste à utiliser l'attribut CSS3 Box-Sizing décrit par pricco:

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

Cela semble être assez bien supporté par les principaux navigateurs et n'est pas "hacky" comme le truc du débordement. Cette approche présente toutefois quelques problèmes mineurs sur les navigateurs actuels (voir http://caniuse.com/#search=box-sizing Problèmes connus).

8
David Peterson

Je sais que cette question a 3 ans, mais le problème persiste pour les navigateurs actuels et les gens viennent toujours ici. La solution pour l'instant est calc ()

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

Il est supporté par la plupart des navigateurs modernes.

2
trojan

Le problème est dû au modèle de boîte d'élément d'entrée. Je viens tout juste de trouver une solution intéressante à ce problème lorsque je tente de maintenir ma contribution à 100% pour les appareils mobiles. 

Enveloppez votre entrée avec un autre élément, un div par exemple. Ensuite, appliquez le style que vous voulez pour votre entrée à la div wrapper. Par exemple:

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

Donnez à .input-wrapper les coins arrondis, etc. Vous avez votre entrée bien rembourrée avec une bordure, etc., mais sans le débordement ennuyeux! 

1
hallodom

au lieu de cette lutte de la marge juste faire

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

ainsi, la bordure de la cellule est visible et vous pouvez contrôler la couleur d'arrière-plan de la ligne.

1
bortunac

J'ai résolu ce problème en commençant par la réponse de @ hallodom. Toutes mes entrées étaient contenues dans les liens, donc tout ce que je devais faire était de définir le débordement de li: caché pour lui permettre de supprimer cet excès de débordement.

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

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

J'ai résolu le problème en utilisant cette

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;
}
0
Kevin Muchwat

J'ai résolu le problème en appliquant box-sizing:border-box; aux cellules de la table elles-mêmes, en plus de faire la même chose avec l'entrée et l'emballage.

0
Vanco

Avec du Javascript, vous pouvez obtenir la largeur exacte du TD contenant, puis l’affecter directement à l’élément d’entrée.

Ce qui suit est javascript brut mais jQuery le rendrait plus propre ...

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

Les problèmes avec cette solution sont:

1) Si vos entrées sont contenues dans un autre élément tel qu'un SPAN, vous devrez alors boucler et trouver le TD, car des éléments tels que SPAN encapsuleront l'entrée et montreront sa taille plutôt que d'être limitée à la taille du TD.

2) Si vous avez ajouté des marges de remplissage ou des marges à différents niveaux, vous devrez peut-être explicitement les soustraire de [pEl.offsetWidth]. En fonction de votre structure HTML qui peut être calculée.

3) Si les colonnes de la table sont dimensionnées de manière dynamique, la modification de la taille d'un élément entraînera une redistribution de la table dans certains navigateurs. Vous obtiendrez peut-être un effet renforcé si vous «corrigez» séquentiellement les tailles d'entrée. La solution consiste à affecter des largeurs spécifiques à la colonne, sous forme de pourcentages ou de pixels OR, collectez les nouvelles largeurs et définissez-les ensuite. Voir le code ci-dessous.

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;
}
0
AnthonyVO

Retirez le "http://www.w3.org/TR/html4/loose.dtd" de la déclaration DOCTYPE et corrigez votre problème. 

À votre santé! :)

0
Lucian