Problème
J'ai un <select>
où l'une de ses <option>
valeurs de texte est très longue. Je veux que le <select>
redimensionne pour qu'il ne soit jamais plus large que son parent, même s'il doit couper son texte affiché. max-width: 100%
devrait le faire.
Avant de redimensionner:
Ce que je veux après le redimensionnement:
Mais si vous chargez cet exemple jsFiddle et redimensionnez la largeur du panneau Résultat pour qu'elle soit plus petite que celle du <select>
, vous pouvez voir que la sélection à l'intérieur du <fieldset>
ne parvient pas à réduire sa largeur.
Ce que je vois réellement après le redimensionnement:
Cependant, la page équivalente avec un <div>
au lieu d'un a<fieldset>
évolue correctement. Vous pouvez le voir et tester vos modifications plus facilement si vous avez un <fieldset>
et un <div>
côte à côte sur une seule page . Et si vous supprimez les <fieldset>
balises environnantes , le redimensionnement fonctionne. La <fieldset>
balise provoque en quelque sorte la rupture du redimensionnement horizontal.
Les <fieldset>
actes sont comme s'il y avait une règle CSS fieldset { min-width: min-content; }
. ( min-content
signifie, en gros, la plus petite largeur qui ne fait pas déborder un enfant.) Si je remplace le <fieldset>
par un <div>
avecmin-width: min-content
, il a exactement la même apparence. Pourtant, il n'y a pas de règle avec min-content
dans mes styles, dans la feuille de style par défaut du navigateur, ou visible dans l'inspecteur CSS de Firebug. J'ai essayé de remplacer tous les styles visibles <fieldset>
dans l'inspecteur CSS de Firebug et dans la feuille de style par défaut de Firefox, forms.css , mais cela n'a pas aidé. Spécifiquement prioritaire min-width
et width
n'a rien fait non plus.
Code
HTML de l'ensemble de champs:
<fieldset>
<div class="wrapper">
<select id="section" name="section">
<option value="-1"></option>
<option value="1501" selected="selected">Sphinx of black quartz, judge my vow. The quick brown fox jumps over the lazy dog.</option>
<option value="1480">Subcontractor</option>
<option value="3181">Valley</option>
<option value="3180">Ventura</option>
<option value="3220">Very Newest Section</option>
<option value="1481">Visitor</option>
<option value="3200">N/A</option>
</select>
</div>
</fieldset>
Mon CSS devrait fonctionner mais ne l'est pas:
fieldset {
/* hide fieldset-specific visual features: */
margin: 0;
padding: 0;
border: none;
}
select {
max-width: 100%;
}
La réinitialisation des width
propriétés aux valeurs par défaut ne fait rien:
fieldset {
width: auto;
min-width: 0;
max-width: none;
}
CSS supplémentaire dans lequel j'essaie et ne parviens pas à résoudre le problème :
/* try lots of things to fix the width, with no success: */
fieldset {
display: block;
min-width: 0;
max-width: 100%;
width: 100%;
text-overflow: clip;
}
div.wrapper {
width: 100%;
}
select {
overflow: hidden;
}
Plus de détails
Le problème se produit également dans cet exemple jsFiddle plus complet et plus compliqué , qui est plus similaire à la page Web que j'essaie de corriger. Vous pouvez en voir que ce <select>
n'est pas le problème - un bloc en ligne div
ne parvient pas non plus à redimensionner. Bien que cet exemple soit plus compliqué, je suppose que le correctif pour le cas simple ci-dessus corrigera également ce cas plus compliqué.
[Modifier: voir les détails de prise en charge du navigateur ci-dessous.]
Une chose curieuse à propos de ce problème est que si vous définissezdiv.wrapper { width: 50%; }
, les <fieldset>
arrêts se redimensionnent au point alors la taille réelle <select>
aurait atteint le bord de la fenêtre. Le redimensionnement se produit comme si le <select>
has width: 100%
, même si le <select>
ressemblait width: 50%
.
Si vous donnez le <select>
lui - mêmewidth: 50%
, ce comportement ne se produit pas; la largeur est simplement correctement réglée.
Je ne comprends pas la raison de cette différence. Mais cela peut ne pas être pertinent.
J'ai également trouvé que le champ de questions HTML très similaire permet aux enfants de se développer indéfiniment . Le demandeur n'a pas pu trouver de solution et suppose qu'il n'y a pas d' autre solution que de supprimer le <fieldset>
. Mais je me demande, s'il est vraiment impossible de bien faire l' <fieldset>
affichage, pourquoi est-ce? Quelle <fieldset>
est la spécification ou le CSS par défaut (à partir de cette question ) à l'origine de ce comportement? Ce comportement spécial est probablement documenté quelque part, car plusieurs navigateurs fonctionnent comme ceci.
Objectif et exigences de base
La raison pour laquelle j'essaie de le faire est dans le cadre de l'écriture de styles mobiles pour une page existante avec un grand formulaire. Le formulaire comporte plusieurs sections, dont une partie est enveloppée dans un <fieldset>
. Sur un smartphone (ou si vous réduisez la taille de la fenêtre de votre navigateur), la partie de la page avec le <fieldset>
est beaucoup plus large que le reste du formulaire. La plupart du formulaire limite très bien sa largeur, mais pas la section avec le <fieldset>
, forçant l'utilisateur à effectuer un zoom arrière ou à faire défiler vers la droite pour voir toute cette section.
Je me méfie simplement de supprimer le <fieldset>
, car il est généré sur de nombreuses pages dans une grande application, et je ne suis pas sûr de savoir quels sélecteurs en CSS ou JavaScript pourraient en dépendre.
Je peux utiliser JavaScript si nécessaire, et une solution JavaScript vaut mieux que rien. Mais si JavaScript est le seul moyen de le faire, je serais curieux d'entendre pourquoi il n'est pas possible d'utiliser uniquement CSS et HTML.
Modifier: prise en charge du navigateur
Sur le site, je dois prendre en charge Internet Explorer 8 et versions ultérieures (nous venons de supprimer la prise en charge d'IE7), le dernier Firefox et le dernier Chrome. Cette page particulière devrait également fonctionner sur les smartphones iOS et Android. Un comportement légèrement dégradé mais toujours utilisable est acceptable pour Internet Explorer 8.
J'ai retesté mon fieldset
exemple cassé sur différents navigateurs. En fait, cela fonctionne déjà dans ces navigateurs:
- Internet Explorer 8, 9 et 10
- Chrome
- Chrome pour Android
Il casse dans ces navigateurs:
- Firefox
- Firefox pour Android
- Internet Explorer 7
Ainsi, le seul navigateur auquel je tiens à ce que le code actuel entre en jeu est Firefox (à la fois sur ordinateur et sur mobile). Si le code était corrigé pour qu'il fonctionne dans Firefox sans le casser dans d'autres navigateurs, cela résoudrait mon problème.
Le modèle HTML du site utilise des commentaires conditionnels Internet Explorer pour ajouter des classes telles .ie8
et .oldie
à l' <html>
élément. Vous pouvez utiliser ces classes dans votre CSS si vous avez besoin de contourner les différences de style dans IE. Les classes ajoutées sont les mêmes que dans cette ancienne version de HTML5 Boilerplate .
<fieldset>
(oudiv.wrapper
) la largeur dont il a besoin, etselect { width:100% }
.max-width
semble donner à l'élément quelque% de la largeur d' origine de son parent , puis ne se redimensionne pas, alorswidth
qu'il se redimensionne avec son parent. Je pense que cela fera ce que vous voulez (mais j'aurais pu mal compris). Dans votre violon plus complexe, essayez de donner aux champs de la colonne de gauche une largeur de% et une largeur de pixel minimale. Donnez ensuite aux champs de droite 100 - (champs de gauche -% - largeur)% largeur.Réponses:
Mise à jour (25 septembre 2017)
Le bogue Firefox décrit ci-dessous est corrigé à partir de Firefox 53 et le lien vers cette réponse a finalement été supprimé de la documentation de Bootstrap .
Aussi, mes sincères excuses aux contributeurs de Mozilla qui ont dû bloquer la suppression du support en
-moz-document
partie à cause de cette réponse.Le correctif
Dans WebKit et Firefox 53+, vous venez de définir
min-width: 0;
sur le fieldset pour remplacer la valeur par défaut demin-content
.¹Pourtant, Firefox est un peu… étrange en ce qui concerne les ensembles de champs. Pour que cela fonctionne dans les versions antérieures, vous devez remplacer la
display
propriété de l'ensemble de champs par l'une des valeurs suivantes:table-cell
(conseillé)table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
Parmi ceux-ci, je recommande
table-cell
. Les deuxtable-row
ettable-row-group
vous empêcher de changer la largeur, touttable-column
ettable-column-group
vous empêcher de changer la hauteur.Cela interrompra (assez raisonnablement) le rendu dans IE. Étant donné que seul Gecko en a besoin, vous pouvez à juste titre utiliser
@-moz-document
- l'une des extensions CSS propriétaires de Mozilla - pour la cacher aux autres navigateurs:(Voici une démo jsFiddle .)
Cela règle les choses, mais si vous êtes comme moi, votre réaction a été quelque chose comme…
Quoi.
Il y a une raison, mais ce n'est pas joli.
La présentation par défaut de l'élément fieldset est absurde et essentiellement impossible à spécifier en CSS. Pensez-y: la bordure du fieldset disparaît là où elle est chevauchée par un élément de légende, mais l'arrière-plan reste visible! Il n'y a aucun moyen de reproduire cela avec une autre combinaison d'éléments.
Pour couronner le tout, les implémentations sont pleines de concessions au comportement hérité. L'une d'entre elles est que la largeur minimale d'un jeu de champs n'est jamais inférieure à la largeur intrinsèque de son contenu. WebKit vous donne un moyen de remplacer ce comportement en le spécifiant dans la feuille de style par défaut, mais Gecko² va plus loin et l' impose dans le moteur de rendu .
Cependant, les éléments de table internes constituent un type de cadre spécial dans Gecko. Les contraintes dimensionnelles pour les éléments avec ces
display
valeurs définies sont calculées dans un chemin de code séparé , contournant entièrement la largeur minimale imposée imposée aux ensembles de champs.Encore une fois - le bogue pour cela a été corrigé à partir de Firefox 53, donc vous n'avez pas besoin de ce hack si vous ne ciblez que les versions plus récentes.
L'usage est-il
@-moz-document
sûr?Pour ce seul problème, oui.
@-moz-document
fonctionne comme prévu dans toutes les versions de Firefox jusqu'à 53, où ce bug est corrigé.Ce n'est pas un hasard. En raison de cette réponse, le bogue à limiter
@-moz-document
aux feuilles de style utilisateur / UA a été rendu dépendant du bogue fieldset sous-jacent qui a été corrigé en premier.Au-delà, n'utilisez pas
@-moz-document
pour cibler Firefox dans votre CSS , malgré les autres ressources.³¹ La valeur peut être préfixée. Selon un lecteur, cela n'a aucun effet dans Android 4.1.2 Stock Browser et éventuellement d'autres anciennes versions; Je n'ai pas eu le temps de vérifier cela.
² Tous les liens vers la source Gecko dans cette réponse se réfèrent à l' ensemble de modifications 5065fdc12408 , validé le 29 juillet 2013; vous pouvez comparer les notes avec la révision la plus récente de Mozilla Central .
³ Voir par exemple SO # 953491: Cibler uniquement Firefox avec CSS et astuces CSS: hacks CSS ciblant Firefox pour des articles largement référencés sur des sites de haut niveau.
la source
Problème Safari sur iOS avec réponse sélectionnée
J'ai trouvé la réponse de Jordan Gray particulièrement utile. Cependant, cela n'a pas semblé résoudre ce problème sur Safari iOS pour moi.
Le problème pour moi est simplement que le jeu de champs ne peut pas avoir une largeur automatique si l'élément à l'intérieur a une largeur maximale en% de largeur.
Correction d'un problème
Le simple fait de définir le fieldset pour avoir une largeur de 100% de son conteneur semble contourner ce problème.
Exemple
Veuillez vous référer aux exemples ci-dessous - si vous supprimez le% width du champ ou le remplacez par auto, il ne continuera pas de fonctionner.
JSFiddle | Codepen
la source
J'ai eu du mal pendant de nombreuses heures avec cela, et fondamentalement, le navigateur applique un style calculé que vous devez remplacer dans votre CSS. J'oublie la propriété exacte qui est définie sur les
fieldset
éléments par rapport àdiv
s (peutmin-width
- être ?).Mon meilleur conseil serait de changer votre élément en a
div
, de copier les styles calculés depuis votre inspecteur, puis de changer votre élément en arrièrefieldset
et de comparer les styles calculés pour trouver le coupable.J'espère que cela pourra aider.
Mise à jour: l' ajout d'
display: table-cell
aides dans les navigateurs non Chrome.la source
fieldset
etdiv
sur cette page dans Firebug. Ça n'a pas aidé. Dans Firebug, les seules propriétés avec des valeurs différentes étaientwidth
etperspective-origin
. Lewidth
était numériquement différent, mais lesfieldset
« swidth
étaitauto
, comme lesdiv
» s. Et leperspective-origin
est juste une fonction dewidth
- 50% de celui-ci par défaut.min-width: 0;
à mon exemple après avoir testé dans Chrome, mais il semble que cela ait résolu le problème dans Chrome. L'Inspecteur Web me dit que Chrome a le stylemin-width: -webkit-min-content;
, comme je l'ai supposé. Alors maintenant, je n'ai plus qu'à résoudre le problème dans Firefox et peut-être d'autres navigateurs dans lesquels je n'ai pas encore testé..fake-select { white-space:nowrap; }
a amené le fieldset à interpréter l'.fake-select
élément par sa largeur d'origine, plutôt que par sa largeur forcée (même lorsque le débordement est masqué).Retirer cette règle, et le changement
.fake-select
« estmax-width:100%
à seulementwidth:100%
et tout se. La mise en garde est que vous voyez tout le contenu de la fausse sélection, mais je ne pense pas que ce soit si mauvais, et il s'intègre horizontalement maintenant.Mise à jour: avec les règles actuelles dans le violon suivant (qui ne contient que des sélections réelles), les enfants de l'ensemble de champs sont contraints de corriger les largeurs. Autre que la suppression des règles
.fake-select
et la correction des commentaires (de// comment
à/* comment */
, j'ai noté des changements dans le CSS du violon.Je comprends mieux votre problème maintenant, et le violon reflète certains progrès. J'ai défini des règles par défaut pour tous les
<select>
s, et réserve.xxlarge
pour celles dont vous savez qu'elles seront plus larges que 480px (et cela ne fonctionne que parce que vous connaissez la largeur de#viewport
, et pouvez ajouter manuellement la classe à celles trop larges. Nécessite juste un peu de test )Preuve
la source
<select>
. Le site actuel n'a que l'<select>
art. Le butfake-select
était d'avoir les règles de mise en page d'un<select>
sans être réellement un<select>
, juste pour montrer que ce comportement n'est pas un bug de navigateur qui ne se produit qu'avec des<select>
éléments. Donc, changer les styles.fake-select
pour être moins comme un<select>
défait le but..fake-select
boîte par une<select>
(identique à celle déjà présente) pour le démontrer. Les éléments sont tous limités à la largeur du parent (sauf lorsque vous cliquez dessus, en déposant les options, qui sont chacune affichées sur une seule ligne - mais je ne pense pas que vous puissiez contrôler cela). J'ai également supprimé toutes les règles pour.fake-select
. Le violon actuel fait-il ce dont vous avez besoin?width: 100%
fonctionne avec les menus longs de la page, mais ne fonctionne pas correctement avec les menus courts. Il étend les menus courts sur toute la largeur de la page, mais je souhaite que les menus courts conservent leur largeur courte. Les menus doivent être leur largeur naturelle s'il y a de la place, mais une largeur de 100% s'ils sont trop grands pour leur parent. C'est ce quimax-width
est censé faire, mais à défaut dans ce cas.<select>
s" des "longs<select>
" et en travaillant maintenant sur la largeur de l'arrière-plan.#viewport
n'a pas non plus de largeur fixe. C'est pourquoi j'ai mis le bouton Redimensionner la fenêtre d'affichage sur la page - afin que vous puissiez tester que tout fonctionne quelle que soit la largeur de la fenêtre d'affichage. Tout comme.fake-select
un substitut pour un réel<select>
à tester,#viewport
est un substitut pour une vraie fenêtre. (Une «fenêtre» est essentiellement une fenêtre de navigateur). J'ai inclus#viewport
sur la page afin que vous puissiez facilement voir les éléments qui dépassent de la fenêtre d'affichage, plutôt que d'avoir à faire défiler pour les voir.