<alan> yanlış boyutlandırır; kaldırılamaz "min-width: min-content`


221

Sorun

Ben <select>burada onun <option>metin değerlerinden biri çok uzun. <select>Görüntülenen metnini kesmek zorunda olsa bile yeniden boyutlandırılmasını istiyorum . max-width: 100%bunu yapmalı.

Yeniden boyutlandırmadan önce:

yeniden boyutlandırmadan önceki sayfa, tüm <code> select </code>

Yeniden boyutlandırdıktan sonra ne istiyorum:

yeniden boyutlandırdıktan sonra istediğim sayfa, <code> select </code> içeriğini kırparak

Ancak bu jsFiddle örneğini yüklerseniz ve Sonuç panelinin genişliğinden daha küçük olacak şekilde yeniden boyutlandırırsanız, içindeki seçimin genişliğini küçültemediğini<select> görebilirsiniz <fieldset>.

Yeniden boyutlandırdıktan sonra gerçekte gördüğüm şey:

yeniden boyutlandırdıktan sonra kaydırma çubuğuyla geçerli sayfam

Ancak, do <div>yerine eşdeğer sayfa<fieldset> düzgün ölçeklenir. Bunu görebilir ve daha kolay değişiklikleri test varsa bir <fieldset>ve bir <div>tek sayfada yan yana . Ve çevresindeki <fieldset>etiketleri silerseniz , yeniden boyutlandırma çalışır. <fieldset>Etiket nasılsa yatay yeniden boyutlandırma kırmaya neden oluyor.

Gerçekler <fieldset>sanki bir CSS kuralı varmış gibi fieldset { min-width: min-content; }. ( min-contentVasıta, kabaca, en küçük genişlik taşma için bir çocuk yol açmadığını.) Ben değiştirin <fieldset>bir ile <div>birliktemin-width: min-content , tam olarak aynı görünüyor. Yine min-contentde stillerimde, tarayıcı varsayılan stil sayfasında veya Firebug'un CSS İnceleyicisinde görünen bir kural yok . <fieldset>Firebug'un CSS Inspector'ında ve Firefox'un varsayılan stil sayfası forms.css'de görünen her stili geçersiz kılmaya çalıştım , ancak bu yardımcı olmadı. Özellikle geçersiz kılma min-widthve widthhiçbir şey yapmadı.

kod

Alan kümesinin HTML'si:

<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>

Çalışması gereken ancak olmayan CSS'm:

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

select {
    max-width: 100%;
}

widthÖzelliklerin varsayılanlara sıfırlanması hiçbir şey yapmaz:

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

Hangi CSS hangi denemek ve sorunu çözmek için başarısız :

