【本文會持續(xù)更新!】
1、color 影響 border-color
當只設置元素的邊框寬度和樣式時判呕,邊框的顏色會取當前元素 color
屬性的計算值。
<div style="color: blue;border: 1px solid;">這里設置了 border送滞,但不指定 border-color</div>
瞧瞧該實例元素的 border-color
屬性的計算值:
可以看到侠草,border-color
屬性未設置值時為 initial
關鍵字,代表取該屬性的默認值犁嗅。那么边涕,為什么這里取的是 color
屬性的值而非瀏覽器對 border-color
的默認值(如果有的話)呢?
因為 border-color
屬性的默認值就是 currentColor 關鍵字(CSS 3)褂微,也就是當前元素的 color
屬性的計算值功蜓,詳見 border-color | MDN。
color 前景色
MDN 中對 color
屬性是這樣介紹的:
The
color
property sets the foreground color of an element's text content, and its decorations. It doesn't affect any other characteristic of the element
翻譯過來就是宠蚂,color
屬性設置元素文本內容的 前景色 和 修飾式撼。
HTML 元素的前景色包括:
- 字體顏色,也就是狹義上的
color
肥矢; -
border-color
端衰,邊框的顏色; -
outline-color
甘改,輪廓的顏色旅东; -
box-shadow
,陰影的顏色十艾; -
text-shadow
抵代,文本陰影的顏色;
以及文本修飾中的 text-decoration-color
忘嫉,下劃線的顏色荤牍。
<head>
<style>
p {
color: blue;
max-width: 500px;
}
</style>
</head>
<body>
<p>這里沒有做任何處理</p>
<p style="border: 1px solid;">這里設置了 border案腺,但不指定 border-color</p>
<p style="outline: 1px solid;">這里設置了 outline,但不指定 outline-color</p>
<p style="text-decoration: underline;">這里設置了 text-decoration康吵,但不指定 text-decoration-color</p>
<p style="box-shadow: 0 1px 2px 0;">這里設置了 box-shadow劈榨,但不指定顏色</p>
<p style="text-shadow: 10px 10px 2px;">這里設置了 text-shadow,但不指定顏色</p>
</body>
2晦嵌、移動端 H5 禁止顯示系統(tǒng)菜單
當在移動端 H5 上長按一個目標元素時同辣,瀏覽器會彈出一個關于目標元素的菜單信息。請看下面針對文本元素的實例:
<span>這是一段文字惭载,請在移動端長按</span>
在某些場景下旱函,我們并不希望瀏覽器彈出這樣的菜單,應該怎么做呢描滔?我在網上搜羅了幾個常見方案:
-
通過 -webkit-touch-callout 屬性禁用 callout【無效】
-webkit-touch-callout: none;
-webkit-touch-callout
屬性的兼容性非常差棒妨,之前只有在 Safari 瀏覽器上可用。而 現(xiàn)在應該是被廢棄了含长,親測在 ios Safari 瀏覽器上不起效券腔,Can I use 上也已經搜索不到了。 -
JS 屏蔽 contextmenu 事件的默認行為【無效】
$elm.addEventListener('contextmenu', (e) => { e.preventDefault(); });
當用戶嘗試打開上下文菜單(通常是鼠標右鍵單擊)時拘泞,
contextmenu
事件會被觸發(fā)颅眶,我們可以通過preventDefault()
方法來屏蔽菜單的顯示。那么這種方法是否適用于移動端 h5 呢田弥?答案是否定的涛酗。不妨來看看
contextmenu
事件的兼容性:so,網上的部分教程就不要再誤人子弟了偷厦。
-
通過 user-select 屬性讓元素不可選中【有效】
-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none;
在移動端商叹,若用戶不可選中元素,自然也就不能通過長按調起默認菜單了只泼。但需要注意的是剖笙,
user-select: none
在部分瀏覽器(如 Safari)中會使<input>
、<textarea>
等表單元素失效请唱。 -
JS 屏蔽
touchstart
事件的默認行為【有效】$elm.addEventListener('touchend', (e) => { e.preventDefault(); });
此方案和使用
user-select
是一樣的原理弥咪,但同樣 需要注意禁止默認行為所帶來的負面影響,譬如作用于可滾動元素時十绑。
所有方案的測試情況見:https://codepen.io/JunreyCen/pen/rEBYPV
總結一下聚至,移動端的兼容性一直是非常棘手的問題,各種手機操作系統(tǒng)本橙、各種瀏覽器應用沒有一套統(tǒng)一的 web 標準扳躬,都喜歡 “各抒己見”。也因此镰踏,上面提及的方案在某些型號手機的瀏覽器中(譬如 Oppo 自帶的瀏覽器)依然是不起作用的柱告,這種情況下開發(fā)者只能 “見招拆招”,無招可使時也只能擇 “較優(yōu)解” 了桦沉。
3役纹、文本溢出顯示省略號
我們經常遇到單行文本溢出時顯示省略號的場景偶摔,那多行文本的類似處理該如何實現(xiàn)?
單行文本
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* 文本不換行 */
多行文本
多行文本溢出時促脉,最后一行截斷并顯示省略號啰挪。這里提供兩種實現(xiàn)方式:
-
使用 line-clamp 屬性
line-clamp
是一個不規(guī)范的屬性,沒有出現(xiàn)在 CSS 規(guī)范草案中嘲叔。而且,它必須結合舊版的flexbox
(伸縮盒)模型才起作用抽活。overflow: hidden; display: -webkit-box; /* 舊版伸縮盒模型 */ display: -moz-box; -webkit-box-orient: vertical; /* 子元素垂直排列 */ -moz-box-orient: vertical; -webkit-line-clamp: 2; /* 塊元素顯示的文本行數(shù) */ -moz-line-clamp: 2;
如下圖所示硫戈,
line-clamp
在兼容性方面還是有點缺陷的。除此之外還需要注意的是下硕,autoprefixer 等預處理插件會自動刪除一些舊的樣式屬性(包括
-webkit-box-orient
屬性)丁逝,所以使用這種方式時要對 autoprefixer 插件進行配置,詳見這個 issue 梭姓。 -
JS + CSS 手動加省略號
處理流程:
- 元素的
height
值設置為line-height
值的整數(shù)倍霜幼;
- JS 獲取元素的文本節(jié)點高度(
scrollHeight
),若高度倍
line-height
值則視為文本溢出誉尖; - 文本溢出時罪既,于元素右下方顯示省略號,否則不顯示铡恕;
<style> #ellipsis { position: relative; display: block; overflow: hidden; line-height: 20px; height: 40px; /* height 為整數(shù)倍 line-height */ word-break: break-all; /* 使文本填充滿容器琢感,利于省略號和文本的銜接 */ } .show-ellipsis { padding-right: 12px; /* 給省略號騰出空間 */ } .show-ellipsis:after { content: '...'; position: absolute; right: 0; bottom: 0; } </style> <p id="ellipsis">JS 和 CSS 設置多行文本字數(shù)超出時最后一行顯示省略號,JS 和 CSS 設置多行文本字數(shù)超出時最后一行顯示省略號</p> <script> const $elm = document.getElementById('js-ellipsis'); const style = window.getComputedStyle($elm); const limitHeight = +style.height.replace('px', '') + +style.lineHeight.replace('px', ''); if ($elm.scrollHeight >= limitHeight) { // 文本溢出則顯示省略號 $elm.className = 'show-ellipsis'; } </script>
這種實現(xiàn)方式基本不存在兼容性問題(除了低版本 IE 瀏覽器)探熔,但效果肯定比不上
line-clamp
的方式驹针,只能靜待 W3C 制訂一套規(guī)范的處理方案了。 - 元素的
4诀艰、圖像自適應
我們寫頁面的時候經常會遇到柬甥,獲取的圖片尺寸與我們所期待的渲染尺寸不符。譬如在渲染用戶頭像的場景下其垄,我們往往希望用戶上傳的圖片都是統(tǒng)一的正方形尺寸苛蒲,然而用戶給的可能是這樣的:
常見的處理方式是 適當?shù)募舨檬箞D片填滿容器而不被拉伸,我們可以利用背景圖(background-size
/ background-position
)來實現(xiàn):
<style>
.avatar {
width: 200px;
height: 200px;
border: 2px solid #07C160;
background: url('./images/captain.jpeg') no-repeat;
background-size: cover;
background-position: center;
}
</style>
<div class="avatar"></div>
CSS 3 中提供了新的屬性:object-fit绿满,可以對 <img>
標簽作寬高自適應處理撤防,效果類似于 background-size
屬性。
object-fit
提供了5個取值:
- none:內容保持原有尺寸;
- contain:內容保持寬高比地縮放寄月,內容和容器的寬高比不匹配時會 留下白邊辜膝;
- cover:內容保持寬高比地填滿容器,內容和容器的寬高比不匹配時會 被裁剪漾肮;
- fill:內容剛好填滿容器厂抖,內容和容器的寬高比不匹配時會 被拉伸;
- scale-down:內容尺寸和 none 或 contain 中的一個相同克懊,最終會顯示尺寸較小的那個忱辅;
background-size 和 object-fit 的效果對比
同樣的,background-position
和 object-position 的作用類似谭溉,比較明顯的區(qū)別在于:
background-position
的默認值是0% 0%
墙懂,而object-position
的默認值是50% 50%
。
object-fit 的意義
- 解放了
background-image
的能力扮念;
譬如可以同時利用background-image
和<img>
標簽完成圖片的堆疊等损搬。 -
object-fit
對所有 可替換元素 都有效;
常見的可替換元素包括:<iframe>
柜与、<video>
巧勤、<embed>
、<img>
弄匕、<input type="image">
颅悉。
兼容性
額,如果要兼容 IE 瀏覽器的話迁匠,還是乖乖用背景圖的方式把剩瓶。
5、塊元素等比縮放
現(xiàn)在的網頁開發(fā)都講究響應式設計城丧,以使在各種尺寸的設備上也能保持良好的 UI 呈現(xiàn)儒搭。在響應式布局中,我們經常需要實現(xiàn)隨網頁視窗寬度動態(tài)變化的元素芙贫,尤其是支持等比縮放的元素搂鲫。
比較傳統(tǒng)的做法,是通過 JS 監(jiān)聽 resize
事件磺平,動態(tài)獲取容器的寬度然后調整元素的寬高魂仍。這里提供一種純 CSS 實現(xiàn)的方式,主要利用的是 padding
屬性的百分比取值:
padding
屬性的百分比取值是相對于其包含塊的寬度拣挪。
所以擦酌,當包含塊的寬度發(fā)生變化時,子元素的 padding
屬性的計算值會隨之發(fā)生變化菠劝,也就是說子元素的總寬高都會被改變赊舶,且與包含塊寬度成正比。
<style>
.wrapper {
width: 200px;
height: 300px;
border: 2px solid #07C160;
}
.content {
padding: 50%;
width: 0;
height: 0;
background-color: #FA5151;
}
</style>
<div class="wrapper">
<div class="content"></div>
</div>
接下來的工作,只需要讓目標元素的寬高參考于 padding
子元素的寬高笼平,就完成了元素的等比縮放园骆。我們可以利用 絕對定位 來實現(xiàn)。
這里實現(xiàn)一個寬高比為 1:2寓调、寬度保持為容器的等比縮放元素:
<style>
.wrapper {
width: 20%;
height: 40%;
border: 2px solid #07C160;
}
.container {
position: relative;
padding: 50%;
width: 0;
height: 0;
}
.content {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: #FA5151;
}
</style>
<div class="wrapper">
<div class="container">
<div class="content"></div>
</div>
</div>
為了突出演示效果锌唾,稍微 “修飾” 了一下:
需要體驗 Demo 的請?zhí)D:https://codepen.io/JunreyCen/pen/agzoyG
6、垂直外邊距合并
當兩個垂直外邊距鄰接時夺英,會合并成一個外邊距晌涕。只有普通文檔流中塊元素的垂直外邊距才會發(fā)生合并,不在同一個 BFC 內(譬如行內元素痛悯、浮動元素余黎、絕對定位等)的垂直外邊距不會合并,水平方向的外邊距也不會合并载萌。
通常發(fā)生外邊距合并的場景有:
-
相鄰的兩個塊元素惧财,鄰接的上/下外邊距發(fā)生合并
圖片摘自 http://www.w3school.com.cn/css/css_margin_collapsing.asp發(fā)生合并時外邊距的計算規(guī)則:
- 兩個外邊距都是正數(shù)時,取兩者中的較大值炒考;
- 兩個外邊距一正一負時,取兩者之和霎迫;
- 兩個外邊距都是負數(shù)時斋枢,比較兩者的絕對值大小,誰大取誰知给;
-
無內邊距(
padding
)和邊框(border
)的父元素的垂直外邊距會與子元素的垂直外邊距合并圖片摘自 http://www.w3school.com.cn/css/css_margin_collapsing.asp -
無內邊距(
padding
)瓤帚、邊框(border
)和內容(content
)的空元素的上/下外邊距會合并圖片摘自 http://www.w3school.com.cn/css/css_margin_collapsing.asp
這里提供一個完整 Demo:https://codepen.io/JunreyCen/pen/zVxPWX
7、行內(塊)元素空隙
試試執(zhí)行這段代碼:
<img src="./images/captain.jpeg" width="200">
<img src="./images/captain.jpeg" width="200">
奇怪涩赢,兩張圖片之間出現(xiàn)了一道縫隙……
這是因為 img
元素默認會被渲染成行內元素(display: inline;
)戈次,而上述代碼中兩個 <img>
之間其實是存在一個 換行符 (以及若干個 制表符)的,這些都會被渲染成一個空白格筒扒,也就導致了縫隙的產生怯邪。
解決辦法有倆:
- 寫 HTML 代碼的時候避免行內元素間的空格、換行符等特殊字符花墩;
<img src="./images/captain.jpeg" width="200"><img src="./images/captain.jpeg" width="200">
- 把行內元素所在行的字體大小設為
font-size: 0;
<style> body { font-size: 0; } </style> <img src="./images/captain.jpeg" width="200"> <img src="./images/captain.jpeg" width="200">
PS:行內塊元素(
display: inline-block
)也會存在同樣的問題悬秉。
8、pointer-events: none;
pointer-events
屬性可以指定元素是否可以成為鼠標事件的 target 冰蘑,通俗點講就是該元素是否可以接收鼠標事件和泌。
pointer-events
屬性有多種取值,詳見 MDN祠肥。這里著重介紹取值 none
:
pointer-events: none;
指定元素及其后代元素不會成為鼠標事件的 target武氓,父元素不受影響。
實驗 Demo
實驗內容:三層 DOM 元素都監(jiān)聽了鼠標點擊事件,其中 target 節(jié)點設置了 pointer-events: none
县恕,點擊 child 元素东羹,看看有哪層元素可以響應點擊事件。
<div class="parent" onclick="alert('parent')">
<div class="target" onclick="alert('target')">
<div class="child" onclick="alert('child')"></div>
</div>
</div>
左邊不作處理的實例會 alert
三次弱睦;而右邊的實例只會 alert
一次百姓,內容為 parent
。
應用場景
-
同層元素點擊穿透
我們在寫 UI 基礎組件時况木,多多少少會接觸到 Field 輸入框組件垒拢。比如下面的實例,需求是滿足 0.5px 邊框 + input 輸入框火惊。
<style> .field { position: relative; width: 250px; height: 50px; text-align: center; } .field:after { position: absolute; top: -50%; left: -50%; right: -50%; bottom: -50%; content: ''; border: 1px solid #ccc; transform: scale(0.5); } </style> <div class="field"> <input type="text" placeholder="請輸入"> </div>
你會發(fā)現(xiàn)求类,左邊的輸入框無法聚焦。這其實跟 0.5px 邊框的實現(xiàn)方式有關屹耐,實例中利用偽元素
:after
制造了一個2倍尺寸的子元素尸疆,然后通過transform: scale(0.5)
縮放,從而實現(xiàn) 0.5px 邊框惶岭。然而寿弱,**這個偽元素和input
輸入框屬于同層元素,根據渲染的先后順序偽元素是層疊于輸入框之上的按灶,所以鼠標點擊事件是無法被輸入框捕獲的症革。我們只需要給偽元素設置
pointer-events: none;
,使其無法成為鼠標事件的 target鸯旁,input
輸入框就可以成功被聚焦噪矛。 -
阻止 :hover、:active 等鼠標行為狀態(tài)的觸發(fā)
設置了
pointer-events: none;
的元素無法響應鼠標事件铺罢,自然也就無法觸發(fā)相關的狀態(tài)了艇挨。
想體驗實例的請訪問:https://codepen.io/JunreyCen/pen/NZqKOx。
9韭赘、:first-child 和 :first-of-type 的區(qū)別
:first-child
匹配其父元素的符合特定類型的首個子元素缩滨。條件更為苛刻,需要滿足 首個子元素 + 符合特定類型泉瞻。:first-of-type
匹配其父元素的符合特定類型的第一個元素楷怒。條件較為寬松,在滿足 符合特定類型 的范疇下尋找第一個元素即可瓦灶。
<style>
.group-1 h2:first-child,
.group-1 h3:first-child,
.group-2 h2:first-of-type,
.group-2 h3:first-of-type {
color: #FA5151;
}
</style>
<div class="group-1">
<h2>父元素的第一個元素鸠删,第一個 h2 元素</h2>
<h3>父元素的第二個元素,第一個 h3 元素</h3>
</div>
<div class="group-2">
<h2>父元素的第一個元素贼陶,第一個 h2 元素</h2>
<h3>父元素的第二個元素刃泡,第一個 h3 元素</h3>
</div>
10巧娱、當心分號 ;
我們都知道,在樣式表的聲明塊({...}
)內烘贴,樣式聲明之間會用分號隔開禁添,這是因為引擎在解析時,每條聲明之間的空格(包括換行符等)會被忽略:
<style>
div {
color: red;
font-size: 20px;
}
</style>
<div>content</div>
那如果桨踪,分號寫在聲明塊之外呢老翘?
這相當于告訴引擎,樣式表解析到這里就結束了锻离,后面的東西就不用管了铺峭。來看看這個 demo:
<style>
div {color: red};
.ctn-1 {color: blue}
.ctn-2 {font-weight: 600}
</style>
<div id="ctn-1">藍色字體</div>
<div id="ctn-2">加粗字體</div>
遇到類似的面試題時,就要注意仔細看別被 “坑” 了~