【譯】CSS 中你須要知道 auto 的一切!

做者:shadeed 譯者:前端小智 來源:css-trickscss

點贊再看,養成習慣html

本文 GitHub github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端

在CSS中,咱們有auto值,它能夠用於像marginpositionheightwidth等屬性。在本文中,會先解釋auto的工做方式以及如何最大程度地利用auto的技術細節,固然,會配合一些用例和示例。git

簡介

auto關鍵字的使用因屬性而異。 對於本文,我將在每一個屬性的上下文中解釋值。github

width: auto

塊級元素(如<div><p>)的初始寬度是auto,這使得它們佔據了包含它們的塊的整個水平空間。面試

根據CSS規範:瀏覽器

‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ = 塊的寬度bash

當一個元素的寬度值爲auto時,它包含marginpaddingborder,不會變得比它的父元素大。其中 content 的寬度將是content自己減去marginpaddingborder微信

咱們以上面的模型爲例。app

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將被忽略。

事例源碼:codepen.io/shadeed/pen…

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能夠很好地填充其父元素的可用空間。

事例源碼:codepen.io/shadeed/pen…

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

height: auto

說到height,狀況就不同了。元素的高度等於默認值爲auto的內容。

考慮下面的例子

<div class="wrapper">
  <div class="item">What's my height?</div> </div> 複製代碼

要使.item得到其容器的所有高度,咱們可使用如下方法之一:

  1. .wrapper一個固定的高度,而後爲.item元素添加height: 100%
  2. .wrapper使用 flex 佈局,默認狀況下它將拉伸子項.item

CSS

.wrapper {
    height: 200px;
}

.item {
    height: 100%;
}
複製代碼

margin 和 auto 關鍵字

對於margin,最多見的用例是將已知寬度的元素水平居中。

請考慮如下示例:

要讓上面的藍色矩形居中,可使用下面的方法:

.element {
    margin-left: auto;
    margin-right: auto;
}
複製代碼

根據CSS規範:

若是margin-leftmargin-right值均爲auto,則它們的使用值相等。 這使元素相對於包含塊的邊緣水平居中。

具備絕對定位元素的 margin:auto

另外一個不太常見的將絕對定位元素居中的用例是margin: auto。當咱們有一個元素應該在它的父元素內部水平和垂直居中時,咱們可能會傾向於使用translateXtranslateY

咱們可使用下面方法讓具備絕對定位元素居中:

  1. 設置的寬度和高度。
  2. 元素應具備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;
}
複製代碼

事例源碼:codepen.io/shadeed/pen…

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

Flexbox

在某些狀況下,在flexbox中使用自動頁邊距很是有用。當一個子項目有一個marginauto 時,它將被推到遠的另外一邊。例如,若是一個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;
}
複製代碼

事例源碼:codepen.io/shadeed/pen…

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: automargin-right: auto對於從左到右的佈局(例如英語)可能效果很好。 可是,在多語言網站上工做時要小心顛覆這些價值觀。 更好的是,使用flexboxgrid屬性,以防使用它們完成工做。 若是沒有,那麼請使用自動頁邊距做爲最後的選擇,而應使用CSS邏輯屬性

overflow 屬性

當咱們有一個元素時,咱們應該考慮它應該包含的最小和最大內容。若是內容超過了最大值,那麼咱們須要顯示一個滾動條。

你可能想使用如下內容:

element {
  overflow-y: scroll;
}
複製代碼

然而,這可能會顯示一個滾動條,即便內容高度很短。參見下面的示例

在 Chrome 窗口中,滾動條老是顯示出來,這是不正確和使人困惑的行爲。

經過使用auto關鍵字,咱們能夠確保滾動條不會顯示,除非內容高度大於它的容器。

根據MDN

取決於用戶代理。 若是內容適合填充框內部,則它看起來與可見內容相同,但仍會創建新的塊格式化上下文。 若是內容溢出,桌面瀏覽器會提供滾動條。

.element {
  overflow-y: auto;
}
複製代碼

position 屬性

對於CSS定位屬性toprightbottomleft,咱們可使用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屬性也是如此。 對於rightbottom屬性,其默認計算值分別等於元素的寬度和高度。

事例源碼:codepen.io/shadeed/pen…

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

用例和示例

值得一提的是,下面的用例可能還不夠,可是我嘗試添加一些用例,但願它們對大家有用。

提示箭頭

對於提示框,咱們須要一個指向箭頭,以使其對用戶更加清晰。 若是咱們正在設計系統上,則應該考慮多個狀態。 例如,提示的箭頭指向左側,另外一個箭頭指向右側。

.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;
}
複製代碼

這樣,只有當內容高度足夠大時,它纔會顯示滾動條。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:css-tricks.com/almanac/pro…


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub github.com/qq449245884… 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索