使用這種技巧,可以大大地提高前端布局效率
在布局中,對于每塊功能的 DOM 結(jié)構(gòu),我們一般使用一個(gè)帶有 wrapper 類元素把它包裹起來,讓代碼或者網(wǎng)頁內(nèi)容更易于閱讀。為此,我們一般使用wrapper 或者container。在CSS 中使用wrapper可能有多種方式,這些方式中,有些會(huì)帶來一些問題。
在本文中,將介紹 CSS中 的 wrapper 布局,它們?nèi)绾喂ぷ?,如何使用它們以及何時(shí)不使用它們。請注意,在本文中,可能會(huì)提到wrapper 和container這兩個(gè)術(shù)語,它們的含義相同。
wrapper 簡介
當(dāng)我們說到 wrapper 或container,實(shí)際上是指一組元素被包裝或包含在另一個(gè)元素內(nèi)。我們可以為 元素添加一個(gè) wrapper類,這樣我們就不用額外元素,如下所示:
- body {
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
但是,將 wrapper添加到元素是不切實(shí)際。 wrapper元素可以防止子項(xiàng)超出其邊界??紤]下圖:
我們這里有aside和main元素,它們被放在了wrapper 元素中。當(dāng)然,.wrapper元素有一個(gè)寬度
- <div class="wrapper">
- <aside>...</aside>
- <main>...</main>
- </div>
如果沒有wrapper,子元素將粘附在屏幕的邊緣。這可能會(huì)讓用戶非常惱火,尤其是在大屏幕上。
上圖顯示了當(dāng)沒有用wrapper進(jìn)行包裹時(shí)元素是如何展開的,用戶不應(yīng)該體驗(yàn)這種行為。我們來解釋一下背后的原因。
為什么頁面上 wrapper 有必要的
通過多加一層 wrapper 布局,有很多好處:
- 使內(nèi)容更具可讀性。沒有多加一層 wrapper,文本和圖像之類的內(nèi)容就可以拉伸以占據(jù)整個(gè)屏幕寬度。對于小屏幕,這似乎可以。但是,對于大屏幕,這是非常煩人的。
- 對設(shè)計(jì)元素進(jìn)行分組可以更好地增加間距。
- 在沒有wrapper的情況下,將設(shè)計(jì)元素劃分為列是不容易完成的。
在CSS中實(shí)現(xiàn) wrapper
目前我們已經(jīng)了解了wrapper基礎(chǔ)知識和優(yōu)點(diǎn),接下來我們來具體的看看在 CSS 如何使用它。
設(shè)置寬度
實(shí)現(xiàn)wrapper第一件事就是要確認(rèn)它的寬度。而寬度如何這取決于 UI 的設(shè)計(jì)。一般來說,最常用寬度是1000px-1300px。例如,流行的框架Bootstrap使用1170px的寬度。
- .wrapper {
- width: 1170px;
- }
但是,不建議使用width屬性,因?yàn)楫?dāng)屏幕尺寸小于1170像素時(shí),會(huì)出現(xiàn)水平滾動(dòng)。可以max-width 來解決這個(gè)問題。
- .wrapper {
- width: 1170px;
- max-width: 100%;
- }
我們還可以更簡單點(diǎn),僅使用 max-width。
- .wrapper {
- max-width: 1170px;
- }
現(xiàn)在有了寬度,我們可以將它居中 。
居中 wrapper
為了讓 wrapper 居中,使用讓左右外邊距的值為 auto,如下所示:
- .wrapper {
- max-width: 1170px;
- margin: 0 auto;
- }
根據(jù) CSS 規(guī)范,下面是margin: 0 auto;的工作原理
如果'margin-left'和'margin-right'均為'auto',則它們的使用值相等。這會(huì)讓元素相對于包含塊的邊緣水平居中。
這里我使用margin:0 auto,這基本上將頂部和底部的margin重置為零,并使其左側(cè)和右側(cè)為auto。使用此功能會(huì)有一些后果,這將在本文后面介紹。目前,建議使用簡化版邊距:
- .wrapper {
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- }
在左側(cè)和右側(cè)添加 padding
要考慮的重要事項(xiàng)是在左側(cè)和右側(cè)添加padding。當(dāng)視口大小小于 wrapper 的最大寬度時(shí),這將導(dǎo)致 wrapper 邊緣粘在視口上。
- .wrapper {
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
通過添加padding,我們可以確保從左右兩邊得到一個(gè)16px的偏移量,即使視口的大小小于最大寬度。padding作為一種保護(hù)策略,避免在寬度不足時(shí)讓 wrapper 粘在視口邊緣。
使用百分比的 wrapper
我收到了有關(guān)使用百分比寬度(如max-width:90%)用于包裝器而不是使用padding-left和padding-right的答復(fù)。
我經(jīng)常可以到直接在 'wrapper' 使用百分比寬度,如max-width: 90%。而不是使用padding-left和padding-right。
在大屏幕上,寬度90%太大了,我們可以使用媒體查詢來覆蓋它。
- .wrapper {
- max-width: 90%;
- margin-left: auto;
- margin-right: auto;
- }
- /* A media query for a large screen */
- @media (min-width: 1170px) {
- .wrapper {
- max-width: 1170px;
- }
- }
使用百分比寬度,我們多添加了一個(gè)額外的步驟。通過使用固定的寬度值,我們可以輕松地避免此步驟。對應(yīng)于這種方案,我們可以將width: 90%與max-width:1170px屬性結(jié)合在一起。
- .wrapper {
- width: 90%;
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- }
這是一個(gè)有趣的方法,但我更喜歡自己添加padding,而不是依賴于百分比寬度。
Wrapper 的display類型
由于wrapper 是<div>,因此默認(rèn)情況下它是塊級元素。問題是,當(dāng)要將wrapper內(nèi)的內(nèi)容放置在grid中時(shí),該怎么辦?我們直接在 wrapper 上添加 display: grid ?
我不建議您這樣做,因?yàn)檫@與關(guān)注點(diǎn)分離的概念背道而馳。wrapper用于包裹其內(nèi)容,僅此而已。如果需要使用grid布局,則在多添加一層
專門用來 grid 布局會(huì)更容易也更清晰還容易維護(hù)。
- <div class="wrapper">
- <!-- Content -->
- </div>
不建議這樣做,因?yàn)閣rapper元素可以在另一頁上使用,這可能會(huì)無意間破壞布局。
- .wrapper {
- display: grid;
- grid-template-columns: 2fr 1fr;
- grid-gap: 16px;
- }
更好的解決方案如下:
- <div class="wrapper">
- <div class="featured-news">
- <!-- Elements that needs to be placed in a grid -->
- </div>
- </div>
- .featured-news {
- display: grid;
- grid-template-columns: 2fr 1fr;
- grid-gap: 16px;
- }
在 wrapper 之間添加 margin
上面我們說到不建議使用簡寫版本來居中wrapper 元素:
- .wrapper {
- margin: 0 auto;
- }
雖然它可以工作,但當(dāng)頁面上有多個(gè)wrapper ,并且需要在它們之間添加間距時(shí),它可能會(huì)令人困惑。由于布局需要,我們需要在 wrapper 上多添加一個(gè)類,如 wrapper-variation,那么margin有可能無法正常工作。
- .wrapper-variation {
- margin-top: 50px;
- }
- .wrapper {
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
.wrapper-variation元素的margin無法使用,因?yàn)樗驯籱argin: 0 auto覆蓋。為避免此類混淆,建議在這種情況下使用非簡寫格式 。
現(xiàn)在讓我們來添加頁邊距。在每個(gè)項(xiàng)目中,我都準(zhǔn)備了一組用于margin和padding的實(shí)用工具類,在必要時(shí)使用它們,考慮下圖。
- <div class="wrapper mb-5"></div>
- <section>
- <div class="wrapper"></div>
- </section>
- <div class="wrapper"></div>
- .mb-5 {
- margin-bottom: 3rem !important;
- }
這樣,wrapper 的 CSS保持原樣,并且使用附加的 CSS 類添加了間距。現(xiàn)在,你可能會(huì)問,為什么可以在一個(gè)頁面上添加多個(gè)wrapper?在上面的HTML中,兩個(gè)wrapper之間有一個(gè)<section>
在這里使用!important很好,因?yàn)閷?shí)用程序類的要點(diǎn)是強(qiáng)制屬性,通過添加!important,我們可以確保做到這一點(diǎn)。
全屏中的 Wrapper
在某些情況下,如果某個(gè)部分的背景視口寬度為100%,并且其中包含wrapper`,則可能會(huì)出現(xiàn)這種情況。與上一個(gè)示例中介紹的類似。
- <section>
- <div class="wrapper"></div>
- </section>
- <section>
- <div class="wrapper"></div>
- </section>
主內(nèi)容需要添加 wrapper 嗎?
這要看情況。讓我們探討兩種最常用內(nèi)容區(qū)間的設(shè)計(jì)。
第一個(gè)以其內(nèi)容為中心,并受特定寬度限制。
第二個(gè)將其內(nèi)容擴(kuò)展到主內(nèi)容的邊緣。
為了更好地理解這兩種模式,我們來一起探討如何構(gòu)建其中的每種模式。
內(nèi)容居中
你可能想在不使用 wrapper前提下讓內(nèi)容居中。
- <section class="hero">
- <h2>How to make bread at home</h2>
- <p>....</p>
- <p><a href="/sign-up">Sign up</a></p>
- </section>
在上面的 HTML 中,可以使用text-align將內(nèi)容居中
- .hero { text-align: center; }
除非你調(diào)整瀏覽器窗口的大小,不然你可能會(huì)忽略掉這個(gè)問題。
內(nèi)容緊貼邊緣
由于左側(cè)和右側(cè)沒有padding,因此內(nèi)容將粘在邊緣上。這對用戶是不友好的,因?yàn)槭箖?nèi)容瀏覽變得更加困難。
大屏幕的行長
在大屏幕上,由于行長太長,段落文本可能很難看清。根據(jù)應(yīng)用于 Web 的版式樣式元素,行的建議字符數(shù)為45到75。超出該范圍的任何字符都會(huì)使閱讀更加困難。
為避免上述問題,可以使用wrapper來防止文本長度變得過長并在移動(dòng)設(shè)備中增加間距。
- <section class="hero">
- <div class="hero__wrapper">
- <h2>How to make bread at home</h2>
- <p>...</p>
- <p><a href="/sign-up">Sign up</a></p>
- </div>
- </section>
這里使用了hero__wrapper類,因?yàn)樵搘rapper可能僅是針對hero部分定制的,因此它可以具有一定的寬度,該寬度小于通用的wrapper元素。
- .hero__wrapper {
- max-width: 720px;
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
為了使內(nèi)容居中,可以根據(jù)具體情況使用具體的屬性。對于此示例,使用text-align:center足以使內(nèi)容居中。
對wrapper使用 CSS 變量
只用一種尺寸的wrapper很少。wrapper的寬度可以小也可以大,具體取決于內(nèi)容。通過利用 CSS 變量,我們可以創(chuàng)建一個(gè)更現(xiàn)代的wrapper,它擁有極大的靈活性??紤]以下內(nèi)容:
- <div class="wrapper"></div>
- .wrapper {
- max-width: var(--wrapper-width, 1170px);
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
var有兩個(gè)值,第一個(gè)值是變量--wrapper-width,第二個(gè)值是1170px,如果未設(shè)置--wrapper-width變量,則將使用1170px。
當(dāng)然,我們可以直接在標(biāo)簽內(nèi)對 --wrapper-width 進(jìn)行賦值,這樣就能動(dòng)態(tài)設(shè)置我們想要的值。
- <div class="wrapper" style="--wrapper-width: 720px"></div>
如果你不使用 CSS 變量的方式,也可以通過多加一個(gè)類來解決:
- <div class="wrapper wrapper--small"></div>
- .wrapper--small {
- --wrapper-width: 720px;
- /* this will override the default wrapper width. */
- }
使用 display: contents
首先,簡要介紹一下這個(gè)屬性。CSS中的每個(gè)元素都是一個(gè)盒子,該盒子包含content、padding、margin和border。display: contents樣式規(guī)則使div元素不產(chǎn)生任何邊界框,因此元素的margin、border和padding部分都不會(huì)渲染。然而,繼承的屬性如顏色(color)和字體(font)卻能照常影響到子元素。
- <header class="site-header">
- <div class="wrapper site-header__wrapper">
- <!-- Header content -->
- </div>
- </header>
- .site-header__wrapper {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- }
在上面的示例中,你可能需要讓標(biāo)題擴(kuò)展到整個(gè)頁面的寬度,而不是受wrapper寬度的限制。
- .site-header__wrapper {
- display: contents;
- }
- .site-header {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- }
這樣,.wrapper元素將被隱藏(類似)?,F(xiàn)在,當(dāng)將display:flex應(yīng)用于.site-header元素時(shí),.wrapper的后代項(xiàng)將成為.site-header的子項(xiàng)。
流動(dòng)背景,固定內(nèi)容
Lea Verou 在她的《CSS Secrets》一書中介紹了一種有趣的技巧,該技巧可用于流動(dòng)背景(占據(jù)整個(gè)視口寬度)且內(nèi)部帶有wrapper部分。讓我們回顧一下常見的做法。
- <section>
- <div class="wrapper"></div>
- </section>
- section {
- background-color: #ccc;
- }
- .wrapper {
- max-width: 1170px;
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- }
margin-left: auto和margin-right: auto的工作方式是計(jì)算視口寬度的一半減去內(nèi)容寬度。使用padding也可以做到。

- section {
- padding: 1rem calc(50% - 585px);
- }
這樣還有問題,在移動(dòng)設(shè)上內(nèi)容將粘貼備的邊緣,一種解決方案如下:
- section {
- padding: 1rem;
- }
- @media (min-width: 1170px) {
- section {
- padding: 1rem calc(50% - 585px);
- }
- }
作者:Ahmad shaded 譯者:前端小智 來源:sitepoint 原文:https://ishaded.com/article/styling-css/
本文轉(zhuǎn)載自微信公眾號「大遷世界」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系大遷世界公眾號。