在CSS中,我們有auto
值,它可以用于像margin
,position,height
,width
等屬性。在本文中,會先解釋auto
的工作方式以及如何最大程度地利用auto
的技術細節,當然,會配合一些用例和示例。
簡介
auto
關鍵字的使用因屬性而異。 對于本文,我將在每個屬性的上下文中解釋值。
width: auto
塊級元素(如<div>
或<p>
)的初始寬度是auto
,這使得它們占據了包含它們的塊的整個水平空間。
根據CSS規范:
‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ +‘padding-right’ + ‘border-right-width’ + ‘margin-right’ =
塊的寬度
當一個元素的寬度值為auto
時,它包含margin
、padding
和border
,不會變得比它的父元素大。其中 content 的寬度將是content本身減去margin
、padding
和border
。
我們以上面的模型為例。
html
<div class="wrapper"> <div class="item"> <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eos maxime cum non cupiditate, perferendis saepe vitae fugiat id exercitationem officiis voluptate sint ducimus commodi reiciendis error itaque dolores ipsam? Ea!</p> </div> </div>
css
* { box-sizing: border-box; } .wrapper { max-width: 600px; margin: 2rem auto 0; padding: 1rem; } .item { padding: 1rem; margin: 0 50px; border: 15px solid #1f2e17; }
一切都好,元素 item
被限制在其父項中。
是,如果我們將元素item的寬度更改為100%而不是auto會發生什么? 該元素將占用其父項的100%,加上左側和右側的邊距。
// css .item { width: 100%; padding: 1rem; margin: 0 50px; border: 15px solid #1f2e17; }
該元素的寬度為568px
,是以下各項的總和:
‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ +‘border-right-width’ = 15 + 16 + 506 + 16 + 15 =
568px
如果方向是ltr
,則完全忽略margin-right
。在我們的例子中,這種情況發生了。但是,如果布局是rtl
,那么margin-left
將被忽略。
事例源碼:https://codepen.io/shadeed/pen/f305220fbd4b444371bdef11dad014ec?editors=0100
width 用例: auto
僅僅解釋基礎知識不足以使我們掌握這一概念,因此需要一些事例來說明。
手機和 PC 之間的寬度不同
我們有一組按鈕。在移動設備上,我們希望它們彼此相鄰(每個按鈕包裝器占據其父元素的50%
),而在桌面設備上,每個按鈕都應該占據其父元素的全部寬度。該怎么做?
HTML
<div class="group"> <div class="group__item"> <button class="c-button">Sign In</button> </div> <div class="group__item"> <button class="c-button c-button--ghost">Register</button> </div> </div>
這里使用 flex 布局將按鈕排列在一起。
CSS
.group { display: flex; } .group__item { width: 50%; }
對于 PC,我們每個項需要都取全寬。在這種情況下,你可能傾向于使用width: 100%,對嗎?下面是一個更好的解決方案。
CSS
@media (min-width: 800px) { /* Revert the wrapper to a block element instead of flex */ .group { display: block; } .group__item { width: auto; } }
由于.group
是一個塊元素,因此使用width: auto
可以很好地填充其父元素的可用空間。
事例源碼:https://codepen.io/shadeed/pen/399de6d9d473137998f87f957cfdfa03?editors=1100
height: auto
說到height
,情況就不一樣了。元素的高度等于默認值為auto
的內容。
考慮下面的例子
<div class="wrapper"> <div class="item">What's my height?</div> </div>
要使.item
獲得其容器的全部高度,我們可以使用以下方法之一:
-
給
.wrapper
一個固定的高度,然后為.item
元素添加height: 100%
-
對
.wrapper
使用flex
布局,默認情況下它將拉伸子項.item
CSS
.wrapper { height: 200px; } .item { height: 100%; }
margin 和 auto 關鍵字
對于margin
,最常見的用例是將已知寬度的元素水平居中。
請考慮以下示例:
要讓上面的藍色矩形居中,可以使用下面的方法:
.element { margin-left: auto; margin-right: auto; }
根據CSS規范:
如果
margin-left
和margin-right
值均為auto
,則它們的使用值相等。 這使元素相對于包含塊的邊緣水平居中。
具有絕對定位元素的 margin:auto
另一個不太常見的將絕對定位元素居中的用例是margin: auto
。當我們有一個元素應該在它的父元素內部水平和垂直居中時,我們可能會傾向于使用translateX
或translateY
。
我們可以使用下面方法讓具有絕對定位元素居中:
-
設置的寬度和高度。
-
元素應具有
position: absolute
HTML
<div class="wrapper"> <div class="item">I am centered.</div> </div>
CSS
.wrapper { position: relative; } .item { width: 200px; height: 100px; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; }
事例源碼:https://codepen.io/shadeed/pen/b086f8402be981e871ac5db15495dec8?editors=0100
Flexbox
在某些情況下,在flexbox中使用自動頁邊距非常有用。當一個子項目有一個margin
是auto
時,它將被推到遠的另一邊。例如,如果一個flex
項目的左邊是margin-left: auto
,那么它將被推到最右邊。
考慮下面的模型,父級元素是一個 flex
布局:
我們想把第二項推到最右邊,自動邊距就派上用場了。
CSS
.wrapper { display: flex; } .item-2 { margin-left: auto; }
不僅如此,它還可以在水平或垂直方向工作。參見下面的示例
CSS
.item-2 { margin-top: auto; }
另外,如果只有一個子元素,則可以使用margin:auto
將其水平和垂直居中。
CSS
.item-1 { margin: auto; }
flex 屬性和 auto 關鍵字
在flexbox中,我們可以使用flex: auto作為子項目。這是什么意思?當一個子項目有flex: auto時,它等價于flex: 11 auto,與下面等價:
CSS
.item { flex-grow: 1; flex-shrink: 1; flex-basis: auto; }
MDN 描述
該項目根據其寬度和高度屬性調整大小,但會增長以吸收flex容器中的任何額外自由空間,并會收縮到其最小尺寸以適合該容器,這等效于設置“
flex:1 1 auto
”。
具有flex:auto
的項目將根據其寬度和高度來調整大小,但它可以根據可用的額外空間來增大或縮小。 在研究本文之前,我不知道這一點!
HTML
<div class="wrapper"> <div class="item item-1">Item</div> <div class="item">Item</div> <div class="item">Item</div> </div>
CSS
.wrapper { display: flex; flex-wrap: wrap; } .item { width: 120px; height: 500px; } .item-1 { flex: auto; }
事例源碼:https://codepen.io/shadeed/pen/4914b4517b858f0fcf0f8acd07c64b1e?editors=1100
CSS grid 和自動設置一個 auto
列
在CSS Grid中,我們可以設置一個列為auto
,這意味著它的寬度將基于它的內容長度。看看下面,你就知道我的意思了:
wrapper { display: grid; grid-template-columns: auto 1fr 1fr; }
grid 和 auto 邊距
使用CSS網格時,可以使用自動頁邊距實現類似于 flexbox 的結果。 當我們有一個網格,并且其中的網格項目具有margin-left: auto
時:該項目將被推到右邊,其寬度將基于其內容長度
考慮下面的例子:
當我們希望item1
的寬度基于其內容,而不是網格區域。 通過使用margin-left: auto
,可以通過下面代碼實實現:
.item-1 { margin-left: auto; }
從右向左布局
值得一提的是,使用margin-left: auto
或margin-right: auto
對于從左到右的布局(例如英語)可能效果很好。 但是,在多語言網站上工作時要當心顛覆這些價值觀。 更好的是,使用flexbox
或grid
屬性,以防使用它們完成工作。 如果沒有,那么請使用自動頁邊距作為最后的選擇,而應使用CSS邏輯屬性。
overflow 屬性
當我們有一個元素時,我們應該考慮它應該包含的最小和最大內容。如果內容超過了最大值,那么我們需要顯示一個滾動條。
你可能想使用以下內容:
element { overflow-y: scroll; }
然而,這可能會顯示一個滾動條,即使內容高度很短。參見下面的示例
在 Chrome 窗口中,滾動條總是顯示出來,這是不正確和令人困惑的行為。
通過使用auto
關鍵字,我們可以確保滾動條不會顯示,除非內容高度大于它的容器。
根據MDN:
取決于用戶代理。 如果內容適合填充框內部,則它看起來與可見內容相同,但仍會建立新的塊格式化上下文。 如果內容溢出,桌面瀏覽器會提供滾動條。
.element { overflow-y: auto; }
position 屬性
對于CSS定位屬性top,right,bottom和left,我們可以使用auto關鍵字作為它們的值。 接下來我要解釋的是對我來說是新的,我在研究本文時學到了它。
考慮下面的模型:
我們有一個有內邊距的 wrapper 元素,還有一個子項。子項目是絕對定位的,但沒有任何定位屬性。
.wrapper { position: relative; padding: 16px; } .item { position: absolute; width: 100px; height: 100px; }
在CSS中,每個屬性都有一個初始值/默認值。 如果我檢查了子項并轉到computed styles,你猜下left
屬性的值會是什么?
left
的默認值為16px
,即使沒有設置。為什么會發生這種情況? 好吧,原因是絕對定位的元素相對于其最接近的父元素具有position:relative
。 該父項具有padding: 16px
,因此子項位于頂部和左側的16px
處。 有趣,不是嗎?
現在,你可能會問,這樣做有什么好處?好吧,讓我繼續。
假設子項必須在較小的視口中位于距左側100像素的位置,對于桌面,它應恢復為默認位置。
.wrapper { position: relative; } .item { position: absolute; left: 100px; width: 100px; height: 100px; }
如何在較大的視口中重設left
? 我們不能使用left:0
,因為這會將子元素粘到邊緣,這不是我們想要的。 請參閱下面的模型,以了解我的意思。
要以正確的方式重置子項,我們應該使用left: auto
。 根據 MDN:
如果元素是靜態元素,則將定位在它應該水平定位的位置
這意味著,它會尊重padding
,而不會將子條目粘貼到其父條目的邊緣。
.item { position: absolute; left: 100px; width: 100px; height: 100px; } @media (min-width: 800px) { .item { /* This is equivalent to left: 16px */ left: auto; } }
top
屬性也是如此。 對于right
和bottom
屬性,其默認計算值分別等于元素的寬度和高度。
事例源碼:https://codepen.io/shadeed/pen/d062539938346e5458f769cbc08833e1?editors=0100
用例和示例
值得一提的是,下面的用例可能還不夠,但是我嘗試添加一些用例,希望它們對你們有用。
提示箭頭
對于提示框,我們需要一個指向箭頭,以使其對用戶更加清晰。 如果我們正在設計系統上,則應該考慮多個狀態。 例如,提示的箭頭指向左側,另一個箭頭指向右側。
.tooltip:before { /* 箭頭代碼 */ position: absolute; left: -15px; } /* 這是一個箭頭指向右側的版本*/ .tooltip.to-right:before { /* 箭頭代碼 */ position: absolute; left: auto; right: -15px; }
請注意,在初始實現中,我使用left: auto
來覆蓋left: -15px
。 供您參考,這是非常常用的,我建議改用以下內容:
.tooltip:before { position: absolute; right: 100%; } .tooltip.to-right:before { /* Arrow code */ position: absolute; right: auto; left: 100%; }
通過使用100%
,我們避免了使用硬編碼的值(箭頭寬度),如果我們改變箭頭的大小,這個值可能會失敗。這是一個更經得起時間考驗的解決方案。
卡片組件
你可能有一個card組件,其左上角有一個操作,它可能僅用于裝飾,也可能是一個有用的操作。不管是什么,你都應該考慮到它是雙向的。
通過使用left:auto
,我們可以很容易地重置它的基本實現。
.card .icon { position: absolute; left: 15px; top: 15px; } .card.is-right .icon { left: auto; right: 15px; }
Flexbox 和 自動邊距
當談到flexbox時,它有無限的可能性。 通過將其與自動邊距相結合,我們可以構建功能強大的布局。
考慮下面的例子
我們在右側包含一行標題,描述和一個操作按鈕的行。 我們希望操作按鈕貼在右側。
HTML
<div class="item"> <div class="item-group"> <!-- Title and description --> </div> <button class="item__action">Confirm</button> </div>
CSS
.item { display: flex; flex-wrap: wrap; justify-content: space-between; } .item__action { margin-left: auto; }
就是這樣! 通過使用margin-left: auto
,將動作推到最右角。 更好的是,如果您要構建多語言網站,我們可以使用CSS邏輯屬性。 CSS將如下所示:
.item__action { margin-inline-start: auto; }
CSS grid 和自動邊距
在向網格項目添加邊距時,它可以是固定值,百分比或自動值。 我對auto更感興趣。 考慮以下:
HTML
<p class="input-group"> <label for="">Full Name</label> <input type="email" name="" id=""> </p>
CSS
.input-group { display: grid; grid-template-columns: 1fr; grid-gap: 1rem; @media (min-width: 700px) { grid-template-columns: 0.7fr 2fr; } }
我想將label 與input的左邊緣對齊。 為此,我需要應用以下內容:
.input-group label { margin-left: auto; }
模態設計
在進行模態設計時,重要的是要考慮內容高度很大時會發生的情況。 對于這種情況,我們可以使用以下代碼:
.modal-body { overflow-y: auto; }
這樣,只有當內容高度足夠大時,它才會顯示滾動條。
英文原文地址:https://css-tricks.com/almanac/properties/o/overflow/
作者:shadeed