/* 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;
}

Daha fazla detay

Sorun , aslında düzeltmeye çalıştığım web sayfasına daha benzer olan bu daha kapsamlı, daha karmaşık jsFiddle örneğinde de ortaya çıkıyor . <select>Sorunun bu olmadığını görebilirsiniz - bir satır içi blok divda yeniden boyutlandırılamaz. Bu örnek daha karmaşık olsa da, yukarıdaki basit durum için düzeltmenin de bu daha karmaşık durumu düzelteceğini varsayalım.

[Düzenle: aşağıdaki tarayıcı desteği ayrıntılarına bakın.]

Bu sorunla ilgili ilginç bir şey, belirlersenizdiv.wrapper { width: 50%; } , <fieldset>noktada yeniden boyutlandırılan durakların tam boyutun <select>görünüm penceresinin kenarına çarpmasıdır. Yeniden boyutlandırma, <select>sahip gibi görünüyor width: 100%olsa da, <select>sahip gibi olur width: 50%.

% 50 genişlik sarıcı div ile yeniden boyutlandırdıktan sonra

Eğer varsa vermek <select>kendisiwidth: 50% bu davranış oluşmaz; genişlik basit bir şekilde ayarlanmıştır.

% 50 genişlik seçimi ile yeniden boyutlandırdıktan sonra

Bu farkın nedenini anlamıyorum. Ancak konuyla ilgili olmayabilir.

HTML alan kümesinin çocukların süresiz olarak genişlemesini sağlayan çok benzer bir soru da buldum . Asker bir çözüm bulamadı ve bu çözümü kaldırmak dışında bir çözüm olmadığını tahmin ediyor<fieldset> . Ama merak ediyorum, eğer <fieldset>ekranı doğru yapmak gerçekten imkansızsa , neden böyle? Ne <fieldset>bireyin Spec veya varsayılan CSS ( Bu sorunun itibariyle ) bu davranışı neden olur? Bu özel davranış muhtemelen bir yerde belgelenmiştir, çünkü birden fazla tarayıcı bu şekilde çalışır.

Arka plan hedefi ve gereksinimleri

Bunu yapmaya çalışmamın nedeni, büyük bir forma sahip mevcut bir sayfa için mobil stiller yazmanın bir parçası. Formun birden çok bölümü vardır ve bir bölümü a <fieldset>. Bir akıllı telefonda (veya tarayıcı pencerenizi küçük yaparsanız) sayfanın bir kısmı <fieldset>formun geri kalanından çok daha geniştir. Formun çoğu genişliğini iyi sınırlar, ancak ile olan bölüm <fieldset>, kullanıcıyı bu bölümü görmek için uzaklaştırmaya veya sağa kaydırmaya zorlamaz.

<fieldset>Büyük bir uygulamadaki birçok sayfada oluşturulduğu için basitçe kaldırmaya dikkat ediyorum ve CSS veya JavaScript'teki hangi seçicilerin buna bağlı olabileceğinden emin değilim.

Gerekirse JavaScript kullanabilirim ve bir JavaScript çözümü hiç yoktan iyidir. Ancak JavaScript bunu yapmanın tek yolu ise, bunun neden sadece CSS ve HTML kullanarak mümkün olmadığını açıklayan bir açıklama duymak isterim.


Düzenle: tarayıcı desteği

Sitede, Internet Explorer 8 ve sonraki sürümlerini (IE7 desteğini yeni bıraktık), en yeni Firefox'u ve en son Chrome'u desteklemem gerekiyor. Bu belirli sayfa iOS ve Android akıllı telefonlarda da çalışmalıdır. Internet Explorer 8 için biraz bozulmuş ancak yine de kullanılabilir davranış kabul edilebilir.

Kırık fieldsetörneğimi farklı tarayıcılarda yeniden test ettim . Aslında bu tarayıcılarda zaten çalışıyor:

  • Internet Explorer 8, 9 ve 10
  • Krom
  • Android için Chrome

Bu tarayıcılarda kırılıyor:

  • Firefox
  • Android için Firefox
  • Internet Explorer 7

Bu nedenle, geçerli kodun kırıldığı umurumdaki tek tarayıcı Firefox'tur (hem masaüstü hem de mobil cihazlarda). Kod, başka bir tarayıcıda kırılmadan Firefox'ta çalıştı, bu yüzden sorunumu çözecekti.

Site HTML şablonu tür sınıfları eklemek için Internet Explorer koşullu yorum kullanır .ie8ve .oldiehiç <html>eleman. IE'de stil farkları üzerinde çalışmanız gerekiyorsa bu sınıfları CSS'nizde kullanabilirsiniz. Eklenen sınıflar , HTML5 Boilerplate'in bu eski sürümü ile aynıdır .


41
Bu mükemmel yazıya tebrikler
Alp

Basit örneğiniz: İhtiyaç duyduğu genişliği verin <fieldset>(veya div.wrapper) ve select { width:100% }. max-widthöğeye üst öğesinin orijinal genişliğinin % bir kısmını veriyor gibi görünür , ardından ölçeklenmez, üst öğeyle widthbirlikte ölçeklenir. Bunun istediğini yapacağını düşünüyorum (ama yanlış anlayabilirdim). Daha karmaşık kemanınızda, sol sütundaki alanlara% genişlik ve minimum piksel genişliği vermeyi deneyin. Ardından sağdaki alanları% 100 - (sol alanlar -% - genişlik)% genişliğine verin.
Truva

Başka bir düşüncem vardı: ya alan kümesinin min-genişliğini 0 olarak ayarlarsanız? Bu muhtemelen tek başına sorunu çözmeyecek, ama muhtemelen çözmeye çalışmaya değer. Şimdi farklı bir yol üzerinde çalışıyorum, ancak işe yaramazsa ben de deneyeceğim
Trojan

Aynı hatta kalmak için etikete ve alana mı ihtiyacınız var? Küçük görünüm alanları için üst üste binerler. Neden biraz yanıt vermiyor ve gerekirse yeni bir çizgiye geçmiyorsunuz?
Truva

Yanıtlar:


346

Güncelleme (25 Eylül 2017)

Firefox hata aşağıda açıklanan Firefox 53 itibariyle sabittir ve bu cevaba linki nihayet olmuştur Bootstrap belgelerine kaldırıldı .

Ayrıca, -moz-documentbu cevap nedeniyle kısmen desteğin kaldırılmasını engellemek zorunda kalan Mozilla katılımcılarına özür dilerim .

Çözüm

WebKit ve Firefox 53+ sürümlerinde, min-width: 0;alan kümesinde varsayılan değeri geçersiz kılacak şekilde min-contentayarladınız.

Yine de, alan kümeleri söz konusu olduğunda Firefox biraz… tuhaf. Bunun önceki sürümlerde çalışmasını sağlamak için display, alan kümesinin özelliğini aşağıdaki değerlerden biriyle değiştirmeniz gerekir :

  • table-cell (önerilen)
  • table-column
  • table-column-group
  • table-footer-group
  • table-header-group
  • table-row
  • table-row-group

Bunlardan tavsiye ederimtable-cell . Hem table-rowve table-row-groupgenişliğini değiştirerek engel iken table-columnve table-column-groupsen yüksekliğini değiştirmesini engeller.

Bu (biraz makul) IE'de render kırmak olacaktır. Sadece Gecko buna ihtiyacı olduğundan, haklı kullanabilirsiniz @-moz-documentait -on Mozilla'nın tescilli CSS uzantıları diğer tarayıcılar gizlemek Yapılır:

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

(İşte bir jsFiddle demosu .)


Bu işleri düzeltir, ama eğer benim gibi bir şeysen, tepkin şöyleydi ...

Ne.

Orada olan bir sebep, ama oldukça değil.

Alan kümesi öğesinin varsayılan sunumu saçmadır ve CSS'de belirtilmesi neredeyse imkansızdır. Bir düşünün: alan kümesinin kenarlığı, bir efsane öğeyle çakıştığı yerde kaybolur, ancak arka plan görünür kalır! Bunu başka herhangi bir element kombinasyonu ile çoğaltmanın bir yolu yoktur.

Üstelik, uygulamalar eski davranışlara verilen tavizlerle doludur. Böyle bir durum, bir alan kümesinin minimum genişliğinin içeriğinin gerçek genişliğinden asla daha az olmamasıdır. WebKit, varsayılan stil sayfasında belirterek bu davranışı geçersiz kılmanın bir yolunu sunar, ancak Gecko² bir adım daha ileri gider ve oluşturma motorunda uygular .

Ancak, iç tablo öğeleri Gecko'da özel bir çerçeve türü oluşturur . Bu displaydeğer kümesine sahip elemanlar için boyutsal kısıtlamalar , alan kümelerine uygulanan zorunlu minimum genişliği tamamen atlayarak ayrı bir kod yolunda hesaplanır .

Yine — bunun için hata Firefox 53'ten itibaren düzeltildi, bu yüzden sadece daha yeni sürümleri hedefliyorsanız bu saldırıya ihtiyacınız yok.

@-moz-documentGüvenli mi kullanıyorsunuz ?

Bu bir sorun için, evet. @-moz-documentbu hatanın giderildiği 53'e kadar tüm Firefox sürümlerinde amaçlandığı gibi çalışır.

Bu bir tesadüf değil. Bu cevabın bir kısmı nedeniyle, kullanıcı / UA stil sayfalarıyla sınırlandırılacak@-moz-document hata, öncelikle düzeltilen temel alan kümesi hatasına bağlı olarak yapıldı.

Bunun ötesinde , diğer kaynaklara bakılmaksızın, CSS'nizdeki Firefox'u hedeflemek için kullanmayın.³@-moz-document


¹ Değer ön ekli olabilir. Bir okuyucuya göre, bunun Android 4.1.2 Stok Tarayıcı ve muhtemelen diğer eski sürümlerde hiçbir etkisi yoktur; Bunu doğrulamak için zamanım olmadı.

² Bu yanıttaki Gecko kaynağına yapılan tüm bağlantılar , 29ᵗʰ Temmuz 2013'te taahhüt edilen 5065fdc12408 değişiklik kümesiyle ilgilidir; notları Mozilla Central'ın en son revizyonu ile karşılaştırmak isteyebilirsiniz .

³ Bkz. Örneğin SO # 953491: Yalnızca CSS ve CSS Hileleriyle Firefox'u Hedefleme : CSS , yüksek profilli sitelerde yaygın olarak başvurulan makaleler için Firefox'u hedefliyor .


5
Düzeltmenin IE'de kırıldığını fark ettim, sadece buraya gelip çözümde zaten düzenlediğinizi öğrenmek için. Teşekkürler! Gecko kesmek çözümü her tarayıcıda benim için iyi çalışıyor.
Rory O'Kane

Bu konuda saçlarımı çekiyordum, ancak düzeltmeniz mükemmel - sadece firefox'ta çalışıyor gibi görünüyor. Diğer tarayıcılar, özellikle mobil tarayıcılar için herhangi bir öneriniz var mı? En büyük sorunum, mobil cihazlardaki oryantasyon değişikliği nedeniyle yeniden boyutlandırılıyor ...
Adriaan Nel

30
Bu kesinlikle mükemmel bir cevap - kapsamlı, araştırılmış ve özlü. Teşekkürler.
iamkeir

16
Tabii ki kesinlikle mükemmel bir cevap! Bootstrap resmi dokümantasyon burada noktaları
Ranhiru Jude Cooray

1
Saha setlerini hiç bilmiyordum. Bugün burada bir şey öğrendim.
superluminary

11

Seçilen yanıtla iOS'ta Safari sorunu

Jordan Gray'in cevabını özellikle yararlı buldum. Ancak Safari iOS'ta bu sorunu benim için çözmedim.

Benim için sorun, alandaki öğenin% genişlik olarak maksimum genişliğe sahip olması durumunda alan kümesinin otomatik genişliğe sahip olamamasıdır.

Sorun düzeltildi

Yalnızca alan kümesini, kabının% 100 genişliğine sahip olacak şekilde ayarlamak bu sorunun üstesinden gelmek gibi görünüyor.

Misal

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

Çalışma örnekleri için lütfen aşağıya bakın - alan kümesindeki% genişliğini kaldırır veya otomatik ile değiştirirseniz, çalışmaya devam etmez.

JSFiddle | Codepen


1
Bu genel soruna harika bir ektir, iOS'ta test etmeyi düşünmedim. :) Bunun yeni bir soru olarak sormaya ve kendi kendine yanıtlamaya değeceğini düşünüyorum. Bu hafta fazladan test yapmaya çalışacağım ve işe yaradığında bu cevaba bağlantı vereceğim.
Jordan Gray

3

Bununla saatlerce uğraştım ve temel olarak tarayıcı, CSS'nizde geçersiz kılmanız gereken bilgisayarlı stil uyguluyor. Ben s (belki de ?) fieldsetKarşı öğeler üzerinde ayarlanan tam özelliğini unutmak .divmin-width

En iyi tavsiyem, öğenizi a olarak değiştirmek div, hesaplanan stilleri denetçinizden kopyalamak, sonra öğenizi geri değiştirmek fieldsetve suçluyu bulmak için hesaplanan stilleri karşılaştırmak olacaktır.

Umarım yardımcı olur.

Güncelleme: Ekleme display: table-cell, Chrome dışı tarayıcılarda yardımcı olur.


Ben her CSS özelliğini karşılaştırıldı fieldsetve divüzerinde bu sayfayı Firebug. Yardım etmedi. Firebug'da, farklı değerlere sahip tek özellikler widthve idi perspective-origin. widthSayısal olarak farklı, ama fieldset'ın widtholdu autogibi divs'. Ve bu perspective-originsadece widthvarsayılan olarak -% 50'sinin bir fonksiyonudur .
Rory O'Kane

Ancak, karşılaştırma Chrome Web Inspector'da bir şekilde yardımcı oldu. Örneğimi açtıktan hemen sonra Chrome'da çalıştığını öğrendim ! Ben ekledi vardı min-width: 0;benim örneğe sonra Chrome'da test, ama bu Chrome'da sorunu çözülmüş gibi görünüyor. Web Müfettişi min-width: -webkit-min-content;, tıpkı varsaydığım gibi Chrome'un tarzı olduğunu söylüyor . Şimdi sorunu yalnızca Firefox'ta ve muhtemelen henüz test etmediğim diğer tarayıcılarda çözmem gerekiyor.
Rory O'Kane

Biraz yardımcı oldu sevindim. Sorunumu "display: table-cell" ile diğer tarayıcılarda çözmeyi başardım. Bunun en iyi çözüm olmadığını düşünmüyorum, ama umarım sizin için işe yarar.
doktora

2

.fake-select { white-space:nowrap; }alan kümesinin .fake-selectöğeyi zorlanmış genişlik yerine (taşma gizlenmiş olsa bile) orijinal genişliğiyle yorumlamasına neden oldu .

Bu kuralı kaldırın ve .fake-select's max-width:100%just ' olarak değiştirin width:100%ve her şey uyuyor. Uyarı, sahte seçimin tüm içeriğini görmenizdir, ancak bunun o kadar da kötü olduğunu düşünmüyorum ve şimdi yatay olarak uyuyor.

Güncelleme: Aşağıdaki kemandaki geçerli kurallarla (yalnızca gerçek seçimler içerir), alan kümesinin alt öğeleri doğru genişliklerle sınırlandırılır. İçin kurallar kaldırılmasını dışında .fake-selectve gelen (yorumlarınızı sabitleme // commentiçin /* comment */, ben Fiddle CSS değişiklikleri not ettik.

