件多了,收拾出一個列表來能方便檢索和整理,用dirhtml能簡單快捷的生成一個網頁文件html,在一頁上顯示文件列表。
圖標
2.運行dirhtml后,選擇“雜項”,可以勾選需要顯示的文件的基本屬性相關內容進行調整。
選擇“雜項”
3.設置“在一個文件中顯示所有鏈接”,不要選“每個文件夾生成一個HTML”,否則,生成的文件個數將等于你選擇目錄中的文件夾的個數。然后可以對需要生成的版面項目進行設置。
選擇“在一個文件中顯示所有鏈接”
4.然后,點擊“文件夾,文件”選項,選擇文件夾的路徑。
選擇文件夾
5.點擊“創建”。
創建完成
6.打開文件后顯示效果。
頁面效果
/ 阿里淘系 F(x) Team - 大貘
前幾天在 F(x) Team.午夜識堂 和大家聊了一下 CSS 方面的話題,即 CSS 新特性。
在這個話題中主要整理了有關于 CSS 方面的特性,并且盡可能的整理了一些大家現在能用或過不了多久就能用的屬性。另外,雖然標題是“新特性”,但其中有蠻多特性并不是“新”,可能已經出現在你的項目中,或者你已經看過,只是不了解而以。接下來,就和大家一起來簡單地回顧一下這些性,希望大家能喜歡,也希望對大家平時工作有所幫助。
CSS 等比縮放一般指的是 “容器高度按比例根據寬度改變”,很多時候也稱為寬高比或縱寬比。 眾所周知,我們開發 Web 頁面要面對的終端更復雜的了,而這些終端的寬高比都不一樣。常見的比例有:?
特別是在做媒體相關開發的同學,比如視頻、圖像等,這方面的需求會更多,比如 Facebook 上的圖片,視頻展示:?
CSS 在還沒有 _aspect-ratio_ 之前,常使用一些 Hacck 手段來實現實類似的效果,即使用 padding-top 或 padding-bottom 來實現:?
<aspectratio-container>
<aspectratio-content></aspectratio-content>
</aspectratio-container>
<style>
.aspectratio-container {
width: 50vmin; /* 用戶根據自己需要設置相應的值 */
/* 布局方案可以調整 */
display: flex;
justify-content: center;
align-items: center;
}
/* 用來撐開aspectratio-container高度 */
.aspectratio-container::after {
content: "";
width: 1px;
padding-bottom: 56.25%;
/*元素的寬高比*/
margin: -1px;
z-index: -1;
}
</style>
?
有了 CSS 自定義屬性之后,可以結合 calc() 函數來實現容器等比縮放的效果:?
.container {
--ratio: 16/9;
height: calc(var(--width) * 1 / (var(--ratio)));
width: 100%;
}
?
雖然比padding-top 這樣的Hack 手段簡單,但相比原生的aspect-ratio還是要復雜的多。即:?
.container {
width: 100%;
aspect-ratio: 16 / 9;
}
下面這個示例演示了這三種不同方案實現寬比的效果:
Demo: https://codepen.io/airen/full/ExWjeZr
?
還可以通過 @media 讓元素在不同的終端上按不同的比例進行縮放:?
.transition-it {
aspect-ratio: 1/1;
transition: aspect-ratio .5s ease;
@media (orientation: landscape) { & {
aspect-ratio: 16/9;
}}
}
在 Web 布局中,時常會碰到內容溢出容器的現狀,如果 overflow 設置為 auto 或 scroll 時容器會出現水平或垂直滾動條:?
為了給用戶提供更好的滾動體驗,CSS 提供了一些優化滾動體驗的 CSS 特性,其中滾動捕捉就是其中之一。CSS 的滾動捕捉有點類似于 Flexbox 和 Grid 布局的特性,分類可用于滾動容器的屬性和滾動項目的屬性:?
有了滾動捕捉特性,我們要實現類似下圖的效果就可以不需要依賴任何 JavaScript 庫或腳本:?
就是每次滾動時,圖片的中心位置和容器中心位置對齊(想象一下 Swiper 的效果)。關鍵代碼就下面這幾行:?
.container {
scroll-behavior: smooth;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
scroll-padding: 20px;
}
img {
scroll-snap-align: center;
scroll-snap-stop: always;
}
Demo: https://codepen.io/airen/full/mdRpboo
利用該特性,還可以實現類似 iOS的一些原生交互效果:
Demo: https://codepen.io/airen/full/PoWQPvN
要是再利用一點點JavaScript腳本,還可以實現沉浸式講故事的交互效果:?
Demo: https://codepen.io/airen/full/qBRxNOo
CSS 的 gap 屬性的出現,幫助我們解決了以前一直比較麻煩的布局效果:?
正如上圖所示,設計師期望的一個效果是,緊鄰容器邊緣沒有任何間距,但相鄰項目之間(水平或垂直方向)都有一定的間距。在沒有 gap 屬性之前使用 margin 是很煩人的,特別是多行多列的時候更麻煩。有了 gap 僅需要一行代碼即可。?
CSS 的 gap 屬性是一個簡寫屬性,分為 row-gap 和 column-gap :?
該屬性 gap 到目前為止只能運用于多列布局,Flexbox布局和網格布局的容器上:?
// 多列布局
.multi__column {
gap: 5ch
}
// Flexbox布局
.flexbox {
display: flex;
gap: 20px
}
// Grid布局
.grid {
display: grid;
gap: 10vh 20%
}
gap 屬性可以是一個值,也可以是兩個值:?
.gap {
gap: 10px;
}
// 等同于
.gap {
row-gap: 10px;
column-gap: 10px
}
.gap {
gap: 20px 30px;
}
// 等同于
.gap {
row-gap: 20px;
column-gap: 30px;
}
如果 gap 僅有一個值時,表示 row-gap 和 column-gap 相同。?
國內大多數 Web 開發者面對的場景相對來說比較單一,這里所說的場景指的是書寫模式或排版的閱讀模式。一般都是 LTR (Left To Right)。但有開發過國際業務的,比如阿拉伯國家的業務,就會碰到 RTL (Right To Left) 的場景。比如你打開 Facebook ,查看中文和阿拉伯文兩種語言下的 UI 效果:?
在沒見有邏輯屬性之前,一般都會在 <html> 或 <body> 上設置 dir 屬性,中文是 ltr ,阿拉伯語是 rtl ,然后針對不同的場景運用不同的 CSS 樣式:?
其實,閱讀方式除了水平方向(ltr 或 trl)之外,還會有垂直方向的閱讀方式:?
?
為了讓 Web 開發者能更好的針對不同的閱讀模式提供不同的排版效果,在CSS新增邏輯屬性。有了邏輯屬性之后,以前很多概念都有所變化了。比如我們以前熟悉的坐標軸,x 軸和 y 軸就變成了 inline 軸 和 block 軸,而且這兩個軸也會隨著書寫模式做出調整:?
除此之外,我們熟悉的 CSS 盒模型也分物理盒模型和邏輯盒模型:?
你可能感知到了,只要是以前帶有 top、right 、bottom 和 left 方向的物理屬性都有了相應的 inline-start 、 inline-end 、block-start 和 block-end 的邏輯屬性:?
我根據 W3C 規范,把物理屬性和邏輯屬性映射關系整了一份更詳細的表:?
?
回到實際生產中來:?
如果不使用邏輯屬性的話,要實現類似上圖這樣的效果,我們需要這樣來編寫 CSS:?
.avatar {
margin-right: 1rem;
}
html[dir="rtl"] .avatar {
margin-right: 0;
margin-left: 1rem;
}
有了 CSS 邏輯屬性之后,僅一行 CSS 代碼即可實現:?
.avatar {
margin-inline-end: 1rem;
}
簡單多了吧,特別是有國際化需求的開發者,簡直就是一種福音。
CSS 媒體查詢 @media 又稱為 CSS 條件查詢。在 Level 5 版本中提供了一些新的媒體查詢特性,可以查詢到用戶在設備上的喜好設置:
比如:?
?
使用的方式和以往我們熟悉的 @media 是相似。比如 prefers-color-scheme 實現暗黑查式的皮膚切換效果:?
// 代碼源于: https://codepen.io/airen/full/ProgLL
// dark & light mode
:root {
/* Light theme */
--c-text: #333;
--c-background: #fff;
}
body {
color: var(--c-text);
background-color: var(--c-background);
}
@media (prefers-color-scheme: dark) {
:root {
/* Dark theme */
--c-text: #fff;
--c-background: #333;
}
}
?
還可以根據網格數據設置來控制資源的加載:?
@media (prefers-reduced-data: reduce) {
header {
background-image: url(/grunge.avif);
}
}
@media (prefers-reduced-data: no-preference) {
@font-face {
font-family: 'Radness';
src: url(megafile.woff2);
}
}
其他的使用方式和效果就不一一演示了。不過在未來,CSS 的 @media 在編寫方式上會變得更簡單:?
@media (width <= 320px) {
body {
padding-block: var(--sm-space);
}
}
@custom-media --motionOK (prefers-reduced-motion: no-preference);
@media (--motionOK) {
.card {
transition: transform .2s ease;
}
}
.card {
@media (--motionOK) { & {
transition: transform .2s ease;
}}
}
@media (1024px >= width >= 320px) {
body {
padding-block: 1rem;
}
}
?
特別聲明,該示例代碼來自于 @argyleink 的 PPT 。
?
自從折疊屏設備的出現,給 Web 開發者帶來新的挑戰:?
值得慶幸的是,微軟和三星的團隊就針對折疊屏幕設備提供了不同的 媒體查詢判斷。?
上圖是帶有物理分隔線的雙屏幕設備:
main {
display: grid;
gap: env(fold-width);
grid-template-columns: env(fold-left) 1fr;
}
@media (spanning: single-fold-vertical) {
aside {
flex: 1 1 env(fold-left);
}
}
無縫的折疊設備:?
@media (screen-fold-posture: laptop){
body {
display: flex;
flex-flow: column nowrap;
}
.videocall-area,
.videocall-controls {
flex: 1 1 env(fold-bottom);
}
}
?
CSS 的比較函數是指 min() 、max() 和 clamp() ,我們可以給這幾個函數傳入值(多個)或表達式,它們會對傳入的值進行比較,然后返回最合適的值。另外,這幾個和我們熟悉的 calc() 類似,也可以幫助我們在 CSS 中做動態計算。?
先看 min() 和 max() ,它們之間的差異只是返回值的不同:?
下圖展示了 min(50vw, 500px) 在瀏覽器視窗寬度改變時,返回的值的變化:?
Demo: https://codepen.io/airen/full/mdeLMoZ
?
把上面的示例的 min() 換成 max() 函數,即 max(50vw, 500px),它的返回值是:?
Demo: https://codepen.io/airen/full/oNjdGyv
clamp() 和 min() 以及 max()略有不同,它將返回一個區間值,即 在定義的最小值和最大值之間的數值范圍內的一個中間值。該函數接受三個參數:?
?
clamp(MIN, VAL, MAX),這三個值之間的關系(或者說取值的方式):?
?
比如下面這個示例:?
.element {
/**
* MIN = 100px
* VAL = 50vw ? 根據視窗的寬度計算
* MAX = 500px
**/
width: clamp(100px, 50vw, 500px);
}
?
就這個示例而言,clamp() 函數的計算會經歷以下幾個步驟:?
.element {
width: clamp(100px, 50vw, 500px);
/* 50vw相當于視窗寬度的一半,如果視窗寬度是760px的話,那么50vw相當等于380px*/
width: clamp(100px, 380px, 500px);
/* 用min()和max()描述*/
width: max(100px, min(380px, 500px))
/*min(380px, 500px)返回的值是380px*/
width: max(100px, 380px)
/*max(100px, 380px)返回的值是380px*/
width: 380px;
}
示例效果如下:
Demo: https://codepen.io/airen/full/pojVpJv
?
簡單地說,clamp() 、min() 和 max() 函數都可以隨著瀏覽器視窗寬度的縮放對值進行調整,但它們的計算的值取決于上下文。
我們來看一個比較函數中 clamp() 的典型案例。假設我們需要在不同的屏幕(或者說終端場景)運用不同大小的 font-size :?
在還沒有 CSS 比較函數之前,使用了一個叫 CSS 鎖(CSS Locks)的概念來實現類似的效果:?
需要做一些數學計算:?
Demo: https://codepen.io/airen/full/bGqdOma
?
使用 clamp() 之后,只需要一行代碼就可以實現:?
/** minf: 20px (min font-size)
* maxf: 40px (max font-size)
* current vw: 100vw
* minw: 320px (min viewport's width)
* maxw: 960px (max viewport's width)
*/
h1 {
font-size: clamp(20px, 1rem + 3vw, 40px);
}
?
使用這方面的技術,我們就可以輕易實現類似下圖這樣的效果:?
注,上圖來自《Use CSS Clamp to create a more flexible wrapper utility》一文。
CSS 內容可見性,說要是指 content-visibilit 和 contain-intrinsic-size 兩個屬性,目前隸屬于 W3C 的 CSS Containment Module Level 2 模塊,主要功能是可以用來提高頁面的渲染性能。
一般來說,大多數Web應用都有復雜的UI元素,而且有的內容會在設備可視區域之外(內容超出了用戶瀏覽器可視區域),比如下圖中紅色區域就在手機設備屏幕可視區域之外:?
在這種場合下,我們可以使用CSS的 content-visibility 來跳過屏幕外的內容渲染。也就是說,如果你有大量的離屏內容(Off-screen Content),這將會大幅減少頁面渲染時間。?
Google Chrome 團隊有工程師對 content-visibility 做過相關的測試:?
使用了 CSS 的 `content-visibility` 屬性,瀏覽器的渲染過程就變得更加容易。本質上,這個屬性 改變了一個元素的可見性,并管理其渲染狀態。?
而 contain-intrinsic-size 屬性控制由 content-visibility 指定的元素的自然尺寸。它的意思是,content-visibility 會將分配給它的元素的高度(height)視為 0,瀏覽器在渲染之前會將這個元素的高度變為 0,從而使我們的頁面高度和滾動變得混亂。但如果已經為元素或其子元素顯式設置了高度,那這種行為就會被覆蓋。如果你的元素中沒顯式設置高度,并且因為顯式設置 height可能會帶來一定的副作用而沒設置,那么我們可以使用contain-intrinsic-size來確保元素的正確渲染,同時也保留延遲渲染的好處。?
換句話說,contain-intrinsic-size 和 content-visibility 是一般是形影不離的出現:?
section {
content-visibility: auto;
contain-intrinsic-size: 1000px;
}
如果你使用瀏覽器開發者工具審查代碼時,將鼠標放到一個 <img> 標簽上,你會看到類似下圖這樣的:?
<img> 的 src 路徑上浮出來的圖片底下有一行對圖像的尺寸的描述,即252 x 158 px (intrinsic: 800 x 533 px) ,其實現這表述圖片尺寸中兩個重要信息:?
?
其實在 CSS 中給一個元素框設置大小時,有的是根據元素框內在的內容來決定,有的是根據上下文來決定的。根據該特性,CSS的尺寸也分為內部(內在)尺寸和外部(外在)尺寸。?
?
通過一個簡單的示例來向大家演示 CSS 內在尺寸的特性,即 min-content 、max-content 和 fit-content 的特性。?
<h1>CSS is Awesome</h1>
<style>
h1 {
width: auto;
}
</style>
?
先來看 h1 的 width 取值為 auto 和 min-content 的差異:?
// 外在尺寸
h1 {
width: auto; // 根據容器變化
}
// 內在尺寸
h1 {
width: min-content; // 根據內容變化
}
Demo: https://codepen.io/airen/full/zYZvGrY
?
從上圖中不難發現,width 取值為 min-content 時,h1 的寬度始終是單詞“Awesome”長度(大約是144.52px)。它的寬度和容器寬度變化并無任何關系,但它受排版內相關的屬性的影響,比如font-size、font-family 等。?
再來看max-content :?
Demo: https://codepen.io/airen/full/zYZvGrY
?
當h1 的 width 取值為 max-content 時,它的寬度是h1 所在行所有內容的寬度。最后來看 fit-content :?
?
Demo: https://codepen.io/airen/full/zYZvGrY
?
相對而言,fit-content 要比 min-content 和 max-content 復雜地多:?
h1 {
width: fit-content;
}
// 等同于
h1 {
width: auto;
min-width: min-content;
max-width: max-content;
}
簡單地說,fit-content 相當于 min-content 和 max-content,其 取值:?
?
使用下圖來描述它們之間的關系:?
min-content、max-content 和 fit-content 被稱之個內在尺寸,它可以運用于設置容器尺寸的屬性上,比如width 、height 以及 inline-size 和 block-size 等。但有些屬性上使用的話則會無效:?
?
在布局上使用 min-content 、max-content 或 fit-content 可以幫助我們設計內在布局,另外在構建一些自適應的布局也非常靈活。特別是和 CSS 的 Grid 和 Shapes 相關特性結合,還能構建一些具有創意的布局。?
最后有一點需要特別聲明,fit-content 和 fit-content()函數不是相同的兩個東東,使用的時候需要區別對待。?
display 對于大家而言并不陌生,主要用來格式化上下文,這里特別拿出來和大家說的是因為 display 也有一些變化。其中之一就是 display 未來可以支持多個值:?
據最新的消息,Sarafi 瀏覽器已經把display 設置兩個值已進入實驗性屬性。display 取兩個值的含義大致如下:?
另外單獨要說的是,display 新增了 contennts 屬性值,** W3C規范是這樣描述的**:?
大致意思是說:?
設置了 display: contents 的元素自身將不會產生任何盒子,但是它的子元素能正常展示。
?
比如:?
<div class="outer">
I'm, some content
<div class="inner">I'm some inner content </div>
</div>
<style>
.outer {
border: 2px solid lightcoral;
background-color: lightpink;
padding: 20px;
}
.innter {
background-color: #ffdb3a;
padding: 20px;
}
</style>
?
上面這個簡單地示例代碼,你將看到的效果如下:?
如果我們在.outer 元素上顯式設置 display: contents ,該元素本身不會被渲染,但子元素能夠正常渲染:?
Demo: https://codepen.io/airen/full/abJvyoj
?
在某些布局中,特別是不希望調整 HTML 的結構的時候,我們就可以使用該特性。比如在 Flexbox 或 Grid 中,希望把其他后代元素變成網格項目或 Flex項目,那就可以這樣做:?
Demo: https://codepen.io/airen/full/zYZvdJb
?
display: contents 在規范討論階段和 display: subgrid 的討論中是非常的激烈,最終是 display: contents 獲勝了。你現在在Grid的布局中,也沒有單獨的display: subgrid ,而是將subgrid 移入到 grid-template-columns 和 grid-template-rows 中。?
另外還有一個比較大的爭執就是 display: contents 和 Web 可訪問性方面的。有關于這方面的討論,你要是感興趣的話,可以閱讀:?
?
CSS 中的 @ 規則有很多種,但大家比較熟悉的應該是 @import 、@media 和 @supports 之類的。今天給大家簡單的提幾個不常見的,比如:?
?
使用過 CSS 處理器的同學,應該用過嵌套來組織自己的代碼,比如 SCSS:?
// SCSS
foo {
color: red;
& bar {
color: green;
}
}
上面的代碼經過編譯之后:?
// CSS
foo {
color: red;
}
foo bar {
color: green;
}
慶幸的是,W3C 也在討論和定義CSS中的嵌套規則。目前兩種規則:?
foo {
color: red;
@nest bar {
color: green;
}
}
// 或者
foo {
color: red;
& bar {
color: green;
}
}
// 都等同于
foo {
color: red;
}
foo bar {
color: green;
}
也可以和媒體查詢 @media 相互嵌套:?
article {
color: darkgray;
& > a {
color: var(--link-color);
}
}
code > pre {
@media (hover) {
&:hover {
color: hotpink;
}
}
}
code > pre {
@media (hover) {
@nest &:hover {
color: hotpink;
}
}
}
article {
@nest section:focus-within > & {
color: hotpink;
}
}
main {
padding: var(--space-sm);
@media (width >= 540px) { & {
padding: var(--space-lg);
}}
}
除了 @nest 之外還有 @apply 。你可能在一些前端的框架或構建器中看到過 @apply:?
如果你在 Chrome Canary 瀏覽器“實驗性屬性” 就可以直接體驗 @apply :?
?
簡單地說,它有點類似于 SCSS 中的混合宏 @mixin 和 @extend :?
:root {
--brand-color: red;
--heading-style: {
color: var(--brand-color);
font-family: cursive;
font-weight: 700;
}
}
h1 {
--brand-color: green;
@apply --heading-style;
}
@property 是用來注冊一個變量的,該變量是一個 CSS Houdini 中的變量,但它的使用和 CSS 中的自定義屬性(CSS變量)是一樣的,不同的是注冊方式:?
// Chrome 78+
// 需要在 JavaScript腳本中注冊
CSS.registerProperty({
'name': '--custom-property-name',
'syntax': '<color>',
'initialValue': 'black',
'inherits': false
})
// Chrome 85+
// 在CSS文件中注冊
@property --custom-property-name {
'syntax': '<color>',
'initialValue': 'black',
'inherits': false
}
他的最大特色之一就是可以指定已注冊的 CSS 變量的類型、初始值,是否可繼承:?
上圖截取于 Maxi 在推特上發的推文。
?
雖然它的使用方式和 CSS 的自定義屬性相似,但它要更強大,特別是在動效方面的使用,能增強 CSS 的動效能力,甚至實現一些以前 CSS 無法實現的動效。比如?
@property --hue {
initial-value: 0;
inherits: false;
syntax: '<number>';
}
@keyframes rainbow {
to {
--hue: 360;
}
}
@property --milliseconds {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.counter {
counter-reset: ms var(--milliseconds);
animation: count 1s steps(100) infinite;
}
@keyframes count { to {
--milliseconds: 100;
}}
把它和 CSS Houdini 的 Paint API 結合起來,可做的事情更多:?
更多這方向的效果可以在 houdini.how 網站上查閱:
Una Kravets 在 Google I/O 開發大會上就分享了容器查詢 @container ,她把它稱為新的響式布局所需特性之一:?
那么容器查詢 @container 可以做什么呢?假設你的設計師給你提供了一份像下圖這樣的設計稿:?
你可能首先會想到的是 @media (在沒有容器查詢之前,似乎也只有這樣的方式),而有了@container 之后,就可以換過一種姿勢:?
這兩張圖上來自于 @shadeed9 的 《CSS Container Queries For Designers》一文,他的另一篇文章《Say Hello To CSS Container Queries》也是介紹容器查詢的。
看上去非常強大,事實上也很強大,并且它的使用和 @meida 非常相似:?
// Demo: https://codepen.io/una/pen/mdOgyVL
.product {
contain: layout inline-size;
}
@container (min-width: 350px) {
.card-container {
padding: 0.5rem 0 0;
display: flex;
}
.card-container button {
/* ... */
}
}
Demo: https://codepen.io/una/pen/mdOgyVL
?
對于 @container 特性,有叫好的,也有不同的,比如 Kenton de Jong 在他的新博文《Why I am not a fan of CSS container queries》闡述了自己不喜歡該t特性:?
就我個人而言,我是很喜歡這個特性,后面會花一定的時間深入了解和學習 @container。當然有討論是一件好事,這樣會讓該特性更成熟,如果你也想參與進來討論的話,可以點擊這里加入。?
我以前只看到過 @scope 規則,主要是用來處理 CSS 中樣式規則作用域相關的,但并沒有深入了解過。Una Kravets 在 Google I/O 開發大會分享上再次看到了 @scope :?
上圖是 Miriam Suzanne 繪制的!
?
@scope 內的樣式允許穿透和特定組件的樣式,以避免命名沖突,許多框架和插件(如CSS模塊)已經使我們能夠在框架內做到這一點?,F在,這個規范將允許我們為我們的組件編寫具有可讀性的CSS的本地封裝樣式,而不需要調整標記。?
/* @scope (<root>#) [to (<boundary>#)]? { … } */
@scope (.tabs) to (.panel) {
:scope { /* targeting the scope root */ }
.light-theme :scope .tab { /* contextual styles */ }
}
怎么看上去和 Web Componed中的 Scope 那么的相似呢??
對于 @layer ,我第一見:?
@layer reset {
* { box-sizing: border-box; }
body { margin: 0; }
}
// ...
@layer reset { /* add more later */ }
@import url(headings.css) layer(default);
@import url(links.css) layer(default);
@layer default;
@layer theme;
@layer components;
@import url(theme.css) layer(theme);
@layer default, theme, components;
@import url(theme.css) layer(theme);
@layer framework.theme {
p {
color: rebeccapurple;
}
}
@layer framework {
@layer theme {
p { color: cyan; }
}
}
上面代碼表示啥意思,我也還沒整明白,只知道 @layer 被稱為層疊層(Cascade Layers)。該特性是 什么** W3C 層疊和繼承規范 Level5** 中新提出來的。?
在我分享結束沒多久,正在整理這篇文章的時候,發現我的偶像 @argyleink 也分享了一個相似的話題《Hover:CSS! What's New in 2021?》,分享了 31 個 CSS 相關的特性,并且按風險級別分為高、中、低三檔:?
你會發現,和我整理的特性有很多吻合之處。如果你聽過他去年在倫敦CSS大會分享的《London CSS: What‘s New in 2020?》,你會發現 2021 年的是 2020 年的升級版。?
在 2020 年聽完 分享之后,我也整理了一份中文版本的《2020年你不應該錯過的 CSS 新特性》,并在淘系前端團隊 微信公眾號發過。
?
文章很長,能閱讀到這里,說明你也是 CSS 的真愛。感謝大家的閱讀,在未來我將繼續為大家服務。把 CSS 方面最新、最有意思的一面與大家共享!
文最初發布于 CSS-Tricks 博客,由 InfoQ 中文站翻譯并分享。
過去幾周,我一直在為我的家具租賃公司Pabio招聘一名高級全棧JavaScript 工程師。由于是一個遠程團隊,面試是在 Zoom 上進行的。根據我的觀察,部分開發人員不擅長現場編碼或白板面試,即使他們對這項工作很在行。所以取而代之,我們會進行一小時的技術討論,我會問他們關于 Web Vitals、可訪問性、瀏覽器戰爭以及其他類似 Web 話題的問題。我很喜歡問的一個問題是:“解釋一下 Twitter 源代碼的前十幾行”。
我認為這是一個很簡單的測試,可以借此了解應聘者對前端基礎知識的掌握程度。本文列出了這個問題的最佳答案。
我打開 Twitter.com,點擊查看源代碼并分享我的屏幕,然后要求他們逐行進行解釋,他們想說多少就說多少。我放大了文本,使其更加清晰,所以你看不到整行的內容,不過可以大概有個了解,如下所示:
注意,既然我們的技術討論是一種談話,所以我并不期望任何人能給出完美答案。只要聽到一些正確的關鍵詞,我就知道應聘者了解這個概念,我就會試著把他們引向正確的方向。
每個源代碼文檔的第一行都非常適合這個面試,因為應聘者對DOCTYPE聲明的了解程度與他們的工作年限密切相關。我仍然記得,在 Dreamweaver 時代,XHTML DOCTYPE 行很長,就像 2009 年 Chris 在文章“常見DOCTYPE”中所寫的那樣。
最佳答案:這是文檔類型(doc-type)聲明,我們總是把它放在 HTML 文件的第一行。你可能認為這些信息是多余的,因為瀏覽器已經知道響應的 MIME 類型是text/html;但在Netscape/Internet Explorer時代,瀏覽器要從多個相互競爭的版本中找出要使用哪個 HTML 標準來渲染頁面,這是一項困難的任務。
這一點尤其令人討厭,因為每個標準都會產生不同的布局,所以采用這個標簽是為了讓瀏覽器更容易判斷。以前,DOCTYPE標簽很長,甚至包括規范鏈接(有點像現在的 SVG),但幸運的是,<!doctype html>在 HTML5 中得到了標準化,延續了下來。
也可接受:DOCTYPE標簽告訴瀏覽器這是一個 HTML5 頁面,應該這樣渲染。
這一行代碼可以告訴我應聘者是否了解可訪問性和本地化的問題。令人驚訝的是,在我的面試中,只有少數人知道dir屬性,但這是討論屏幕閱讀器的一個很好的切入點。幾乎每個人都能說清楚lang="en"屬性,即使他們以前沒有用過。
最佳答案:這是 HTML 文檔的根元素,其他所有元素都包在這個元素里。它有兩個屬性:方向和語言。方向屬性的值是從左到右,它告訴瀏覽器代理內容方向;另一個值是從右到左,適用于阿拉伯語等語言,或者是auto,讓瀏覽器自己來決定。
語言屬性告訴我們,這個標簽里的所有內容都是英文的;你可以把這個值設置為任何語言,甚至可以區分en-us和en-gb。這對屏幕閱讀器來說也很有用,可以知道用哪種語言來播音。
最佳答案:源代碼中的元標簽用來提供關于這個文件的元數據。字符集(char-set)屬性告訴瀏覽器要使用哪種字符編碼,而 Twitter 使用的是標準的 UTF-8 編碼。UTF-8 很好,因為它有很多字符代碼點,所以你可以在源代碼中使用各種符號和表情。把這個標簽放在代碼開頭附近,這很重要,這樣瀏覽器就不會在遇到這一行之前解析太多的文本;我覺得可以定個這樣的規則,就是把它放在文檔的前 1000 個字節里,但我認為最好的做法是把它放在<head>的正上方。
順便提一下,Twitter 似乎是出于性能方面的考慮(加載的代碼較少)省略了<head>標簽,但我還是喜歡明確定義,因為它是所有元數據、樣式等的大本營。
最佳答案:源代碼中的這個元標簽是為了在小屏幕上(比如智能手機)可以適當調整網頁的大小。如果你還記得最早的 iPhone 主題演講,史蒂夫·喬布斯在那個 4.5 英寸的小屏幕上展示了整個《紐約時報》的網站;在那時,這是一個了不起的功能,你必須捏住放大才能閱讀。
現在,網站的設計是響應式的,width=device-width告訴瀏覽器使用設備的整個寬度作為視口,所以沒有水平滾動條,但你甚至可以使用具體的像素值指定寬度。通常,最佳的做法是將初始縮放比例設置為1,寬度設置為device-width,這讓人們仍然可以根據自己的需要進行縮放。
還有些值源代碼截圖中沒有顯示出來,但你最好也了解下:Twitter 還應用了user-scalable=0,顧名思義,就是禁用了縮放功能。這對可訪問性沒什么好處,但使網頁感覺更像一個本地應用程序。出于同樣的原因,它還設置了maximum-scale=1(你可以使用最小和最大縮放比例,并使用兩者之間的值限制縮放能力)。一般來說,設置全寬和初始縮放比例就足夠了。
大約 50%的應聘者知道 Open Graph 標簽,如果他們這個問題回答得比較好,就表明他們了解 SEO。
最佳答案:這個標簽是網站名稱 Twitter 的 Open Graph(OG)元標簽。Open Graph協議是由 Facebook 制定的,目的是使鏈接更容易打開,并在一個漂亮的卡片布局中顯示預覽;開發者可以添加各種著作權詳情和封面圖片,實現花式分享。而事實上,使用 Puppeteer 之類的東西自動生成 Open Graph 圖片,現在也很常見。(CSS-Tricks使用了一個WordPress插件來做到這一點。)
另外提一個比較有趣的點,元標簽通常具有name屬性,但 OG 使用非標準的property屬性。我猜這只是 Facebook 的特色。標題、URL 和描述 Open Graph 標簽有點多余,因為我們已經有了這些常規的元標簽,人們添加它們只是為了安全?,F在的大多數網站都搭配使用 Open Graph 和其他元標簽以及頁面上的內容來生成豐富多彩的預覽。
大多數應聘者都不知道這個,但有經驗的開發者可以談下如何針對蘋果設備優化網站,比如apple-touch-icon和 Safari 固定標簽 SVG。
最佳答案:你可以將網站固定在 iPhone 主屏幕上,讓它感覺像一個原生應用程序。Safari 不支持漸進式 Web 應用,你也無法在 iOS 上使用其他瀏覽器引擎,所以如果你想要類似于原生的體驗,真的沒有其他選擇,當然,Twitter 是喜歡這種體驗的。所以他們添加了這個,告訴 Safari 這個應用的標題是 Twitter。下一行類似,控制應用程序啟動后狀態欄如何顯示。
最佳答案:這是一個符合 Web 標準的、相當于蘋果狀態欄顏色元標簽的標簽。它告訴瀏覽器周邊UI使用什么主題色。Chrome on Android 和 Brave on Desktop 在這方面都做得很好。你可以把任何 CSS 顏色放在內容中,甚至可以使用media屬性,只為特定的媒體查詢顯示這種顏色,如支持深色主題。你也可以在 Web 應用清單中定義這個及其他屬性。
我面試過的人都不知道這個。我想,只有對標準化階段發生的所有新鮮事都有深入的了解時,才會知道這個。
最佳答案:起源試驗讓我們可以在網站上使用實驗性的新特性,跟蹤用戶代理反饋,并報告給 Web 標準社區,而無需用戶選擇加入一個特性標識。例如,Edge 有一個針對雙屏和可折疊設備基元的起源試驗,這非???,因為你可以根據可折疊手機是打開還是關閉來設置有趣的布局。
也可接受:這個我不知道。
幾乎沒有人知道這一行;只有了解 CSS 的邊緣情況和優化時,才能看懂這一行。
最佳答案:想象一下,如果沒有一個移動端響應式站點,那么當你在一個小屏幕上打開時,瀏覽器可能會調大字體,以方便閱讀。CSS 的text-size-adjust屬性可以用none值禁用,也可以指定一個百分比,允許瀏覽器調大字體。
在這種情況下,Twitter 設置的最大比例是100%,所以文本不會大于實際尺寸;他們這樣做是因為他們的網站已經是響應式的,他們不想冒因瀏覽器調大字體而破壞布局的風險。它作用于根 HTML 標簽,所以它作用于根標簽中的所有內容。由于這是一個實驗性的 CSS 屬性,所以需要供應商前綴。另外,這行 CSS 代碼之前少了<style>,但我猜這是在前一行去掉的,所以我們沒有看到。
也可接受:我不特別了解這個屬性,但-ms和-webkit-是非標準屬性的供應商前綴,分別針對基于 Internet Explorer 和 WebKit 的瀏覽器。在 CSS3 剛推出時,我們需要這些前綴,但當屬性從實驗變為穩定或被采納到標準中時,這些前綴就消失了,人們轉而采用標準化的屬性。
Twitter 源代碼中的這一行特別有趣,因為你可以跟進一個問題,即網頁重置和規范化之間有什么區別。幾乎每個人都有一個版本的正確答案。
最佳答案:不同瀏覽器有不同的默認樣式(用戶代理樣式表),而你希望通過重置屬性來覆蓋它們,使得網站在不同的設備上看起來都一樣。在這種情況下,Twitter 就告訴瀏覽器刪除body標簽的默認邊距。這只是為了降低瀏覽器的不一致性,但我更喜歡將樣式規范化,而不是重置它們,也就是說,在不同的瀏覽器上應用相同的默認值,而不是完全刪除它們。人們甚至曾經使用* { margin: 0 },這完全是矯枉過正,對性能并不好,但現在,常見的方式是導入normalize.css或reset.css之類的東西(甚至是更新的東西)并在此基礎上進行設計。
我一直很喜歡玩瀏覽器的檢查器工具,看一看網站是如何制作的,我就是因為這個想出了這樣的面試方法。盡管我自認為算是語義 HTML 方面的專家,但每次這樣做時我都會學到一些新東西。
因為 Twitter 主要是一個客戶端 React 應用,所以源代碼只有幾十行。即使這樣還是有很多東西可以學!在 Twitter 的源代碼中,還有一些更有趣的行,我留給讀者做練習。你能在面試中解釋其中的多少個?
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Twitter">
…告訴瀏覽器用戶可以將 Twitter 添加為一個搜索引擎。
<link rel="preload" as="script" crossorigin="anonymous" href="https://abs.twimg.com/responsive-web/client-web/polyfills.cad508b5.js" nonce="MGUyZTIyN2ItMDM1ZC00MzE5LWE2YmMtYTU5NTg2MDU0OTM1" />
…有許多有趣的屬性可供討論,尤其是nonce。
<link rel="alternate" hreflang="x-default" href="https://twitter.com/" />
…針對國際登錄頁。
:focus:not([data-focusvisible-polyfill]){outline: none;}
…在不使用鍵盤導航時移除焦點輪廓(這里的:focus-visible選擇器是 CSS 增強插件)。
了解更多軟件開發與相關領域知識,點擊訪問 InfoQ 官網:https://www.infoq.cn/,獲取更多精彩內容!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。