這一期中咱們主要來聊聊全屏的事情。對於全屏的佈局,你們可能首先想到的是100%
(或100vw
)來實現,但若是你要在一個限寬的容器中實現一個全屏效果呢?好比說,一個Banner區全屏顯示。相似這樣的效果在PC端是很是常見的一個效果。可能會有不少同窗會說,這樣的效果有什麼好聊的,不是很是簡單的Layout嗎?其實仍是有點事情可聊的。若是你感興趣,不仿繼續往下閱讀。javascript
在Web佈局中,特別是在PC端中,經常能夠看到這樣的設計風格:內容居中,而後Banner區全屏。這也就是標題所說的效果,限寬的容器中實現全屏效果。那麼問題來了,在實際中如何實如今限寬的容器中實現全屏效果。好比下面的設計風格:css
看到上圖的效果,咱們可能首先會想到從HTML結構上來作相應的處理:html
<div class="banner">
<div class="container">
</div>
</div>
複製代碼
對應的CSS樣式:vue
.banner .container {
width: 100%
}
複製代碼
若是對於多個區域全屏和多個區域限寬居中呢?若是仍是從結構上作處理的話,可能會:java
<header>
<div class="wrapper">
</div>
</header>
<div class="full-width">
<div class="wrapper">
</div>
</div>
複製代碼
CSS並不會太複雜:css3
.full-width {
width: 100%;
}
.wrap {
width: 80%;
max-width: 24em;
margin: 0 auto;
}
複製代碼
這其實很簡單。若是咱們換過一個環境或提升限制條件呢?假設你是在爲一個CMS系統作開發(你並無自主修改HTML的權限)。即你的結構有能都是這樣的一個模式:git
<div class="container">
<header></header>
<div clas="banner"></div>
<main></main>
<footer></footer>
</div>
複製代碼
在.container
中設置一個限制寬度,好比:github
.container {
width: 80%;
max-width: 80vw;
margin: 0 auto;
}
複製代碼
基於這樣的一個Layout結構,若是header
、.banner
和footer
區域須要全屏顯示。在不修改HTML結構的狀況之下,如何實現須要的效果。web
你們是否還記得等高佈局,在等高佈局的實現方案中就有一個負margin
和正padding
相互抵銷的方案。那麼若是僅實現一個全屏的背景顏色也可使用該方案:正則表達式
header {
margin: 0 -9999rem;
padding: 1rem 9999rem;
}
複製代碼
和前面的一個方案相似,只不過把正padding
換成了border
:
.banner {
border-left: 600rem solid maroon;
border-right: 600rem solid maroon;
margin: 0 -600rem;
}
複製代碼
使用vw
和calc()
二者的結合可讓事情變得更爲簡單,好比:
.full-width {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
複製代碼
在CSS中,咱們能夠藉助transform
中的translate()
來替代left
和right
,上面的示例代碼能夠變成:
.full-width {
width: 100vw;
transform: translateX(calc(( 960px - 100vw ) / 2)); // 假設限寬的容器寬度爲960px
}
複製代碼
上面的代碼我們繼續優化一下:960px
至關於100%
,這樣一來960px / 2
也就至關於50%
;對應的100vw / 2
就變成了50vw
。這樣上面的代碼就變成了:
.full-width {
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
}
複製代碼
若是你使用Sass這樣的CSS處理器,你還能夠將其封裝成一個@mixin
:
@mixin full-width($support-type: margin,$min-width:null){
@if $support-type == 'margin' {
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
// margin-left: calc(-100vw / 2 + #{$min-width} / 2);
// margin-right: calc(-100vw / 2 + #{$min-width} / 2);
}
@if $support-type == 'position' {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
@if $support-type == 'translate' {
width: 100vw;
transform: translateX(calc((#{$min-width} - 100vw)/2));
}
}
複製代碼
有了上述定義的混合宏,在實際使用的時候,只須要向下面這樣調用:
.full-width {
@include full-width(margin,960px);
}
複製代碼
使用vw
和calc()
函數來實現限寬容器中任何一個單一元素實現全屏佈局。另外,vw
還能夠配合僞元素、padding
或者說百分比和padding
也能夠實現一些相似的佈局效果:
有關於這方面更詳細的介紹能夠閱讀:
在Web技巧第四期中末尾向你們介紹了CSS中重要的屬性之一display
,在將來的display
中可使用兩個值。而@Rachel Andrew花了三篇文章的篇幅來介紹CSS的display
屬性:
若是想對display
有一個深刻的瞭解,那麼這幾篇文章對你是有較大的參考價值或者文章中相關的內容是很是值得咱們去深挖。固然,想更深刻的把display
聊的清楚一些,那麼咱們頗有必要花更多的時間來梳理。若是你感興趣的話,歡迎關注後續相關的更新,我將會花一到兩篇的篇幅和你們從新來聊display
。若是你不想等的過久,除了上面的文章以外,下面這幾篇文章也是有助於你更好的理解display
:
在《Web中的圖標》一文中主要和你們一塊兒聊了聊Web中的圖標(Icon圖標)如何應該,應該怎麼去選擇。雖然SVG的Icon在實際使用中已經很是的成熟了:
但仍是有不少同窗在使用字體圖標,並且有關於字體圖標相關的介紹也很是的多:
但字體圖標的使用過程當中會存在不少的問題。@zachleat在《The Scoville Scale of Web Font Loading Opinions》爲Web字體加載作了一個主題的介紹,並且有關於這方面的優秀教程,在互聯網上大把:
而字體圖標和字體加載存在必定的兼容性問題。簡單地說,字體圖標彷佛存在Web標準以外。換句話說就是font-display
沒有與圖標字體兼容的有效值。
加載字體圖標時,一般不但願有一個降級文本(回退文本)渲染。它不是典型的無樣式文本(FOUT)場景。若是字體圖標沒有回退文本渲染,誰都不知道字體加載未成功的時候會看到什麼。
你可有在訪問有字體圖標的Web頁面時,字體未加載或加載失敗時看不到圖標,而是一個帶顏色的方框。
使用字體圖標都會藉助CSS的@font-face
屬性,在@font-face
指令中使用font-display
來加載自定義字體。這個屬性能夠添加如下的值:
auto
:默認值。典型的瀏覽器字體加載的行爲會發生,也就是使用自定義字體的文本會先被隱藏,直到字體加載結束纔會顯示swap
:後備文本當即顯示直到自定義字體加載完成後再使用自定義字體渲染文本。在大多數狀況下,這就是咱們所追求的效果fallback
:這個能夠說是auto
和swap
的一種折中方式。須要使用自定義字體渲染的文本會在較短的時間不可見,若是自定義字體尚未加載結束,那麼就先加載無樣式的文本。一旦自定義字體加載結束,那麼文本就會被正確賦予樣式optional
:效果和fallback
幾乎同樣,都是先在極短的時間內文本不可見,而後再加載無樣式的文本。不過optional
選項可讓瀏覽器自由決定是否使用自定義字體,而這個決定很大程度上取決於瀏覽器的鏈接速度。若是速度很慢,那你的自定義字體可能就不會被使用block
:爲字體提供一個短暫的阻塞週期和無限的交換週期,它將使用不可見的文本長達3s
,並顯示回退文本,直到Web字體加載完成。這是最佳選項,但仍然不是很好有關於font-display
更詳細的介紹能夠閱讀《font-display
的用法》一文。
要解決這些問題,可使用CSS字體加載API強制不可見的文本,直到圖標字體成功加載。或者使用使用SVG圖標。
@David Walsh整理了使用JavaScript的幾個小技巧。
經過...new Set()
獲得一個惟一值的數組:
var j = [...new Set([1, 2, 3, 3])]
>> [1, 2, 3]
複製代碼
經過map
和filter
來過濾掉數組中的布爾值(好比0
、undefined
、null
、false
等):
myArray.map(item => {
//...
}).filter(Boolean)
複製代碼
好比:
[0, undefined, false, 1, 23].map(item=>{ return item }).filter(Boolean)
>> [1, 23]
複製代碼
可使用{}
來建立一個看起來像空的對象,但該對象仍然有一個__proto__
和hasOwnProperty
和其餘對象方法。然而,有一種方法能夠建立一個純"dictionary"對象:
let dict = Object.create(null)
dict.__proto__ === "undefined"
>> false
複製代碼
在JavaScript中合併多個對象的需求一直存在,特別是當咱們開始建立類和帶有選項的組件時:
const person = {
name: 'David Walsh',
gender: 'Male'
}
const tools = {
computer: 'Mac',
editor: 'Atom'
}
const attributes = {
handsomeness: 'Extreme',
hair: 'Brown',
eye: 'Blue'
}
const summary = {...person, ...tools, ...attributes}
複製代碼
可以爲函數參數設置默認值是JavaScript的一個很棒的功能,但看看這個技巧,它要求爲給定的參數傳遞值:
const isRequired = () => {
throw new Error('param is required')
}
const hello = (name = isRequired()) => {
console.log(`hello ${name}`)
}
複製代碼
解構是一個很是受歡迎的JavaScript,但有時咱們更喜歡用其餘的名稱引用這些屬性,因此咱們能夠利用別名:
const obj = { x: 1}
const { x } = obj
const {x: otherName} = obj
複製代碼
多年來,咱們編寫粗糙的正則表達式來獲取查詢字符串值,但那些日子已經一去不復返了,輸入URLSearchParams
API便可:
// Assuming "?post=1234&action=edit"
var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?post=1234&action=edit&active=1"
複製代碼
有關於數組和對象更多的介紹能夠點擊:
這一期中咱們主要一塊兒聊了聊如何在限寬的容器中讓某部分實現全屏顯示,除了在結構上實現所需的效果以外,還能夠在單個元素上藉助一些CSS的特性來完成,好比負margin
和正padding
、或者負margin
和border
這樣的互負抵銷的方式;也可使用vw
和calc()
讓事情變得還更簡單。
display
是CSS的重要內容之一,@Rachel Andrew的三篇博文,讓咱們對CSS的display
有了一個更深層次的理解,在今年的佈局或者在使用display
會變得更明瞭。另外圖標是Web中經常使用的一部分,這裏羅列了字體圖標使用的一些教程以及如何藉助font-display
來讓字體加載讓用戶有一個更好的體驗。雖然font-display
能夠對字體加載作一些優化,但使用字體圖標依舊是有一些缺陷的,建議你們仍是考慮使用SVG圖標。
最後,把@David Walsh整理的幾個JavaScript小技巧列入到這一期,但願這些小技巧能在實際開發中給你們帶來一些幫助。