博客 / 詳情

返回

CSS 技術沉澱

基礎理論

元素的顯示與隱藏

根據不同的需求選擇隱藏方案

如果希望元素不可見,同時不佔據空間,輔助設備無法訪問,同時不渲染,使用script標籤隱藏

<script type="text/html">

      <img src="./img/55.png" />

</script>

獲取數據的方法使用 document.querySelector('script').innerHTML

如果希望元素不可見,同時不佔據空間,輔助設備無法訪問,但資源有加載,DOM可訪問,則可以直接使用display:none隱藏

.dn{

    display:none;

}

如果希望元素不可見,同時不佔據空間,輔助設備無法訪問,但顯隱的時候可以有transition淡入淡出效果

.hidden {

    position: absolute;

    visibility: hidden;

}

如果希望元素不可見,不能點擊,輔助設備無法訪問,但佔據空間保留則可以使用visibility:hidden隱藏

.vh {

    visibility: hidden;

}

如果希望元素不可見,不能點擊,不佔據空間,但鍵盤可訪問,則可以使用clip裁剪隱藏

.clip {

    position: absolute;

    clip: rect(0 0 0 0);

}

案例:1.請帖生成封面。2.鍵盤使用快捷鍵但不顯示按鈕(使用 accesskey

如果希望元素不可見,不能點擊,但佔據空間,且鍵盤可訪問,則可以使用relative隱藏。如果條件允許,也就是上一層層疊上下文之間設置了背景色,則可以使用更友好的z-index負值隱藏

.out {

    position: relative;

    left:-999em;

}

.lower {

    position: relative;

    z-index: -1;

}

如果希望元素不可見,但可以點擊,而且不佔據空間,則可以使用透明度

.opacity {

    position: absolute;

    opacity: 0;

}

如果希望元素不可見,但位置保留,依然可以點可以選,則直接讓透明度為0

.opacity{

    opacity: 0;

}

如果希望元素在顯示時有一個 transition 動畫,可以使用 max-height 進行隱藏

.hidden {

    max-height: 0;

    overflow: hidden;

}

display與元素的顯隱

基礎瞭解:無法點擊,無法使用屏幕閲讀器等輔助設備訪問,佔據空間消失

深層瞭解:img標籤上或父元素設置 display:none 都會加載資源。但是 background-image 請求的資源在該標籤上或父元素設置 display:none 都不會加載資源(safari和chrome驗證),在計數中設置了display:none的元素不被計入。會對 IntersectionObserver 造成影響

visibility與元素的顯隱

基礎瞭解:無法點擊,無法使用屏幕閲讀器等輔助設備訪問,佔據空間不消失

深層瞭解:visibility 具有繼承性,父級設置 visibility:hidden 後子級可以設置 visibility:visible 顯示子元素。設置了 visibility:hidden 的元素會加載img資源也會加載 background-image 資源。同時也會被納入計數。visibility 屬性被納入 transition 的範圍內,因此可利用該屬性展示元素從隱藏到顯示的過渡效果。但是該屬性不會對 IntersectionObserver 造成影響,也就是説如果彈窗是從隱藏到顯示使用了該屬性的話,對它進行埋點是無效的。

文本的換行

word-break

當行尾放不下一個單詞時,決定單詞內部該怎麼擺放(決定不斷行單詞的長度)

nomal:默認值,默認的換行規則(CJK文本斷行,英文單詞不斷行,空格斷行)

break-all:對於non-CJK(中日韓)文本,可在任意地方斷行

keep-all:CJK文本不斷行,non-CJK文本表現形式如同nomal

word-wrap

是用來説明當一個不能被分開的字符串太長而不能填充其包裹盒時,為防止其溢出,瀏覽器是否允許這樣的單詞斷詞(沒有換行點的單詞在句尾放不下時,決定單詞是否斷詞)

nomal:默認值,行只能在正常的單詞斷點處中斷。(例如兩個單詞之間的空格)。

break-word:表示如果行內沒有多餘的地方容納該單詞到結尾,則那些正常的不能被分割的單詞會被強制分割換行。

white-space

如何處理元素中的空白

nomal:默認值,連續的空白符被合併,換行符被當做空白符處理

nowrap:連續的空白符被合併,文本內的換行符無效(
有效)

pre:連續的空白符會被保留,在遇到換行符或者
元素時才會換行

pre-wrap:連續的空白符會被保留,在遇到換行符或者
元素,或者為了填充行框盒子(line-box)時才會換行

pre-line:連續的空白符會被合併,在遇到換行符或者
元素,或者為了填充行框盒子(line-box)時才會換行

line-break

中文標點的換行規則,比如是避首標點,是避尾標點,通過此屬性控制CJK文本標點的換行規則

auto:使用默認的換行規則。

loose: 使用限制性最小的換行規則分隔文本。通常用於短行,如在報紙上。

normal:使用最普通的換行規則。

strict: 使用最嚴格的換行規則。

anywhere:任意位置都可以作為換行點,包括任意的標點。

<wbr>

這是html元素,寬度不夠,在我這裏換行;寬度足夠,還是一行顯示

實現原理

wbr::after{

  content: '\00200B'

}

光標屬性cursor

https://developer.mozilla.org...

flex子項最終尺寸計算規則

一個flex子項的最終尺寸是基礎尺寸(或內容尺寸),彈性增長或收縮,最大最小尺寸共同作用的結果

最終尺寸計算的優先級是:

最大最小尺寸限制 > 彈性增長或收縮 > 基礎尺寸

  • 基礎尺寸有 flex-basis 屬性或 width 屬性,以及 box-sizing 盒模型共同決定
  • 內容尺寸指最大內容寬度,當沒有設置基礎尺寸時會頂替基礎尺寸的角色
  • 彈性增長指的是 flex-grow 屬性,彈性收縮指的是 flex-shrink 屬性
  • 最大尺寸主要受 max-width 屬性顯示;最小尺寸受最小內容寬度,width 屬性和 min-width 屬性共同影響

flex容器:
flex-wrap:nowrap;
flex-direction:row;
justify-content:flex-start;
align-items:stretch;為默認值

flex: 0 1 auto 這是flex子項的默認值,代表flex-grow:0,flex-shrink:1,flex-basis: auto

最小尺寸計算規則

  • 如果 min-width 屬性值不是 auto,則元素的最小尺寸就是就是 min-width 的屬性值,此時 width 屬性無法影響最小尺寸,哪怕 width 的屬性值大於 min-width 的屬性值。
  • 比較 width 的屬性的計算值和最小內容寬度的大小,較小的值就是元素的最小尺寸。
  • 如果 width 的屬性值和 min-width 的屬性值均為 auto,則元素的最小尺寸就是最小內容寬度。
  • 如果flex子項設置了 overflow:hidden,且最小尺寸是由是否最小內容寬度決定的,則最小尺寸無效。

基礎尺寸計算規則

  • 如果 flex-basis 屬性和 width 屬性同時設置了具體的數值,width 屬性值會被忽略,優先使用 flex-basis 作為基礎尺寸。
  • 如果 flex-basis 的屬性值是初始值 auto,則會使用 width 屬性設置的長度值作為基礎尺寸。
  • 如果 flex-basiswidth 的屬性值都是 auto,則會使用flex子項的最大內容寬度作為基礎尺寸

彈性增長或收縮何時作用

  • 如果容器尺寸足夠並且子元素的屬性值包含 flex-grow 不為0則啓用彈性增長規則
  • 容器尺寸足夠:在容器 flex-wrap:wrap 狀態下,n個子元素的基礎尺寸相加寬度少於容器寬度,n+1個子元素的基礎尺寸相加大於容器,且這n個子元素中具有 flex-grow 不為0的元素,則這n個子元素具備彈性增長的條件。在容器 flex-wrap:nowrap 狀態下,所有子元素基礎尺寸相加寬度少於容器寬度。
  • 如果容器尺寸不足並且子元素的屬性值包含 flex-shrink 不為0則啓用彈性收縮規則
  • 容器尺寸不足:在容器 flex-wrap:wrap 狀態下,子元素的基礎尺寸大於容器寬度,且子元素的 flow-shrink 不為0,則這個子元素具備彈性收縮條件。在容器 flex-wrap:nowrap 狀態下,所有子元素的基礎寬度少於容器寬度,且至少有一個子元素的 flex-shrink 不為0,則 flex-shrink不為0的子元素具備彈性收縮條件。
  • 彈性增長,增長的部分是可分配空間,計算規則是容器寬度-元素基礎尺寸
  • 彈性收縮,收縮的部分是有 flex-shrink 不為0元素的寬度,最多可以收縮至元素最小尺寸。

最終尺寸計算規則-總結

  • 如果沒有彈性收縮或增長,則元素在最大尺寸和最小尺寸範圍內使用基礎尺寸
  • 如果元素能夠彈性增長或收縮,在容器寬度足夠的情況下使用彈性增長規則,在容器寬度不足的情況下使用彈性收縮規則,同一行只可能應用一種規則

選擇器

選擇器優先值計算

選擇器 計算值 計算細則
* {} 0 1個0級統配選擇器,優先級數值為0
dialog {} 1 1個1級標籤選擇器,優先級數值為1
ui > li {} 2 2個1級標籤選擇器,1個0級選擇器,優先級數值為2
li > ol + ol {} 3 3個1級標籤選擇器,2個0級選擇器,優先級數值為3
.foo {} 10 1個2級類名選擇器,優先級數值為10
a:not([rel=nofollow]) {} 11 1個2級屬性選擇器,1個1級標籤選擇器,1個0級否定偽類,優先級數值為11
a:hover {} 11 1個1級標籤選擇器,1個2級偽類,優先級數值為11
ol li.foo {} 12 2個1級標籤選擇器,1個2級類名選擇器,優先級數值為12
li.foo.bar {} 21 1個1級標籤選擇器,2個2級類名選擇器,優先級數值為21
#foo {} 100 1個3級ID選擇器,優先級數值為100
#foo .bar p {} 111 1個3級ID選擇器,1個2級類名選擇器,1個1級標籤選擇器,優先級數值為111

相同計算值下遵循後來居上原則,後面的優先級更高

命名靈感

從HTML標籤尋找靈感

.cs-module-header {}

.cs-module-body {}

.cs-module-aside {}

.cs-module-main {}

.cs-module-nav {}

.cs-module-section {}

.cs-module-content {}

.cs-module-summary {}

.cs-module-detail {} // 詳情

.cd-module-option {}

.cs-module-img {}

.cs-module-footer {}

.cs-module-ui {}

.cs-module-li {} // 列表子項

.cs-module-a {} // 鏈接

.cs-module-g {} // 組

.cs-module-desc {} // 描述

.cs-module-x {} // 容器盒子

從HTML特定屬性值中尋找靈感

.cs-radio {}

.cs-checkbox {}

.cs-range {}

.cs-tspan-email {}

.cs-tspan-number {}

.cs-tspan-color {}

.cs-tspan-tel {}

.cs-tspan-date {}

.cs-tspan-url {}

.cs-tspan-time {}

.cs-tspan-file {}

從無障礙訪問的role屬性值中尋找靈感

.cs-grid {}

.cs-grid-cell {}

.cs-log {}

.cs-menu {}

.cs-menu-bar {}

.cs-menu-item {}

.cs-region {} // 不能被其他role描述,但是很重要的部分

.cs-banner {} // 橫幅廣告

.cs-slider {}

.cs-tab {}

.cs-tab-list {}

.cs-tab-pannel {}

.cs-tooltip {}

.cs-tree {}

從CSS偽類和HTML布爾屬性中尋找靈感

.active {}

.disabled {}

.selected {}

.checked {}

.invalid {} // 出錯狀態

體驗優化

圖片加載失敗體驗優化

<img src="xxx.png" alt="圖片封面" onerror="this.classList.add('error');">
img.error {

  display: inline-block;

  transform: scale(1);

  content: '';

  color: transparent;

}

/* 替換圖片 */

img.error::before {

  content: '';

  position: absolute;

  left: 0; top: 0;

  width: 100%; height: 100%;

  background: #f5f5f5 url(break.svg) no-repeat center / 50% 50%;

}

/* alt 提示 */

img.error::after {

  content: attr(alt);

  position: absolute;

  left: 0; bottom: 0;

  width: 100%;

  line-height: 2;

  background-color: rgba(0,0,0,.5);

  color: white;

  font-size: 12px;

  text-align: center;

  white-space: nowrap;

  overflow: hidden;

  text-overflow: ellipsis;

}

點擊體驗優化

移動端按鈕可點擊範圍放大

.mobi-btn {

    border: 8px solid transparent;

}

鍵盤體驗優化

可訪問性-焦點控制

tabindex = "-1"

元素可以被鼠標或JS focus但不能被鍵盤focus

tabindex = "0"

最後一個被focus的元素

tabindex >= "1"

越小優先級越高

若進入網頁沒有點擊則按照1,2,...,0

若點擊則定位到點擊的主體,按下tab尋找到第一個有focus的元素,再次按下根據該元素的tabindex尋找下一個焦點

:focus-visible

讓我們知道元素的聚焦行為是鍵盤觸發還是鼠標觸發

// 鼠標觸發

:focus:not(:focus-visible) {}

// 鍵盤觸發

:focus:focus-visible {}

當前獲得焦點的元素

document.activeElement

檢測文檔是否獲取了焦點

document.hasFocus()

滾動體驗優化

overscroll-behavior

overscroll-behavior: [ contain | none | auto ]{1,2} 當只有一個值時代表水平垂直方向都是該值,有兩個值時第一個代表水平方向第二個代表垂直方向

auto:滾動到邊緣後繼續滾動外部的可滾動容器

contain:默認的滾動溢出行為只會表現在當前元素的內部,不會對相鄰的滾動區域進行滾動。

none:相鄰的滾動區域不會發生滾動,並且會阻止默認的滾動溢出行為。

scroll-behavior

在可滾動的容器上使用,常用於到達頂部

auto:默認值

smooth:平滑滾動,與 ant-designscrollToFirstError 搭配效果佳

overflow-anchor

auto: 默認值,該行為會調整位置以最大程度的減少內容偏移(例如上方圖片的突然加載會無感知)

none:退出瀏覽器滾動錨定行為

隱藏滾動條,同時元素可滾動

.scroll-none {

    scrollbar-width: none;

}

// chrome 私有方法

.scroll-none::-webkit-scrollbar {

    width:0; height:0;

}

跳轉體驗優化

PC端跳轉同一個地址不創建新的tab頁

<a href="https://www.baidu.com" target="bd">點擊進入百度</a>

target相同時會指向同一個tab頁

輸入體驗優化

cater-color屬性改變插入光標顏色

cater-color: red

移動端喚起數字鍵盤

驗證碼:<input inputmode="numeric">

拉伸行為體驗優化

rezize

none: 默認值,沒有拉伸效果,可以用來種植 textarea 元素默認的拉伸行為

both:既可以水平方向拉伸,也可以垂直方向拉伸

horizontal:僅可以水平方向上拉伸

vertical:僅可以垂直方向上拉伸

生效條件

塊級元素且 overflow 的屬性值不是 visible

限制拉伸範圍

使用 max-width,max-height,min-width,min-height 屬性

選擇行為體驗優化

user-select

text:默認值,文字和圖片可以被選中

none:禁止圖文被選中

all:被低估的一個屬性值,設置了該屬性的圖文內容都會被選中

::selection

被選中時偽類,全局設置時可設置品牌顏色為背景,合適顏色為字體顏色

::selection {

    color: hunlijiColor;

    background: hunlijuBackgroundColor;

}

刷新體驗優化

刷新時滾動條回到頂部

if (history.scrollRestoration) {

  history.scrollRestoration = 'manual';

}

打印行為體驗優化

控制打印樣式的媒體查詢

@media print {

    header{

        display:none;

    }

}

是否進行精確打印

color-adjust

economy:默認值,可能會將背景不打印

exact:精確打印

table{

    -webkit-print-color-adjust: exact;

    color-adjust: exact;

}

使該元素另起一頁打印

break-before:page

性能優化

will-change

will-change 的作用有兩個,一個是創建合成層,一個在真正的行為觸發之前告訴瀏覽器:“我要變化了,你要做好準備”

如何正確的使用

will-change 不應該被設置在默認狀態中且需要及時銷燬,理想中的應用場景應該是 hover 狀態下

// good

.will-change-parent:hover .will-change{

    will-change:transform;

}

.will-change {

    transition: transform 0.3s;

}

.will-change:hover {

    transform: scale(1.5)

}

// bad

.will-change {

    transition: transform 0.3s;

}

.will-change:hover{

    will-change: transform;

    transform: scale(1.5);

}

如果點擊按鈕,某個元素執行動畫,先執行的是 mousedown 事件,之後執行的是 click 事件

dom.onmousedown = function() {

    target.style.willChange = 'transform'

}

dom.onclick = function() {

    // target元素執行動畫

}

target.onanimationend = function() {

    // 動畫結束,用回調函數移除will-change屬性

    this.style.willChange = 'auto'

}

創建合成層

無法複製加載中的內容

  • 合成層的位圖會交由 GPU 合成,比 CPU 處理要快得多
  • 當需要 repaint 時,只需要 repaint 本身,不會影響其他層
  • 元素提升為合成層後,transformopacity 不會觸發 repaint,如果不是合成層則依舊會觸發 repaint

避免隱式創建合成層及優化

合成層比較佔用內存,假如一個合成層的寬高為100px 100px,則合成層佔用內存的計算方式為100100*3 = 30000Byte = 30KB

當元素交疊,處在下方的元素成為了合成層,上方的元素隱式變成了合成層

  • 可以將必須合成層的層級提升至較高層級,則其他交疊層級沒有該層級高就不會隱式創建合成層
  • 動畫使用 transform 實現,一方面如果不涉及到 translateZ 則不會創建合成層,一方面生成層疊上下文不會影響到別的層疊上下文渲染
  • 通過減少寬高再進行 scale 放大的方式可以有效減少合成層使用的內存

SEO

H1標籤一個頁面只能用一個

同一網頁通過多個網址訪問指定規範網址

<link rel="canonical" href="http://www.hunliji.com/merchant/detail_1378">

關鍵詞

<meta data-hid="keywords" name="keywords" content="關鍵詞1,關鍵詞2">

詳細描述

<meta data-hid="description" name="description" content="描述內容,字數在0-200字為佳">

不需要抓取的鏈接nofollow

<a href="www.baidu.com" rel="nofollow">

指定為外部鏈接external

<a href="www.baidu.com" rel="external nofollow">

指定頁面圖標

<link rel="icon" type="image/png" href="/path/to/icons/favicon-16x16.png" sizes="16x16">

<link rel="icon" type="image/png" href="/path/to/icons/favicon-32x32.png" sizes="32x32">

很少用的屬性

將中文簡體轉換為繁體

蘋方字體有效,老老實實做i18n吧哈哈

font-variant-east-asian: traditional;
user avatar guizimo 頭像 susouth 頭像 jianqiangdepaobuxie 頭像 weirdo_5f6c401c6cc86 頭像 pugongyingxiangyanghua 頭像 dashnowords 頭像 mmmy_a 頭像 lihaixing 頭像 thehumble 頭像 y_lucky 頭像
10 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.