Problema
Tengo un <select>
donde uno de sus <option>
valores de texto es muy largo. Quiero <select>
que cambie el tamaño para que nunca sea más ancho que su padre, incluso si tiene que cortar el texto que se muestra.max-width: 100%
Debería hacer eso.
Antes de cambiar el tamaño:
Lo que quiero después de cambiar el tamaño:
Pero si carga este ejemplo de jsFiddle y cambia el tamaño del ancho del panel Resultado para que sea más pequeño que el del <select>
, puede ver que la selección dentro del<fieldset>
no logra reducir su ancho.
Lo que realmente estoy viendo después de cambiar el tamaño:
Sin embargo, la página equivalente con una en <div>
lugar de una<fieldset>
escala correctamente. Puede ver eso y probar sus cambios más fácilmente si tiene un <fieldset>
y uno al <div>
lado del otro en una página . Y si elimina las <fieldset>
etiquetas circundantes , el cambio de tamaño funciona. los<fieldset>
etiqueta está causando que se rompa el cambio de tamaño horizontal.
Los <fieldset>
actos son como si hubiera una regla CSS fieldset { min-width: min-content; }
. ( min-content
significa, aproximadamente, el ancho más pequeño que no hace que un niño se desborde). Si reemplazo el <fieldset>
con un <div>
conmin-width: min-content
, se ve exactamente igual. Sin embargo, no hay ninguna regla min-content
en mis estilos, en la hoja de estilos predeterminada del navegador o visible en el Inspector CSS de Firebug. Traté de anular todos los estilos visibles en el <fieldset>
Inspector CSS de Firebug y en la hoja de estilo predeterminada de Firefox forms.css , pero eso no ayudó. Específicamente anulando min-width
ywidth
tampoco hizo nada.
Código
HTML del conjunto de campos:
<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>
Mi CSS que debería funcionar pero no lo es:
fieldset {
/* hide fieldset-specific visual features: */
margin: 0;
padding: 0;
border: none;
}
select {
max-width: 100%;
}
Restablecer las width
propiedades a los valores predeterminados no hace nada:
fieldset {
width: auto;
min-width: 0;
max-width: none;
}
Más CSS en el que intento y no soluciono el problema :
/* 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;
}
Más detalles
El problema también ocurre en este ejemplo de jsFiddle más completo y más complicado , que es más similar a la página web que estoy tratando de arreglar. Puede ver a partir de eso que <select>
no es el problema: un bloque en línea div
tampoco puede cambiar el tamaño. Aunque este ejemplo es más complicado, supongo que la solución para el caso simple anterior también solucionará este caso más complicado.
[Editar: consulte los detalles de soporte del navegador a continuación.]
Una cosa curiosa sobre este problema es que si configuradiv.wrapper { width: 50%; }
, las <fieldset>
paradas se redimensionan en el punto, entonces el tamaño completo <select>
habría llegado al borde de la ventana gráfica. El cambio de tamaño ocurre como si lo <select>
hubiera hecho width: 100%
, aunque <select>
parezca que sí width: 50%
.
Si das el <select>
sí mismowidth: 50%
, ese comportamiento no ocurre; el ancho simplemente está configurado correctamente.
No entiendo la razón de esa diferencia. Pero puede no ser relevante.
También encontré la pregunta muy similar El conjunto de campos HTML permite a los niños expandirse indefinidamente . El autor de la pregunta no pudo encontrar una solución y adivina que no hay solución aparte de eliminar la <fieldset>
. Pero me pregunto, si realmente es imposible hacer la <fieldset>
pantalla correctamente, ¿por qué es eso? ¿Qué en <fieldset>
la especificación o CSS predeterminado (a partir de esta pregunta ) causa este comportamiento? Este comportamiento especial probablemente esté documentado en alguna parte, ya que varios navegadores funcionan así.
Objetivo de fondo y requisitos
La razón por la que intento hacer esto es como parte de la escritura de estilos móviles para una página existente con una gran forma. El formulario tiene varias secciones, y una parte está envuelta en una <fieldset>
. En un teléfono inteligente (o si hace que la ventana de su navegador sea pequeña), la parte de la página con este <fieldset>
es mucho más ancha que el resto del formulario. La mayor parte del formulario restringe su ancho muy bien, pero la sección con <fieldset>
no lo hace, lo que obliga al usuario a alejarse o desplazarse hacia la derecha para ver toda esa sección.
Tengo cuidado de simplemente eliminarlo <fieldset>
, ya que se genera en muchas páginas en una aplicación grande, y no estoy seguro de qué selectores en CSS o JavaScript podrían depender de él.
Puedo usar JavaScript si lo necesito, y una solución de JavaScript es mejor que nada. Pero si JavaScript es la única forma de hacer esto, me gustaría escuchar una explicación de por qué esto no es posible usando solo CSS y HTML.
Editar: soporte del navegador
En el sitio, necesito admitir Internet Explorer 8 y versiones posteriores (acabamos de dejar de admitir IE7), el último Firefox y el último Chrome. Esta página en particular también debería funcionar en teléfonos inteligentes iOS y Android. Un comportamiento ligeramente degradado pero aún utilizable es aceptable para Internet Explorer 8.
Volví a probar mi fieldset
ejemplo roto en diferentes navegadores. En realidad, ya funciona en estos navegadores:
- Internet Explorer 8, 9 y 10
- Cromo
- Chrome para Android
Se rompe en estos navegadores:
- Firefox
- Firefox para Android
- Internet Explorer 7
Por lo tanto, el único navegador que me importa en el que se rompe el código actual es Firefox (tanto en computadoras de escritorio como en dispositivos móviles). Si el código se corrigiera para que funcionara en Firefox sin romperlo en ningún otro navegador, eso resolvería mi problema.
La plantilla HTML del sitio utiliza comentarios condicionales de Internet Explorer para agregar clases como .ie8
y .oldie
al <html>
elemento. Puede usar esas clases en su CSS si necesita solucionar las diferencias de estilo en IE. Las clases agregadas son las mismas que en esta versión anterior de HTML5 Boilerplate .
<fieldset>
(odiv.wrapper
) cualquier ancho que necesite, yselect { width:100% }
.max-width
parece dar al elemento un porcentaje del ancho original de su padre , luego no se escala, mientraswidth
que se escala con su padre. Creo que hará lo que quieras (pero podría haber entendido mal). En su violín más complejo, intente asignar a los campos de la columna izquierda un% de ancho y un mínimo de píxeles de ancho. Luego dé los campos a la derecha 100 - (campos de la izquierda -% - ancho)% ancho.Respuestas:
Actualización (25 de septiembre de 2017)
El error de Firefox que se describe a continuación se corrigió a partir de Firefox 53 y el enlace a esta respuesta finalmente se eliminó de la documentación de Bootstrap .
Además, mis sinceras disculpas a los contribuyentes de Mozilla que tuvieron que bloquear la eliminación del soporte en
-moz-document
parte debido a esta respuesta.La solución
En WebKit y Firefox 53+, simplemente configura
min-width: 0;
en el conjunto de campos para anular el valor predeterminado demin-content
.¹Aún así, Firefox es un poco ... extraño cuando se trata de conjuntos de campos. Para que esto funcione en versiones anteriores, debe cambiar la
display
propiedad del conjunto de campos a uno de los siguientes valores:table-cell
(recomendado)table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
De estos, lo recomiendo
table-cell
. Tantotable-row
ytable-row-group
que impiden el cambio de ancho, mientras quetable-column
ytable-column-group
que impiden el cambio de altura.Esto (algo razonablemente) romperá la representación en IE. Como solo Gecko necesita esto, puede usar justificadamente
@-moz-document
—una de las extensiones CSS propietarias de Mozilla— para ocultarlo de otros navegadores:(Aquí hay una demostración de jsFiddle ).
Eso arregla las cosas, pero si eres como yo, tu reacción fue algo así como ...
Qué.
No es una razón, pero no es bastante.
La presentación predeterminada del elemento del conjunto de campos es absurda y esencialmente imposible de especificar en CSS. Piénselo: el borde del conjunto de campos desaparece donde se superpone un elemento de leyenda, ¡pero el fondo permanece visible! No hay forma de reproducir esto con ninguna otra combinación de elementos.
Para colmo, las implementaciones están llenas de concesiones al comportamiento heredado. Una de ellas es que el ancho mínimo de un conjunto de campos nunca es menor que el ancho intrínseco de su contenido. WebKit le ofrece una forma de anular este comportamiento al especificarlo en la hoja de estilo predeterminada, pero Gecko² va un paso más allá y lo aplica en el motor de renderizado .
Sin embargo, los elementos internos de la tabla constituyen un tipo de marco especial en Gecko. Las restricciones dimensionales para elementos con estos
display
valores establecidos se calculan en una ruta de código separada , eludiendo por completo el ancho mínimo impuesto impuesto en los conjuntos de campos.Nuevamente, el error para esto se ha solucionado a partir de Firefox 53, por lo que no necesita este truco si solo se dirige a versiones más nuevas.
¿Está usando
@-moz-document
seguro?Para este problema, sí.
@-moz-document
funciona según lo previsto en todas las versiones de Firefox hasta 53, donde se soluciona este error.Esto no es un accidente. Debido en parte a esta respuesta, el error para limitar
@-moz-document
a las hojas de estilo de usuario / UA se hizo dependiente del error del conjunto de campos subyacente que se solucionó primero.Más allá de esto, no lo use
@-moz-document
para apuntar a Firefox en su CSS , a pesar de otros recursos.³¹ El valor puede estar prefijado. Según un lector, esto no tiene efecto en Android 4.1.2 Stock Browser y posiblemente en otras versiones antiguas; No he tenido tiempo de verificar esto.
² Todos los enlaces a la fuente Gecko en esta respuesta se refieren al conjunto de cambios 5065fdc12408 , comprometido el 29 de julio de 2013; Es posible que desee comparar notas con la revisión más reciente de Mozilla Central .
³ Ver, por ejemplo, SO # 953491: Dirigido solo a Firefox con CSS y CSS Trucos: CSS hacks dirigidos a Firefox para artículos ampliamente referenciados en sitios de alto perfil.
fuente
Problema de Safari en iOS con respuesta seleccionada
La respuesta de Jordan Gray me pareció particularmente útil. Sin embargo, no pareció resolver este problema en Safari iOS para mí.
El problema para mí es simplemente que el conjunto de campos no puede tener un ancho automático si el elemento dentro tiene un ancho máximo como% ancho.
Arreglo para el problema
Simplemente configurar el conjunto de campos para que tenga un ancho del 100% de su contenedor parece solucionar este problema.
Ejemplo
Consulte los siguientes ejemplos de trabajo: si elimina el% de ancho del conjunto de campos o lo reemplaza por automático, no continuará funcionando.
JSFiddle | Codepen
fuente
He luchado durante muchas horas con esto, y básicamente, el navegador está aplicando un estilo computarizado que debes anular en tu CSS. Olvidé la propiedad exacta que se establece en
fieldset
elementos versusdiv
s (min-width
¿ tal vez ?).Mi mejor consejo sería cambiar su elemento a a
div
, copiar los estilos calculados de su inspector, luego volver a cambiar su elementofieldset
y comparar los estilos calculados para encontrar al culpable.Espero que ayude.
Actualización: Agregar
display: table-cell
ayuda en navegadores que no son de Chrome.fuente
fieldset
ydiv
en esta página en Firebug. No sirvió de nada. En Firebug, las únicas propiedades con diferentes valores eranwidth
yperspective-origin
. Elwidth
era numéricamente diferente, pero elfieldset
'swidth
eraauto
, como eldiv
' s. Y estoperspective-origin
es solo una función delwidth
50% de forma predeterminada.min-width: 0;
a mi ejemplo después de probar en Chrome, pero parece que eso resolvió el problema en Chrome. El inspector web me dice que Chrome tiene el estilomin-width: -webkit-min-content;
, tal como lo planteé. Así que ahora solo necesito resolver el problema en Firefox y posiblemente en otros navegadores que aún no he probado..fake-select { white-space:nowrap; }
hizo que el conjunto de campos interpretara el.fake-select
elemento por su ancho original, en lugar de su ancho forzado (incluso cuando el desbordamiento está oculto).Eliminar esa regla, y el cambio
.fake-select
'esmax-width:100%
de solowidth:100%
y se adapta a todo. La advertencia es que ve todo el contenido de la selección falsa, pero no creo que esto sea tan malo, y ahora se ajusta horizontalmente.Actualización: con las reglas actuales en el siguiente violín (que contiene solo selecciones reales), los elementos secundarios del conjunto de campos están restringidos a los anchos correctos. Además de eliminar reglas
.fake-select
y corregir comentarios (de// comment
a/* comment */
, he notado cambios en el CSS del violín.Ahora entiendo mejor su problema, y el violín refleja cierto progreso. Establezco reglas predeterminadas para todos
<select>
los.xxlarge
correos electrónicos , y reservo para aquellos que sabe que serán más anchos que 480px (y esto solo funciona porque conoce el ancho de#viewport
, y puede agregar manualmente la clase a aquellos demasiado anchos. Solo requiere un poco de prueba )Prueba
fuente
<select>
. El sitio real solo tiene<select>
s. El puntofake-select
era tener las reglas de diseño de a<select>
sin ser realmente un<select>
, solo para mostrar que este comportamiento no es un error del navegador que solo ocurre con los<select>
elementos. Por lo tanto, cambiar los estilos de.fake-select
ser menos como una<select>
derrota el propósito..fake-select
caja con un<select>
(idéntico al que ya está presente) para demostrar. Todos los elementos están restringidos al ancho del elemento primario (excepto cuando hace clic en él y despliega las opciones, que se muestran en una sola línea, pero no creo que pueda controlarlo). También eliminé todas las reglas para.fake-select
. ¿El violín actual hace lo que necesita?width: 100%
funciona con los menús largos en la página, pero no funciona bien con menús cortos. Expande los menús cortos al ancho completo de la página, pero quiero que los menús cortos mantengan su ancho corto. Los menús deben ser su ancho natural si hay espacio, pero 100% de ancho si son demasiado grandes para sus padres. Eso es lo quemax-width
se supone que debe hacer, pero no lo hace en este caso.<select>
s" de "largos<select>
s", y ahora solo estoy trabajando en el ancho de fondo.#viewport
tampoco tiene un ancho fijo. Es por eso que puse el botón Cambiar tamaño de ventana gráfica en la página, para que pueda probar que todo funciona sin importar el ancho de la ventana gráfica. Así como.fake-select
es un sustituto de una<select>
prueba real ,#viewport
es un sustituto de una ventana gráfica real. (Una "ventana gráfica" es básicamente una ventana del navegador). Lo incluí#viewport
en la página para que pueda ver fácilmente los elementos que sobresalen de la ventana gráfica, en lugar de tener que desplazarse para verlos.