Sorununuzu şimdi daha iyi anlıyorum ve keman biraz ilerlemeyi yansıtıyor. Tüm <select>s için varsayılan kurallar ayarladım ve .xxlarge480 pikselden daha geniş olacağını bildiğinizler için ayırıyorum (ve bu sadece genişliğini bildiğiniz için işe yarıyor #viewportve sınıfı bu genişliğe manuel olarak ekleyebiliyor. Sadece biraz test gerektiriyor )

Kanıt


Hangi düzeltmeyi kullanırsanız kullanın gerçek üzerinde çalışmak zorunda <select>. Gerçek site sadece <select>s. Asıl mesele , sadece bu davranışın sadece öğelerle gerçekleşen bir tarayıcı hatası olmadığını göstermek için , aslında olmadan a'nın fake-selectdüzen kurallarına sahip olmaktı. Yani stillerini daha az yenmek gibi değiştirmek amacı yener. <select><select><select>.fake-select<select>
Rory O'Kane

Bunun değiştirilmesi .fake-selectbir kutuyu <select>göstermek için (daha önce mevcut bir aynıdır). Elemanların tümü ebeveynin genişliğiyle sınırlıdır (üzerine tıkladığınızda, her biri tek bir satırda görüntülenen seçenekleri bırakarak hariç - ancak bunu kontrol edebileceğinizi düşünmüyorum). İçin tüm kuralları da kaldırdım .fake-select. Mevcut keman ihtiyacınız olanı yapıyor mu?
Trojan

O değil. width: 100%sayfadaki uzun menülerle çalışır, ancak kısa menülerle düzgün çalışmaz. Kısa menüleri sayfanın tam genişliğine genişletir, ancak kısa menülerin kısa genişliklerini korumalarını istiyorum. Oda varsa menüler doğal genişlikleri, ebeveynleri için çok büyükse% 100 genişlikleri olmalıdır. Yapması gereken budur max-width, ancak bu durumda yapmamak.
Rory O'Kane

"Tüm <select>s" leri "uzun <select>s" den ayırarak ve şimdi arka plan genişliği üzerinde çalışarak biraz daha değişiklik yaptım .
Trojan

#viewportsabit bir genişliği de yok. Bu yüzden Görünümü Yeniden Boyutlandır düğmesini sayfaya koyuyorum - böylece görünüm alanı genişliği ne olursa olsun her şeyin çalıştığını test edebilirsiniz. Tıpkı .fake-selectbir gerçek bir alternatiftir <select>test için, #viewportgerçek bir görünüm alanına bir alternatiftir. (“Görünüm penceresi” temel olarak bir tarayıcı penceresidir). Ben dahil #viewportkolayca yerine onları görmek için kaydırma yapmak zorunda kalmıyor görünümün dışına sopa unsurları görebilmek için sayfadaki.
Rory O'Kane
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.