Pourquoi est plus large que je l'ai dit d'être?

Donné un <select> et <input> élément, à la fois de 200px large:

<!doctype html>
<body>
<select style="width: 200px"></select><br/>
<input  style="width: 200px" type="text">
</body>
<html>

Finit plus large1,2,3, 4 que les autres:

entrez la description de l'image ici

Quelle est la pourquoi pour cela?

Si quelqu'un peut donner le pourquoi, peut-être la solution serait évident, et pas un hack&prier.

Mise en page

La mise en page appliquée est parfaitement raisonnable:

entrez la description de l'image ici


Mise à Jour 1: Pendant que j'écrivais cette question Chrome mis à jour à partir de 17 pour 19.

Mise à Jour 2: Modification de rembourrage dans la <input> de 1 de zéro:

<!doctype html>
<body>
<select style="width: 200px"></select><br/>
<input style="width: 200px; padding: 0" type="text">
</body>
<html>

Ne fait pas le <input> 200px large (c'est-à-dire ne le corrige pas).

Mise À Jour 3: application D'une réinitialisation CSS :

<!doctype html>
<head>
<style type="text/css">
   * {
       padding: 0;
       margin: 0;
   }
</style>
<body>
<select style="width: 200px"></select><br/>
<input style="width: 200px; padding: 0" type="text">
</body>
<html>

Ne résout pas le problème:

entrez la description de l'image ici

Aussi, je suis moins intéressé par une solution qu'une explication.

Notes

  • 1,2,3 Chrome 1719, Firefox, Internet Explorer 9
  • 4 sous Windows 7 64-bit

Lecture Bonus

27
demandé sur Community 2012-06-20 22:19:32

4 réponses

Votre n'est pas trop large; ton

Le vrai problème est que l'élément <select> ne se comporte pas comme la plupart des éléments. Il utilise un

box-sizing: border-box;

width est la largeur de l'élément après le rembourrage et les bordures sont appliqués; se comporter comme si elle étaient seuls dans "bizarreries" mode.

Cela va à l'encontre de tous les autres éléments html du mode standard, qui utilisent:

box-sizing: content-box; 

Pour le réparer, changez le <select> pour utiliser le même modèle de boîte que le reste du html:

select { box-sizing: content-box; }

Ou modifiez le <input> pour utiliser le même modèle de boîte que le select:

input { box-sizing: border-box; }

L'élément d'entrée se comporte comme la plupart des éléments, en utilisant un modèle content-box, où width est la largeur de l'élément avant le remplissage et les bordures sont appliquées.

Il y a un remplissage par défaut et des bordures définies par votre navigateur, donc il est plus grand que ce que vous pourriez vouloir et/ou attendre. J'utilise toujours un " CSS reset" en haut de mes feuilles de style, comme ceci:

* {
    padding: 0;
    margin: 0;
}

Cela garantira qu'il n'y a pas de remplissage ou de marges par défaut sur un élément.

L'élément select est un cas différent, où se comporte plus comme un élément avec box-sizing: border-box activé, où il prend en compte les bordures et le remplissage dans sa spécification width.

Si vous ajoutez box-sizing: border-box à votre élément input, Il se comportera exactement comme vous le souhaitez.

EDIT: gras la partie qui peut être pertinente pour vous. Une autre solution est de réduire le spécifié width de l'élément d'entrée de quelques pixels, de sorte qu'il corresponde à la largeur de la zone de sélection.

Fiddle démontrant les deux solutions: http://jsfiddle.net/n4yT2/2/

27
répondu justisb 2013-09-12 14:08:48

Parce que les navigateurs font des choses avec les dimensions des boîtes de saisie (ajout de bordures par défaut, remplissage, modification du dimensionnement des boîtes, etc.) pour les faire correspondre à leurs équivalents de contrôle GUI natifs (ou du système d'exploitation).

La solution hack-and-pray, cependant, est la solution évidente, malheureusement.

2
répondu BoltClock 2012-06-20 18:32:24

, Il semble que <select> éléments se comportent comme s'ils avaient box-sizing: border-box. Essayer de le changer en box-sizing: content-box ne fonctionne pas, cependant (au moins sur Chrome 19, OSX 10.7.4).

Après avoir appliqué la réinitialisation CSS, la différence de taille reste due aux bordures sur la zone de saisie. Si vous les supprimez, les deux éléments auront exactement 200px de large. Voir démo.

1
répondu bfavaretto 2012-06-20 18:44:30

Tout remonte à Netscape.

C'est incroyable combien de personnes pensent que le modèle de boîte IE était:

C'est encore plus drôle que:

  • le modèle de boîte que Netscape créé était objectivement "droit" (archive)
  • lorsque le W3C a décidé de standardiser un modèle de boîte, il a choisi un modèle de boîte qui était objectivement "mauvais"
  • ils ont choisi un modèle de boîte qu'aucun navigateur ne faisait, et qu'aucun site web n'utilisait

Netscape et IE avaient déjà convenu que si vous dites quelque chose d'être 200px large: il allait être 200px large. Les gens ont ensuite dû vivre avec l'étrangeté de ce modèle de boîte W3C absurde, par exemple:

  • vous dites que quelque chose doit être 200px large, et dans un navigateur conforme standard, il sera 204px large
  • vous dites à un {[5] } d'être 200px large, et dans un navigateur conforme standard, il sera 200px large

HTML5 corrige enfin le modèle de boîte cassée du W3C

Il est si étrange qu'un élément de 200px de large ne finisse pas par être de 200px de large, qu'en HTML5 nous avons enfin la possibilité de revenir au modèle Netscape / IE Box original (correct):

box-sizing: border-box

, Où un bouton 75px est la largeur de 75px large.

entrez la description de l'image ici

* {

}

td {
}

.correct {
	box-sizing: border-box;
}
<table>
<thead>
	<tr><th></th><th>Correct</th><th>W3C</th></tr>
</thead>
<tbody>
	<tr>
		<td>text input</td>
		<td><input type="text" class="correct" style="width: 100px;">
		<td><input type="text" style="width: 100px;">
	</tr>
	<tr>
		<td>select</td>
		<td><select class="correct" style="width: 100px;">foo</select>
		<td><select style="width: 100px;">foo</select>
	</tr>
	<tr>
		<td>button</td>
		<td><input type="button" class="correct" style="width: 100px;">
		<td><input type="button" style="width: 100px;">
	</tr>
	<tr>
		<td>image</td>
		<td><input type="image" class="correct" style="width: 100px; border: 1px solid black;">
		<td><input type="image" style="width: 100px; border: 1px solid black;">
	</tr>
	<tr>
		<td>password</td>
		<td><input type="password" class="correct" style="width: 100px;">
		<td><input type="password" style="width: 100px;">
	</tr>
	<tr>
		<td>submit</td>
		<td><input type="submit" class="correct" style="width: 100px;">
		<td><input type="submit" style="width: 100px;">
	</tr>	
	

</tbody>
</table>
0
répondu Ian Boyd 2018-08-21 15:37:22