[英]Why does overflow:hidden break multiple column rendering in Firefox but not in Chrome?
我最近在 Firefox 中偶然發現了一個奇怪的行為,其中包含columns:2
div 中的列表。
如果列表有overflow:hidden
設置,Firefox 不再以 2 列呈現。 在 Chrome 中渲染它在 2 列中如預期的那樣(有和沒有溢出)。
這是一個最小的例子:
$('button').on('click', (e) => { $('ul').toggleClass('overflow') })
div { columns:2; } ul.overflow { overflow: hidden; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button>toggle overflow</button> <div> <ul> <li>Lorem ipsum dolor.</li> <li>Consequuntur, ab nostrum.</li> <li>Quibusdam, iure, fuga.</li> <li>Suscipit quisquam, vel.</li> <li>Assumenda architecto, adipisci!</li> <li>Molestias, nostrum ratione.</li> <li>Quaerat, eveniet, in.</li> <li>Illum, debitis, dicta.</li> <li>Tempore, placeat, ea.</li> <li>Amet dignissimos, maiores.</li> <li>Odio, eos, ullam.</li> <li>Modi libero, quis!</li> <li>Aliquid, commodi, voluptates.</li> <li>Aperiam, magni, vel.</li> <li>Vitae, minima dolorum!</li> <li>Quidem, corporis, dolorum.</li> <li>Autem, minima, sit.</li> <li>Adipisci, odio, numquam.</li> <li>At, dicta, hic!</li> <li>Odit, blanditiis voluptate.</li> </ul> </div>
在 CodePen 上: https ://codepen.io/BugHunter2k/pen/rNaVpGG
什么樣的渲染是對的? 有什么我可以添加的東西,所以即使有overflow:hidden
,Firefox 也會呈現 2 列overflow:hidden
雖然蒂埃里的答案包括解決一個問題的解決方案,但它也解決了您面臨的實際問題(我相信是無意中的),並且有問題地將責任歸咎於錯誤的瀏覽器。 讓我們分解一下:
首先,這實際上在 Firefox 中可以正常工作,而在 Chrome 中則不正確。
由於columns: 2
,您有一個 div 充當多列容器,它是以下的簡寫:
div {
column-count: 2;
column-width: auto;
}
這個多列容器建立了一個新的塊格式上下文,因此在本例中,后代元素的任何屬性都將相對於 div 而不是頁面應用。
要記住的一件事是多列布局有點靈活(我的意思也不是與 flexbox 布局有關)……他們會嘗試遵守您提供的值,但如果它們適合在更少的列中,或者如果他們必須占用更多的列來適應您的標記,他們很可能會這樣做。 您稍后會在我的回答中看到這樣的示例。
在 div 中,您有一個無序列表,它通常在垂直列表中顯示其子項,但由於columns: 2
之前的columns: 2
,您的<ul>
會自動拆分以盡可能適合兩列。 因為沒有在任何地方聲明height
或width
屬性(通常或作為column-
屬性),它只是將內容拆分為 50-50。 您在列表的兩半之間看到的未對齊是因為<ul>
默認具有margin-top
屬性,它將列表項的前半部分向下推 16px(通常是<ul>
上的邊距大小)。
應用columns: 2
in ul {}
而不是div {}
解決您的問題的原因是因為您現在將<ul>
本身拆分為兩列,而不是嘗試將普通<ul>
擠壓到多列容器中但是它可以適合; 瀏覽器知道以這種方式將相同的格式應用於每列的開頭。
現在,默認情況下<div>
與其容器一樣寬(因為它的默認display:block;
屬性)和它的內容一樣高。 如果您要向<ul>
添加更多項目,則兩組列表項的高度會增加(如果您為 div 設置了背景顏色,則可以更容易地看到)。
回到我提到的靈活性,如果您將 div 的高度限制在 150 像素,您會看到默認情況下列數增加並溢出 div:
div { columns:2; column-rule: thin solid red; /* this value added just to illustrate the split between columns */ height: 150px; background: grey; /* this value added for ease of visual comprehension */ } ul.overflow { overflow: hidden; }
<div> <ul> <li>Lorem ipsum dolor.</li> <li>Consequuntur, ab nostrum.</li> <li>Quibusdam, iure, fuga.</li> <li>Suscipit quisquam, vel.</li> <li>Assumenda architecto, adipisci!</li> <li>Molestias, nostrum ratione.</li> <li>Quaerat, eveniet, in.</li> <li>Illum, debitis, dicta.</li> <li>Tempore, placeat, ea.</li> <li>Amet dignissimos, maiores.</li> <li>Odio, eos, ullam.</li> <li>Modi libero, quis!</li> <li>Aliquid, commodi, voluptates.</li> <li>Aperiam, magni, vel.</li> <li>Vitae, minima dolorum!</li> <li>Quidem, corporis, dolorum.</li> <li>Autem, minima, sit.</li> <li>Adipisci, odio, numquam.</li> <li>At, dicta, hic!</li> <li>Odit, blanditiis voluptate.</li> </ul> </div>
如您所見,div 與容器一樣寬(無論您的容器有多大),並且列被分成三部分,因為這是適合您擁有的列表項數量所必需的。 它通過根據需要溢出子元素來嘗試保持列的高度相等。 你在切換按鈕時看到的行為的秘密是什么overflow: hidden;
做。
當你應用overflow: hidden;
到一個元件,它也建立一個新的塊格式化上下文。 創建一個新的塊格式化上下文基本上是說“在這里從頭開始重置我的布局計算;不要考慮包含塊在做什么”。 在您的情況下,它是說“忽略前一個塊格式上下文中的 CSS 列布局,並像<ul>
通常那樣顯示”。 Chrome 沒有這樣做,但它應該這樣做。 可能是實現錯誤/不完整的情況,也可能是 Chrome 開發人員根據他們認為大多數人想要的內容做出決定的情況。 這兩種情況在該供應商中都很常見。
其次,Thierry 建議修復<ul>
的兩個部分的不均勻垂直對齊是將column
屬性應用於<ul>
。 該特定目標也可以通過刪除margin-top
屬性/將其設置為0
,但這種解決該目標的方法還執行以下操作:
<ul>
應用適當的多列布局設置(正如我之前提到的,現在瀏覽器知道在多列布局的上下文中處理列表和列表項,而不是僅僅嘗試擠入列表以多列容器)。<ul>
本身上設置columns
屬性意味着,當由於overflow: hidden;
而創建新的塊格式化上下文時overflow: hidden;
,關於<ul>
忽略來自父<div>
及其塊格式上下文的內容沒有任何變化。 換句話說,多列布局應用在由overflow: hidden;
創建的新塊格式化上下文中overflow: hidden;
. 如果您只想將無序列表拆分為多列,這種新行為最終就是您想要的。 如果您希望為多列布局考慮多種類型的元素(或僅多個元素),則需要將其保留在父<div>
上。
這可能是 Firefox 的一個錯誤。
但是你可以做的是把columns: 2;
在ul
而不是在div
。 它還將解決與第一列不對齊的第二列的(不需要的?)行為。
不要忘記在代碼中使用瀏覽器前綴。 它總是可以幫助您防止一些錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.