redimensionne mal; semble avoir `min-width: min-content`non modifiable

problème

j'ai un <select> où l'une de ses valeurs de texte <option> est très longue. Je veux que le <select> soit redimensionné pour qu'il ne soit jamais plus large que son parent, même s'il doit couper son texte affiché. max-width: 100% devrait faire ça.

avant resize:

the page before resize, showing the whole <codeselect</code

ce que je veux après redimensionner:

my desired page after resize, with the <codeselect</code clipping its contents

mais si vous chargez ce jsfiddle exemple et redimensionnez la largeur du panneau de résultat pour être plus petite que celle du <select> , vous pouvez voir que le select à l'intérieur du <fieldset> ne parvient pas à réduire sa largeur vers le bas.

ce que je vois après redimensionner:

my current page after resize, with a scroll bar

cependant, la page équivalente avec un <div> au lieu de <fieldset> fait échelle correctement. Vous pouvez le voir et tester vos modifications plus facilement si vous avez a <fieldset> et un <div> à côté de l'autre sur une page . Et si vous supprimez l'environnement <fieldset> tags , le redimensionnement fonctionne. La balise <fieldset> est en quelque sorte responsable du redimensionnement horizontal de casser.

le <fieldset> actes est comme si il y a une règle CSS fieldset { min-width: min-content; } . ( min-content signifie, grossièrement, la plus petite largeur qui ne provoque pas un débordement d'un enfant.) Si je remplace le <fieldset> par un <div> par min-width: min-content , il semble exactement le même. 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é d'outrepasser tous les styles visibles sur le <fieldset> dans Firebug CSS Inspecteur et dans Firefox par défaut de la feuille de style les formes.css , mais cela n'a pas aidé. L'annulation de min-width et width n'a rien fait non plus.

Code

HTML du fieldset:

<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 qui devrait fonctionner, mais n'est-ce pas:

fieldset {
    /* hide fieldset-specific visual features: */
    margin: 0;
    padding: 0;
    border: none;
}

select {
    max-width: 100%;
}

Réinitialisation des propriétés width en par défaut ne fait rien:

fieldset {
    width: auto;
    min-width: 0;
    max-width: none;
}

D'autres CSS dans lequel je essayer de ne pas corriger 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 ce exemple de jsFiddle plus complet et plus compliqué , qui est plus similaire à la page web que je suis en fait en train d'essayer de corriger. Vous pouvez voir à partir de cela que le <select> n'est pas le problème – un bloc en ligne div ne redimensionne pas non plus. Bien que cet exemple soit plus compliqué, je suppose que le correctif pour le cas simple ci-dessus va également corriger ce cas plus compliqué.

[Edit: voir les détails de la prise en charge par le navigateur ci-dessous.]

une chose curieuse au sujet de ce problème est que si vous mettez div.wrapper { width: 50%; } , le <fieldset> cesse de se redimensionner au point puis la pleine taille <select> aurait frappé le bord de la fenêtre d'affichage. Le redimensionnement se produit comme si le <select> avait width: 100% , bien que le <select> semble avoir width: 50% .

after resize with 50%-width wrapper div

si vous donnez le <select> lui-même width: 50% , ce comportement ne se produit pas; la largeur est simplement correctement définie.

after resize with 50%-width select

je ne comprends pas la raison pour cette différence. Mais il peut ne pas être pertinente.

j'ai aussi trouvé la question très similaire le jeu de champ HTML permet aux enfants d'étendre indéfiniment . L'asker n'a pas pu trouver de solution et devine qu'il n'y a pas de solution à part enlever le <fieldset> . Mais je me demande, s'il est vraiment impossible de rendre l'affichage <fieldset> correct, pourquoi? Quoi dans <fieldset> ’s spec ou css par défaut ( à partir de cette question ) provoque ce comportement? Ce comportement particulier est probablement documenté quelque part, depuis plusieurs navigateurs fonctionnent comme cela.

arrière-plan objectif et les exigences

la raison pour laquelle j'essaie de faire ceci est dans le cadre de l'écriture de styles mobiles pour une page existante avec un grand formulaire. Le formulaire comporte plusieurs sections, et une partie est enveloppée dans un <fieldset> . Sur un smartphone (ou si vous réduisez 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 de la forme limite sa largeur juste fine, mais la section avec le <fieldset> ne le fait pas, forçant l'utilisateur à zoomer ou faire défiler à droite pour voir toute cette section.

je me méfie de simplement 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 ce que les sélecteurs en CSS ou JavaScript pourrait en dépendent.

je peux utiliser JavaScript si je dois, et une solution JavaScript est mieux que rien. Mais si JavaScript est le seul moyen de faire cela, je serais curieux d'entendre une explication pour pourquoi ce n'est pas possible en utilisant seulement CSS et HTML.


Edit: prise en charge du navigateur

sur le site, je dois soutenir Internet Explorer 8 et plus tard (nous venons de laisser tomber le soutien pour IE7), Le Dernier Firefox, et Le Dernier Chrome. Cette page particulière devrait également fonctionner sur iOS et smartphones Android. Un comportement légèrement dégradé mais encore utilisable est acceptable pour Internet Explorer 8.

j'ai retesté my broken fieldset exemple sur les différents navigateurs. Il fonctionne en fait 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 que je me soucie que le code actuel se brise est Firefox (à la fois sur le bureau et mobile). Si le code a été fixé de sorte qu'il a fonctionné dans Firefox sans le casser dans d'autres navigateurs, qui résoudrait mon problème.

le modèle HTML du site utilise les commentaires conditionnels D'Internet Explorer pour ajouter des classes telles que .ie8 et .oldie à l'élément <html> . Vous pouvez utiliser ces classes dans votre CSS si vous avez besoin de travailler autour des différences de style dans IE. Les classes ajoutées sont les mêmes que dans cette ancienne version du Boilerplate HTML5 .

207
demandé sur Rory O'Kane 2013-07-01 20:01:41

4 réponses

Mise À Jour (25 Sept 2017)

a mon grand soulagement, le Firefox bug 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 .

the fix

dans WebKit et Firefox 53+, Il vous suffit de définir min-width: 0; sur le fieldset pour outrepasser la valeur par défaut de min-content .1

Pourtant, Firefox est un peu ... bizarre quand il s'agit de fieldsets. Pour que cela fonctionne dans les versions précédentes, vous devez changer la propriété display du jeu de champs à l'une des valeurs suivantes:

  • table-cell (recommandé)
  • table-column
  • table-column-group
  • table-footer-group
  • table-header-group
  • table-row
  • table-row-group

parmi ceux-ci, je recommande table-cell . table-row et table-row-group vous empêchent de changer de largeur, tandis que table-column et table-column-group vous empêchent de changer de hauteur.

cela cassera (assez raisonnablement) le rendu dans IE. Puisque seulement Gecko a besoin de cela, vous pouvez légitimement utiliser @-moz-document -un de Mozilla's proprietary CSS extensions - pour le cacher des autres navigateurs:

@-moz-document url-prefix() {
    fieldset {
        display: table-cell;
    }
}

(Voici une jsFiddle démo .)


qui répare les choses, mais si vous êtes comme moi, votre réaction a été quelque chose comme ...

quoi.

est une raison, mais c'est pas assez.

la présentation par défaut de l'élément fieldset est absurde et essentiellement impossible à spécifier dans CSS. Pensez-y: la bordure du fieldset disparaît là où elle est doublée d'un élément de légende, mais l'arrière-plan reste visible! Il n'y a aucun moyen de reproduire ceci avec une autre combinaison d'éléments.

pour couronner le tout, les mises en œuvre sont pleines de concessions au comportement hérité. Un exemple est que la largeur minimale d'un fieldset est jamais inférieure à la largeur intrinsèque de son contenu. WebKit vous donne un moyen de contourner ce comportement en le spécifiant dans la feuille de style par défaut, mais Gecko2 va un peu plus loin et le renforce dans le moteur de rendu .

cependant, les éléments de table internes constituent un de type de cadre spécial en Gecko. Les contraintes dimensionnelles pour les éléments avec cet ensemble de valeurs display sont calculées dans un chemin de code séparé , contournant entièrement la largeur minimale imposée sur les fieldsets.

encore une fois-le bug pour ce 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.

est-ce que l'utilisation de @-moz-document est sûre?

pour ce numéro, Oui. @-moz-document fonctionne comme prévu dans toutes les versions de Firefox up jusqu'à 53, où ce bug est corrigé.

ce n'est pas un accident. En partie à cause de cette réponse, le bug de limit @-moz-document vers les feuilles de style Utilisateur/UA a été rendu dépendant de la correction du bug de fieldset sous-jacent en premier.

au-delà de cela, je ne recommande plus d'utiliser @-moz-document pour cibler exclusivement Firefox dans votre CSS, en dépit d'autres ressources.3


1 Valeur préfixe. Selon un lecteur, cela n'a pas d'effet dans Android 4.1.2 Stock Browser et peut-être d'autres versions anciennes; Je n'ai pas eu le temps de vérifier cela.

"1519240920 ² 2 Tous les liens vers la source Gecko dans cette réponse se référer à la 5065fdc12408 changeset , committed 29 ❚ juillet 2013; vous pouvez comparer des notes avec le révision la plus récente de Mozilla Central .

"1519240920 ³ 3 Voir par exemple DONC #953491: Cibler uniquement avec Firefox CSS et Ruses CSS: CSS hacks ciblage Firefox pour largement référencé d'articles sur des sites.

333
répondu Jordan Gray 2017-09-25 13:41:31

Safari sur iOS problème avec la réponse choisie

J'ai trouvé la réponse de Jordan Gray particulièrement utile. Cependant, il ne semble pas résoudre ce problème sur Safari iOS pour moi.

le problème pour moi est simplement que le fieldset ne peut pas avoir une largeur automatique si l'élément intérieur a une largeur max-width en % de la largeur.

fixation pour l'émission

réglage simple le fieldset d'avoir une largeur de 100% de son conteneur semble contourner cette question.

exemple

fieldset {
    min-width: 0; 
    width: 100%; 
}

veuillez vous reporter aux exemples ci - dessous pour des exemples de travail-si vous supprimez le % de la largeur du champ ou le remplacez par auto, il ne continuera pas à fonctionner.

JSFiddle | Codepen

10
répondu boars 2014-04-23 08:55:44

j'ai lutté pendant de nombreuses heures avec cela, et fondamentalement, le navigateur applique le style calculé que vous devez outrepasser dans votre CSS. J'oublie la propriété exacte est réglé sur fieldset éléments par rapport à div s (peut-être min-width ?).

mon meilleur conseil serait de changer votre élément à un div , copier les styles calculés de votre inspecteur, puis changer votre élément de nouveau à fieldset et comparer les styles calculés pour trouver coupable.

Espère que ça aide.

mise à Jour: , Ajoutant que display: table-cell aide à de la non-navigateurs google Chrome.

3
répondu phdj 2013-08-07 16:14:33

.fake-select { white-space:nowrap; } a amené le jeu de champs à interpréter l'élément .fake-select par sa largeur d'origine, plutôt que par sa largeur forcée (même lorsque le débordement est caché).

supprimer cette règle, et de changer .fake-select 's max-width:100% à juste width:100% et tout correspond. La mise en garde est que vous voyez tout le contenu du faux-select, mais je ne pense pas que ce soit si mauvais, et il s'inscrit horizontalement maintenant.

mise à Jour: avec les règles actuelles dans le violon suivant (qui ne contient que des sélections réelles), les enfants du fieldset sont contraints de corriger les largeurs. Outre la suppression des règles pour .fake-select et la correction des commentaires (de // comment à /* comment */ , j'ai noté des changements dans le CSS de fiddle.

je comprends mieux votre problème maintenant, et le violon reflète un certain progrès. Je fixe des règles par défaut pour tous les <select> s, et Réserve .xxlarge pour ceux que vous connaissez sera plus large que 480px (et cela ne fonctionne que parce que vous savoir la largeur de #viewport , et peut ajouter manuellement la classe à ceux trop large. Il faut juste un peu de l'essai)

preuve

2
répondu Trojan 2013-07-24 16:49:13