Problem
Mam <select>
gdzie jedna z jego <option>
wartości tekstowych jest bardzo długa. Chcę <select>
zmienić rozmiar, aby nigdy nie był szerszy niż element nadrzędny, nawet jeśli musi odciąć wyświetlany tekst. max-width: 100%
powinien to zrobić.
Przed zmianą rozmiaru:
Co chcę po zmianie rozmiaru:
Ale jeśli załadujesz ten przykład jsFiddle i zmienisz szerokość panelu Wynik na mniejszą niż szerokość <select>
, możesz zobaczyć, że zaznaczenie wewnątrz <fieldset>
nie przeskalowuje jego szerokości w dół.
Co właściwie widzę po zmianie rozmiaru:
Jednak odpowiednik strony z <div>
zamiast zamiast<fieldset>
nie skaluje się poprawnie. Możesz to zobaczyć i przetestować zmiany łatwiej, jeśli masz jeden <fieldset>
i jeden <div>
obok siebie na jednej stronie . A jeśli usuniesz otaczające <fieldset>
tagi , zmiana rozmiaru będzie działać. <fieldset>
Znacznik jest w jakiś sposób powoduje poziome skalowanie do złamania.
Te <fieldset>
akty jakby istnieje reguła CSS fieldset { min-width: min-content; }
. ( min-content
Środki, z grubsza, najmniejsza szerokość, która nie powoduje dziecka do przelewu). Jeśli mogę wymienić <fieldset>
z <div>
omin-width: min-content
, wygląda dokładnie tak samo. Jednak min-content
w moich stylach, w domyślnym arkuszu stylów przeglądarki lub w Inspektorze CSS Firebug nie ma żadnej reguły . Próbowałem zastąpić każdy styl widoczny <fieldset>
w Inspektorze CSS Firebuga i domyślnym arkuszu stylów forms.css Firefoksa , ale to nie pomogło. Szczególnie nadpisujące min-width
i też width
nic nie zrobiły.
Kod
HTML zestawu pól:
<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>
Mój CSS, który powinien działać, ale nie jest:
fieldset {
/* hide fieldset-specific visual features: */
margin: 0;
padding: 0;
border: none;
}
select {
max-width: 100%;
}
Resetowanie width
właściwości do wartości domyślnych nic nie robi:
fieldset {
width: auto;
min-width: 0;
max-width: none;
}
Dalszy CSS, w którym próbuję rozwiązać problem :
/* 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;
}
Więcej szczegółów
Problem występuje również w tym bardziej kompleksowym, bardziej skomplikowanym przykładzie jsFiddle , który jest bardziej podobny do strony internetowej, którą próbuję naprawić. Widać z tego, że <select>
to nie jest problem - blok wbudowany div
również nie zmienia rozmiaru. Chociaż ten przykład jest bardziej skomplikowany, zakładam, że poprawka do powyższego prostego przypadku również naprawi ten bardziej skomplikowany przypadek.
[Edycja: zobacz szczegóły wsparcia przeglądarki poniżej.]
Ciekawą rzeczą w tym problemie jest to, że jeśli ustawiszdiv.wrapper { width: 50%; }
, <fieldset>
zatrzyma się zmiana rozmiaru w punkcie, a następnie pełny rozmiar <select>
uderzy o krawędź rzutni. Zmiana rozmiaru odbywa się tak, jakby <select>
miała width: 100%
, mimo że <select>
wygląda tak width: 50%
.
Jeśli dasz z <select>
siebiewidth: 50%
, takie zachowanie nie występuje; szerokość jest po prostu poprawnie ustawiona.
Nie rozumiem przyczyny tej różnicy. Ale to może nie mieć znaczenia.
Znalazłem również bardzo podobne pytanie zestaw pól HTML pozwala dzieciom rozwijać się w nieskończoność . Pytający nie mógł znaleźć rozwiązania i zgaduje, że nie ma innego rozwiązania oprócz usunięcia <fieldset>
. Ale zastanawiam się, czy naprawdę nie jest możliwe <fieldset>
poprawne wyświetlanie, dlaczego? Co w <fieldset>
„s specyfikacji lub domyślnego CSS ( w tej kwestii ) powoduje takie zachowanie? To specjalne zachowanie jest prawdopodobnie gdzieś udokumentowane, ponieważ wiele przeglądarek działa w ten sposób.
Cel i wymagania w tle
Powodem, dla którego próbuję to zrobić, jest pisanie stylów mobilnych dla istniejącej strony o dużej formie. Formularz ma wiele sekcji, a jedna jego część jest owinięta w <fieldset>
. Na smartfonie (lub jeśli okno przeglądarki jest małe) część strony z rozszerzeniem <fieldset>
jest znacznie szersza niż reszta formularza. Większość postaci ogranicza swoją szerokość, ale sekcja z <fieldset>
nie, co zmusza użytkownika do pomniejszenia lub przewinięcia w prawo, aby zobaczyć całą tę sekcję.
Obawiam się po prostu usunąć <fieldset>
, ponieważ jest generowany na wielu stronach w dużej aplikacji, i nie jestem pewien, od czego mogą zależeć selektory w CSS lub JavaScript.
W razie potrzeby mogę używać JavaScript, a rozwiązanie JavaScript jest lepsze niż nic. Ale jeśli JavaScript jest jedynym sposobem, aby to zrobić, byłbym ciekawy wyjaśnienia, dlaczego nie jest to możliwe przy użyciu tylko CSS i HTML.
Edycja: obsługa przeglądarki
Na stronie muszę obsługiwać Internet Explorera 8 i nowsze (właśnie zrezygnowaliśmy z obsługi IE7), najnowszego Firefoksa i najnowszego Chrome. Ta konkretna strona powinna również działać na smartfonach z systemem iOS i Android. Nieco obniżone, ale nadal użyteczne zachowanie jest dopuszczalne w Internet Explorerze 8.
Ponownie przetestowałem mój zepsuty fieldset
przykład w różnych przeglądarkach. W rzeczywistości działa już w tych przeglądarkach:
- Internet Explorer 8, 9 i 10
- Chrom
- Chrome na Androida
Uszkadza się w tych przeglądarkach:
- Firefox
- Firefox na Androida
- Internet Explorer 7
Tak więc jedyną przeglądarką, na której mi zależy, że obecny kod się włamuje, jest Firefox (zarówno na komputerze, jak i telefonie komórkowym). Jeśli kod zostałby naprawiony, aby działał w przeglądarce Firefox bez uszkodzenia go w innych przeglądarkach, rozwiązałoby to mój problem.
Szablon strona HTML używa Internet Explorer warunkowe komentarze dodać takie zajęcia .ie8
i .oldie
do <html>
elementu. Możesz użyć tych klas w swoim CSS, jeśli chcesz obejść różnice stylów w IE. Dodane klasy są takie same jak w starej wersji HTML5 Boilerplate .
<fieldset>
(lubdiv.wrapper
) dowolną potrzebną szerokość orazselect { width:100% }
.max-width
wydaje się dawać elementowi pewną% pierwotnej szerokości elementu nadrzędnego , a następnie nie jest skalowany, podczaswidth
gdy skaluje się z rodzicem. Myślę, że zrobi to, co chcesz (ale mogłem źle zrozumieć). W bardziej złożonym skrzypciu spróbuj nadać polom w lewej kolumnie% szerokości i szerokość min. Piksela. Następnie podaj pola po prawej stronie 100 - (lewe pola -% - szerokość)% szerokości.Odpowiedzi:
Aktualizacja (25 września 2017 r.)
Firefox bug opisany poniżej jest ustalana jako Firefoksa 53 i link do tej odpowiedzi został ostatecznie usunięty z dokumentacją Bootstrap za .
Również moje szczere przeprosiny dla twórców Mozilli, którzy musieli
-moz-document
częściowo zablokować usuwanie wsparcia z powodu tej odpowiedzi.Poprawka
W WebKit i Firefox 53+ po prostu ustawiłeś zestaw
min-width: 0;
pól, aby zastąpić domyślną wartośćmin-content
.¹Mimo to Firefox jest trochę… dziwny, jeśli chodzi o zestawy terenowe. Aby działało to we wcześniejszych wersjach, należy zmienić
display
właściwość zestawu pól na jedną z następujących wartości:table-cell
(Zalecana)table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
Spośród nich polecam
table-cell
. Zarównotable-row
itable-row-group
uniemożliwić zmianę szerokości, podczas gdytable-column
itable-column-group
uniemożliwić zmianę wysokości.Spowoduje to (w pewnym sensie) przerwanie renderowania w IE. Ponieważ tylko Gecko tego potrzebuje, możesz w uzasadniony sposób użyć
@-moz-document
jednego z zastrzeżonych rozszerzeń CSS Mozilli, aby ukryć go przed innymi przeglądarkami:(Oto demo jsFiddle .)
To naprawia rzeczy, ale jeśli jesteś podobny do mnie, twoja reakcja była jak…
Co.
Tam jest to powód, ale nie całkiem.
Domyślna prezentacja elementu zestawu pól jest absurdalna i zasadniczo niemożliwa do określenia w CSS. Pomyśl o tym: granica zestawu pól znika, gdy nakłada się na niego element legendy, ale tło pozostaje widoczne! Nie da się tego odtworzyć za pomocą żadnej innej kombinacji elementów.
Reasumując, implementacje są pełne ustępstw wobec starszych zachowań. Jednym z nich jest to, że minimalna szerokość zestawu pól nigdy nie jest mniejsza niż wewnętrzna szerokość jego zawartości. WebKit umożliwia obejście tego zachowania poprzez określenie go w domyślnym arkuszu stylów, ale Gecko² idzie o krok dalej i wymusza to w silniku renderowania .
Jednak wewnętrzne elementy stołu stanowią w Gecko specjalny rodzaj ramy . Ograniczenia wymiarowe dla elementów z
display
ustawionymi wartościami są obliczane w osobnej ścieżce kodu , całkowicie omijając wymuszoną minimalną szerokość nałożoną na zestawy pól.Znowu - błąd został naprawiony w Firefoksie 53, więc nie potrzebujesz tego hacka, jeśli atakujesz tylko nowsze wersje.
Czy używanie jest
@-moz-document
bezpieczne?W przypadku tego jednego problemu tak.
@-moz-document
działa zgodnie z przeznaczeniem we wszystkich wersjach Firefoksa do 53, w których ten błąd został naprawiony.To nie jest przypadek. Częściowo z powodu tej odpowiedzi błąd polegający na ograniczeniu się
@-moz-document
do arkuszy stylów użytkownika / UA został uzależniony od tego, czy najpierw naprawiony zostanie podstawowy błąd zestawu pól.Poza tym nie używaj
@-moz-document
do kierowania Firefoksa w CSS , niezależnie od innych zasobów .³¹ Wartość może być przedrostkiem. Według jednego z czytelników nie ma to wpływu na przeglądarkę zapasową Androida 4.1.2 i prawdopodobnie na inne stare wersje; Nie miałem czasu tego zweryfikować.
² Wszystkie linki do źródła Gecko w tej odpowiedzi odnoszą się do zestawu zmian 5065fdc12408 , zatwierdzonego 29ᵗʰ lipca 2013 r .; możesz porównać notatki z najnowszą wersją Mozilla Central .
³ Patrz np. SO # 953491: Skierowanie tylko do Firefoksa za pomocą CSS i sztuczek CSS: hacki CSS atakujące Firefoksa w przypadku artykułów, do których często się odwołuje, na popularnych stronach.
źródło
Problem z Safari na iOS z wybraną odpowiedzią
Odpowiedź Jordana Graya była szczególnie pomocna. Wydaje mi się jednak, że nie rozwiązało to problemu w Safari iOS.
Problemem jest dla mnie po prostu to, że zestaw pól nie może mieć automatycznej szerokości, jeśli element wewnątrz ma maksymalną szerokość jako% szerokości.
Napraw problem
Wydaje się, że po prostu ustawienie zestawu pól tak, aby miał kontener o 100% szerokości, pozwala obejść ten problem.
Przykład
Przykłady robocze znajdują się poniżej - jeśli usuniesz% szerokości z zestawu pól lub zastąpisz go auto, przestanie on działać.
JSFiddle | Codepen
źródło
Walczyłem z tym przez wiele godzin i zasadniczo przeglądarka stosuje styl komputerowy, który należy zastąpić w CSS. Zapominam dokładną właściwość ustawianą dla
fieldset
elementów w porównaniu dodiv
s (być możemin-width
?).Moja najlepsza rada to zmienić element na a
div
, skopiować obliczone style z inspektora, a następnie zmienić element z powrotem nafieldset
i porównaj obliczone style, aby znaleźć winowajcę.Mam nadzieję, że to pomaga.
Aktualizacja: dodawanie
display: table-cell
pomaga w przeglądarkach innych niż Chrome.źródło
fieldset
idiv
na tej stronie w Firebug. To nie pomogło. W Firebug jedynymi właściwościami o różnych wartościach byływidth
iperspective-origin
.width
Liczbowo była inna, alefieldset
„swidth
byłoauto
, podobnie jakdiv
” s. Iperspective-origin
jest to tylko funkcjawidth
- 50% z tego domyślnie.min-width: 0;
do mojego przykładu po przetestowaniu w Chrome, ale wygląda na to, że to rozwiązało problem w Chrome. Inspektor internetowy mówi mi, że Chrome ma stylmin-width: -webkit-min-content;
, tak jak to przypuszczałem. Teraz muszę tylko rozwiązać problem w przeglądarce Firefox i prawdopodobnie w innych przeglądarkach, w których jeszcze nie testowałem..fake-select { white-space:nowrap; }
spowodowało, że zestaw pól zinterpretował.fake-select
element na podstawie jego pierwotnej szerokości, a nie jego wymuszonej szerokości (nawet gdy przelew jest ukryty).Usunąć tę regułę, a zmiana
.fake-select
„smax-width:100%
do zaledwiewidth:100%
i wszystko pasuje. Zastrzeżenie polega na tym, że widzisz całą zawartość fałszywego wyboru, ale nie sądzę, że jest tak źle, i teraz pasuje poziomo.Aktualizacja: przy obecnych regułach w następującym skrzypcach (które zawierają tylko rzeczywiste selekcje), dzieci zestawu pól są ograniczone do poprawiania szerokości. Oprócz usuwania reguł
.fake-select
i poprawiania komentarzy (od// comment
do/* comment */
, zauważyłem zmiany w CSS skrzypce.Teraz rozumiem twój problem, a skrzypce odzwierciedlają pewne postępy. Ustawiam domyślne reguły dla wszystkich
<select>
s i rezerwuję.xxlarge
dla tych, o których wiesz, że będą szersze niż 480px (i działa to tylko dlatego, że znasz szerokość#viewport
i możesz ręcznie dodać klasę do tych zbyt szerokich. Wystarczy trochę przetestować )Dowód
źródło
<select>
. Rzeczywista strona ma tylko<select>
s. Chodziło ofake-select
to, aby reguły układu<select>
nie były w rzeczywistości<select>
, aby pokazać, że to zachowanie nie jest błędem przeglądarki, który zdarza się tylko z<select>
elementami. Zmiana stylu.fake-select
na mniejszą niż<select>
pokonanie celu..fake-select
pudełko na<select>
(identyczne z tym już obecnym), aby zademonstrować. Wszystkie elementy są ograniczone do szerokości elementu nadrzędnego (z wyjątkiem kliknięcia na nim, rozwijania opcji, które są wyświetlane w jednym wierszu - ale nie sądzę, że można to kontrolować). Usunąłem również wszystkie reguły dotyczące.fake-select
. Czy obecne skrzypce robi to, czego potrzebujesz?width: 100%
działa z długimi menu na stronie, ale nie działa poprawnie z krótkimi menu. Rozszerza krótkie menu do pełnej szerokości strony, ale chcę, aby krótkie menu zachowywały swoją krótką szerokość. Menu powinno mieć naturalną szerokość, jeśli jest miejsce, ale 100% szerokości, jeśli są zbyt duże dla rodzica. To właśniemax-width
należy zrobić, ale nie zrobić w tym przypadku.<select>
s” od „długich<select>
s” i pracuję teraz na szerokości tła.#viewport
nie ma również stałej szerokości. Dlatego umieściłem przycisk Zmień rozmiar rzutni na stronie - abyś mógł sprawdzić, czy wszystko działa bez względu na szerokość rzutni. Podobnie jak.fake-select
substytut prawdziwego<select>
testowania, tak samo jak#viewport
substytut prawdziwej rzutni. („Rzutnia” to w zasadzie okno przeglądarki). Umieściłem#viewport
na stronie, aby można było łatwo zobaczyć elementy wystające z okienka, zamiast przewijania, aby je zobaczyć.