Problema
Eu tenho um <select>
onde um dos seus <option>
valores de texto é muito longo. Quero que o <select>
redimensione para que nunca seja mais largo que seu pai, mesmo que precise cortar o texto exibido. max-width: 100%
deveria fazer isso.
Antes de redimensionar:
O que eu quero depois de redimensionar:
Mas se você carregar este exemplo jsFiddle e redimensionar a largura do painel Resultado para ser menor que a largura do <select>
, poderá ver que a seleção dentro da <fieldset>
falha ao diminuir sua largura.
O que estou vendo após o redimensionamento:
No entanto, a página equivalente com a em <div>
vez de a<fieldset>
é dimensionada corretamente. Você pode ver isso e testar suas alterações mais facilmente se tiver um <fieldset>
e um <div>
ao lado do outro em uma página . E se você excluir as <fieldset>
tags ao redor , o redimensionamento funcionará. De <fieldset>
alguma forma, a tag está causando o redimensionamento horizontal.
O <fieldset>
ato é como se houvesse uma regra CSS fieldset { min-width: min-content; }
. ( min-content
significa, grosso modo, a menor largura que não causa a transbordamento de uma criança.) Se eu substituir a <fieldset>
com uma <div>
pormin-width: min-content
, ela parecerá exatamente a mesma. No entanto, não há regra min-content
nos meus estilos, na folha de estilo padrão do navegador ou visível no CSS Inspector do Firebug. Tentei substituir todos os estilos visíveis no <fieldset>
CSS Inspector do Firebug e na folha de estilo padrão do Firefox forms.css , mas isso não ajudou. Substituindo especificamente min-width
e width
também não fez nada.
Código
HTML do 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>
Meu CSS que deveria estar funcionando, mas não é:
fieldset {
/* hide fieldset-specific visual features: */
margin: 0;
padding: 0;
border: none;
}
select {
max-width: 100%;
}
Redefinir as width
propriedades para os padrões não faz nada:
fieldset {
width: auto;
min-width: 0;
max-width: none;
}
CSS adicional no qual tento e não consigo corrigir o 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;
}
Mais detalhes
O problema também ocorre neste exemplo mais abrangente e complicado do jsFiddle , que é mais semelhante à página da Web que estou tentando corrigir. Você pode ver que isso <select>
não é o problema - um bloco embutido div
também falha ao redimensionar. Embora este exemplo seja mais complicado, suponho que a correção para o caso simples acima também conserte esse caso mais complicado.
[Editar: veja os detalhes de suporte do navegador abaixo.]
Uma coisa curiosa sobre esse problema é que, se você definirdiv.wrapper { width: 50%; }
, as <fieldset>
paradas <select>
serão redimensionadas no ponto e o tamanho completo atingirá a borda da viewport. O redimensionamento acontece como se <select>
tivesse width: 100%
, mesmo que <select>
pareça width: 50%
.
Se você dar a <select>
si mesmowidth: 50%
, que o comportamento não ocorre; a largura é simplesmente definida corretamente.
Eu não entendo o motivo dessa diferença. Mas isso pode não ser relevante.
Eu também achei a pergunta muito semelhante HTML fieldset permite que as crianças se expandam indefinidamente . O solicitante não conseguiu encontrar uma solução e acha que não há solução além de remover o <fieldset>
. Mas eu estou pensando, se é realmente impossível corrigir a <fieldset>
tela, por que isso? O que, em <fieldset>
's especificação ou padrão CSS ( como desta questão ) faz com que este comportamento? Esse comportamento especial provavelmente está documentado em algum lugar, pois vários navegadores funcionam assim.
Objetivo e requisitos em segundo plano
O motivo pelo qual estou tentando fazer isso é como parte da criação de estilos para dispositivos móveis em uma página existente em formato grande. O formulário possui várias seções, e uma parte dele está envolvida em um <fieldset>
. Em um smartphone (ou se você reduzir a janela do navegador), a parte da página com <fieldset>
é muito maior que o restante do formulário. A maior parte do formulário restringe sua largura, mas a seção com <fieldset>
não, forçando o usuário a diminuir o zoom ou rolar para a direita para ver toda a seção.
Tenho o cuidado de simplesmente remover o <fieldset>
, pois ele é gerado em muitas páginas em um aplicativo grande, e não tenho certeza de quais seletores em CSS ou JavaScript podem depender dele.
Eu posso usar JavaScript se precisar, e uma solução JavaScript é melhor que nada. Mas se o JavaScript é a única maneira de fazer isso, ficaria curioso para ouvir uma explicação sobre por que isso não é possível usando apenas CSS e HTML.
Editar: suporte ao navegador
No site, preciso oferecer suporte ao Internet Explorer 8 e posterior (acabamos de deixar o suporte para o IE7), o Firefox mais recente e o Chrome mais recente. Esta página em particular também deve funcionar em smartphones iOS e Android. O comportamento levemente degradado, mas ainda utilizável, é aceitável para o Internet Explorer 8.
Testei novamente meu fieldset
exemplo quebrado em diferentes navegadores. Na verdade, ele já funciona nesses navegadores:
- Internet Explorer 8, 9 e 10
- cromada
- Chrome para Android
Ele quebra nesses navegadores:
- Raposa de fogo
- Firefox para Android
- Internet Explorer 7
Assim, o único navegador que me interessa é o Firefox (no computador e no celular). Se o código fosse corrigido e funcionasse no Firefox sem quebrá-lo em outros navegadores, isso resolveria o meu problema.
O modelo HTML do site usa comentários condicionais do Internet Explorer para adicionar classes como .ie8
e .oldie
ao <html>
elemento. Você pode usar essas classes em seu CSS se precisar solucionar as diferenças de estilo no IE. As classes adicionadas são as mesmas da versão antiga do HTML5 Boilerplate .
<fieldset>
(oudiv.wrapper
) a largura que for necessária eselect { width:100% }
.max-width
parece fornecer ao elemento uma parte da largura original de seu pai , depois não é dimensionado, enquanto quewidth
é dimensionado com seu pai. Eu acho que vai fazer o que você quer (mas eu poderia ter entendido mal). No seu violino mais complexo, tente dar aos campos da coluna esquerda uma largura de% e uma largura de pixel mínima. Em seguida, forneça os campos à direita 100 - (campos da esquerda -% - largura)% de largura.Respostas:
Atualização (25 de setembro de 2017)
O bug do Firefox descrito abaixo foi corrigido no Firefox 53 e o link para esta resposta foi finalmente removido da documentação do Bootstrap .
Além disso, minhas sinceras desculpas aos colaboradores da Mozilla que tiveram que bloquear a remoção do suporte para
-moz-document
parte devido a esta resposta.O conserto
No WebKit e Firefox 53+, você acabou de definir
min-width: 0;
no fieldset para substituir o valor padrão demin-content
.¹Ainda assim, o Firefox é um pouco ... estranho quando se trata de conjuntos de campos. Para fazer isso funcionar em versões anteriores, você deve alterar a
display
propriedade do conjunto de campos para um dos seguintes valores:table-cell
(recomendado)table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
Destes, eu recomendo
table-cell
. Ambostable-row
etable-row-group
impedi-lo de mudar de largura, enquanto quetable-column
etable-column-group
impedir a alteração de altura.Isso (um tanto razoavelmente) interromperá a renderização no IE. Como apenas o Gecko precisa disso, é possível usar justificadamente
@-moz-document
- uma das extensões CSS proprietárias da Mozilla - para ocultá-lo de outros navegadores:(Aqui está uma demonstração do jsFiddle .)
Isso conserta as coisas, mas se você é como eu, sua reação foi algo como ...
O que.
Não é uma razão, mas não é bonito.
A apresentação padrão do elemento fieldset é absurda e essencialmente impossível de especificar em CSS. Pense bem: a borda do fieldset desaparece onde se sobrepõe a um elemento de legenda, mas o fundo permanece visível! Não há como reproduzir isso com qualquer outra combinação de elementos.
Para completar, as implementações estão cheias de concessões ao comportamento herdado. Uma delas é que a largura mínima de um conjunto de campos nunca é menor que a largura intrínseca de seu conteúdo. O WebKit oferece uma maneira de substituir esse comportamento, especificando-o na folha de estilo padrão, mas o Gecko² vai além e o impõe no mecanismo de renderização .
No entanto, os elementos internos da tabela constituem um tipo de quadro especial no Gecko. Restrições dimensionais para elementos com esses
display
valores definidos são calculadas em um caminho de código separado , contornando completamente a largura mínima imposta imposta aos conjuntos de campos.Novamente - o bug para isso foi corrigido no Firefox 53, então você não precisa desse hack se estiver apenas visando versões mais recentes.
O uso é
@-moz-document
seguro?Para esta questão, sim.
@-moz-document
funciona como planejado em todas as versões do Firefox até 53, onde esse bug foi corrigido.Isso não é acidente. Em parte devido a esta resposta, o bug para limitar
@-moz-document
as folhas de estilo do usuário / UA ficou dependente do bug do fieldset subjacente que foi corrigido primeiro.Além disso, não use
@-moz-document
o Firefox como alvo no seu CSS , apesar de outros recursos.³¹ O valor pode ser prefixado. Segundo um leitor, isso não tem efeito no Android 4.1.2 Stock Browser e possivelmente em outras versões antigas; Não tive tempo de verificar isso.
² Todos os links para a fonte Gecko nesta resposta se referem ao 5065fdc12408 changeset , confirmado em 29 de julho de 2013; você pode comparar as notas com a revisão mais recente do Mozilla Central .
³ Veja, por exemplo, SO # 953491: segmentando apenas o Firefox com CSS e truques CSS: hacks CSS direcionados ao Firefox para artigos amplamente referenciados em sites de alto perfil.
fonte
Problema no Safari no iOS com resposta selecionada
Achei a resposta de Jordan Gray particularmente útil. No entanto, não pareceu resolver esse problema no Safari iOS para mim.
O problema para mim é simplesmente que o fieldset não pode ter uma largura automática se o elemento tiver uma largura máxima como% de largura.
Correção para problema
Simplesmente definir o fieldset para ter uma largura de 100% de seu contêiner parece contornar esse problema.
Exemplo
Consulte o exemplo abaixo para exemplos de trabalho - se você remover a largura% do conjunto de campos ou substituí-lo por automático, ele não continuará funcionando.
JSFiddle | Codepen
fonte
Eu lutei por muitas horas com isso e, basicamente, o navegador está aplicando um estilo computado que você precisa substituir no seu CSS. Eu esqueço a propriedade exata que está sendo definida nos
fieldset
elementos versusdiv
s (talvezmin-width
?).Meu melhor conselho seria alterar seu elemento para a
div
, copiar os estilos computados do seu inspetor e, em seguida, alterar seu elemento novamentefieldset
e comparar os estilos computados para encontrar o culpado.Espero que ajude.
Atualização: a adição de
display: table-cell
ajuda em navegadores não Chrome.fonte
fieldset
ediv
sobre esta página no Firebug. Isso não ajudou. No Firebug, as únicas propriedades com valores diferentes eramwidth
eperspective-origin
. Owidth
foi numericamente diferentes, mas osfieldset
'swidth
eraauto
, como osdiv
' s. E operspective-origin
é apenas uma função doswidth
- 50% dele por padrão.min-width: 0;
meu exemplo depois de testar no Chrome, mas parece que isso resolveu o problema no Chrome. O Web Inspector me diz que o Chrome tem o estilomin-width: -webkit-min-content;
, como eu imaginei. Então agora só preciso resolver o problema no Firefox e possivelmente em outros navegadores em que ainda não testei..fake-select { white-space:nowrap; }
fez com que o fieldset interpretasse o.fake-select
elemento pela largura original, e não pela largura forçada (mesmo quando o estouro está oculto).Retirar essa regra, e mudança
.fake-select
émax-width:100%
para apenaswidth:100%
e fits tudo. A ressalva é que você vê todo o conteúdo do falso-select, mas não acho que isso seja tão ruim e se encaixa horizontalmente agora.Atualização: com as regras atuais no violino a seguir (que contém apenas seleções reais), os filhos do fieldset são restritos a corrigir larguras. Além de remover regras
.fake-select
e corrigir comentários (de// comment
para/* comment */
, observei alterações no CSS do violino.Compreendo melhor o seu problema agora, e o violino reflete algum progresso. Eu defino regras padrão para todos os se
<select>
reservo.xxlarge
para aqueles que você sabe que terão mais de 480px (e isso só funciona porque você conhece a largura de#viewport
, e pode adicionar manualmente a classe àqueles muito grandes. Requer apenas um pouco de teste )Prova
fonte
<select>
. O site atual possui apenas<select>
s. O objetivofake-select
era ter as regras de layout de a<select>
sem realmente ser a<select>
, apenas para mostrar que esse comportamento não é um bug do navegador que acontece apenas com<select>
elementos. Então, mudar os estilos de.fake-select
ser menos parecido com um<select>
derrota o objetivo..fake-select
caixa por uma<select>
(idêntica à que já está presente) para demonstrar. Os elementos estão todos restritos à largura do pai (exceto quando você clica nele, suspensa as opções, que são exibidas em uma única linha - mas acho que você não pode controlar isso). Também removi todas as regras para.fake-select
. O violino atual faz o que você precisa?width: 100%
funciona com os menus longos da página, mas não funciona corretamente com menus curtos. Ele expande menus curtos para toda a largura da página, mas eu quero que menus curtos mantenham sua largura curta. Os menus devem ter a largura natural, se houver espaço, mas 100% de largura, se forem grandes demais para os pais. Isso é o quemax-width
deveria fazer, mas não o faz neste caso.<select>
s" de "long<select>
s" e agora trabalhando apenas na largura do plano de fundo.#viewport
também não possui uma largura fixa. É por isso que eu coloquei o botão Redimensionar viewport na página - para que você possa testar se tudo funciona, independentemente da largura da viewport. Assim como.fake-select
é um substituto para um real<select>
para testes,#viewport
é um substituto para uma viewport real. (Uma "janela de visualização" é basicamente uma janela do navegador). Incluí#viewport
na página para que você pudesse ver facilmente os elementos que ficam fora da janela de visualização, em vez de precisar rolar para vê-los.