載說明:原創不易,未經授權,謝絕任何形式的轉載
本文章系《Unleashing the Power of CSS》(釋放CSS的力量,暫且這么翻譯吧)一書的學習筆記,希望通本書的學習,系統的梳理下CSS相關的高級新特性。本篇文章是其第一部分,由于全書英文版,理解和閱讀會有偏差,歡迎各位大佬們指正,我們一起共同提高。
在過去的幾年里,CSS引入了許多新的改進功能,并且跨瀏覽器的努力提高了兼容性,使這門語言比以往任何時候都更加穩定!讓我們回顧一下布局、響應式設計、元素樣式、屬性和選擇器方面的這些增強功能,并且也來看一看即將推出的新功能。
現在,瀏覽器之間新功能的協調實施意味著我們幾乎可以在它們出現的同時開始使用這些功能,這對于保持我們的樣式表盡可能簡單非常有幫助。現在,只需幾個單行屬性就可以替代多行的hacky解決方案。在某些情況下,新提供的功能甚至可能意味著我們可以刪除以前需要的JavaScript解決方案,以解決舊限制!
隨著Internet Explorer 11的生命周期進入尾聲,現在是時候開始使用自定義屬性了!自定義屬性,也被稱為“CSS變量”,允許我們定義可在樣式表中重復使用的值。自定義屬性可以作為屬性的整個值或部分值使用,我們還可以在JavaScript中修改自定義屬性。
一種新的屬性可以消除“填充hack”,它是 aspect-ratio 。它按照其名稱的意思,允許我們為元素定義一個縱橫比。我所提到的 hack 通常用于保持視頻嵌入的16:9比例。現在,通過這個屬性和聲明 aspect-ratio: 16/9 ,可以實現這個比例。它還是實現完美正方形的快速方法,使用 aspect-ratio: 1 即可。
這是一個代碼演示,展示了如何使用 aspect-ratio 與舊屬性 object-fit 結合使用,以保持一致的頭像大小,無論原始圖像的比例如何,而且不會扭曲圖像。
Html部分
<ul class="avatar-list">
<li>
<figure>
<img src='https://images.unsplash.com/photo-1640952131659-49a06dd90ad2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NjkwNTE0MTQ&ixlib=rb-4.0.3&q=80&w=400' alt=''>
<figcaption>Aaron Fizzle</figcaption>
</figure>
</li>
<li>
<figure>
<img src='https://images.unsplash.com/photo-1544725176-7c40e5a71c5e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NjkwNTE0MTQ&ixlib=rb-4.0.3&q=80&w=400' alt=''>
<figcaption>Lily Sebastian</figcaption>
</figure>
</li>
<li>
<figure>
<img src='https://images.unsplash.com/photo-1628157588553-5eeea00af15c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NjkwNTE1MTU&ixlib=rb-4.0.3&q=80&w=400' alt=''>
<figcaption>Devon Albian</figcaption>
</figure>
</li>
</ul>
Css部分
.avatar-list img {
/* Make it a square */
aspect-ratio: 1;
/* Fit the image to it's container without distortion */
object-fit: cover;
/* Make the square round */
border-radius: 50%;
width: 100%; /* Make sure the image fills the container */
height: 100%; /* Make sure the image fills the container */
}
* {
box-sizing: border-box;
margin: 0;
}
html {
height: 100%;
}
body {
min-height: 100%;
font-family: system-ui, sans-serif;
display: grid;
place-content: center;
background-color: mediumvioletred;
padding-inline: 1rem;
}
/* Standard responsive image fix */
img {
max-width: 100%;
}
.avatar-list {
list-style: none;
padding: 0;
background: #fff;
border-radius: 0.5rem;
box-shadow: 0.25rem 0.25rem 0.5rem -0.15rem hsl(0 0% 0% / 30%);
border: 1px solid hsl(0 0% 0% / 10%);
}
.avatar-list li {
position: relative;
padding: 3%;
font-size: 1.35rem;
font-size: clamp(0.8rem, 0.8rem + 2cqi, 1.5rem);
color: hsl(0 0% 45%);
letter-spacing: 0.03em;
}
.avatar-list li + li::before {
content: "";
position: absolute;
top: 0;
left: calc(15% + 1rem);
right: 3%;
border-top: 1px solid hsl(0 0% 0% / 15%);
}
.avatar-list figure {
display: grid;
grid-template-columns: 15% 1fr;
align-items: center;
gap: 1rem;
}
https://codepen.io/SitePoint/pen/oNaNaao
瀏覽器中還新增了各自的變換屬性。Chrome 104進行的CSS變換具有獨立的屬性。這些屬性是 scale , rotate 和 translate ,您可以使用它們來單獨定義變換的各個部分。
并非所有的轉換函數都有相應的個體屬性,例如 skewX() 和 matrix() 。
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
CSS的Logical Properties(邏輯屬性)是一種用于處理文本和布局的屬性,它們考慮了文本流的邏輯方向而不是物理方向。在CSS中,文檔可以采用不同的書寫模式,例如從左到右(LTR)的水平書寫模式和從右到左(RTL)的水平書寫模式,以及垂直書寫模式。Logical Properties的目標是使樣式更加靈活,適應不同的書寫模式,而不需要為每種書寫模式都編寫不同的樣式。
如果我們要為國際受眾管理內容,則可以考慮使用邏輯屬性。適用于大多數 CSS 2.1 屬性,邏輯變體考慮了文本的編寫模式和流。對于標準的英文文本,我們將“左/右”換成“內聯”,用“top/bottom”換成“block”:
.element {
margin-block: 2rem;
}
如上例所示,邏輯屬性還提供了一次設置兩邊的簡寫,其中 margin-block 水平寫入模式等效于 set margin-top 和 margin-bottom 。
近期對CSS最有影響力的三個變化是:is、:where和:has偽類選擇器。以下是它們的概述:
:is() ,它用于選擇滿足括號內任何選擇器的元素。這個偽類可以幫助你編寫更簡潔和可維護的 CSS 代碼,尤其是當你需要同時匹配多個選擇器時。例如, :is(#id, a, .class) 將具有一個 id 的特異性。
:where 是一個 CSS 偽類選擇器,它與 :is 偽類選擇器類似,可以用于選擇滿足括號內任何選擇器的元素。它的語法也與 :is 相似,但有一個重要的區別::where 不會影響優先級。
與 :is 不同,:where 不會增加或改變樣式規則的優先級。這意味著,無論你在樣式表中的什么位置使用 :where,它都不會改變選擇器的權重,不會增加特異性(specificity),也不會影響其他樣式規則的優先級。
這使得 :where 在一些情況下非常有用,特別是當你需要選擇一組元素,但不希望影響其他選擇器的優先級時。例如,假設你有一個已經存在的 CSS 樣式表,其中包含了一些具有不同權重和特異性的樣式規則,但你希望添加一個新的規則,同時不改變其他規則的優先級,你可以使用 :where 來實現這一點。
/* 不使用 :where */
.btn {
background-color: #3498db;
}
/* 使用 :where,不影響其他規則的優先級 */
:where(.btn-primary, .btn-secondary, .btn-danger) {
background-color: #3498db;
color: white;
}
:has() 是期待已久的“父選擇器”,它允許檢查父元素是否包含特定的子元素,并對父元素進行樣式設置,或者擴展為復合選擇器以對子元素進行樣式設置。(本系列教程中有關于 :has() 的完整教程。)
這個演示利用 :where() 、 :is() 和 :has() 來創建一個作者簡介組件,根據是否有頭像來改變網格顯示屬性。
<aside class="bio">
<img class="avatar" src='https://images.unsplash.com/photo-1554727242-741c14fa561c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzExNDcxMjM&ixlib=rb-4.0.3&q=80&w=400' alt=''>
<h2>Jane Stylesheet</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa quam aspernatur, nobis ex rem iure!</p>
</aside>
<aside class="bio">
<h2>Bob Markup</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam neque a blanditiis praesentium impedit.</p>
</aside>
* {
box-sizing: border-box;
margin: 0;
}
body {
font-family: system-ui;
padding: 3vw;
background-color: mediumvioletred;
}
img {
display: block;
max-width: 100%;
}
:where(* + *) {
margin-block-start: 1rem;
}
.bio :is(h2, p) {
margin-block-start: 0;
}
.bio {
background-color: white;
display: grid;
gap: 1rem;
border-radius: 0.5rem;
padding: 5%;
box-shadow: 0 0 10px -2px hsl(0 0% 0% / 85%);
}
.bio:has(.avatar) {
grid-template-areas: "avatar name" "avatar bio";
grid-template-columns: min(25vw, 80px) 1fr;
}
.bio:has(.avatar) :not(.avatar) {
grid-column: bio;
}
.bio .avatar {
grid-area: avatar;
}
.avatar {
aspect-ratio: 1;
object-fit: cover;
border-radius: 50%;
}
https://codepen.io/SitePoint/pen/WNaeJOy
:has() 在撰寫本文時僅部分瀏覽器支持,因此上述演示目前僅適用于Safari 15.4+和Chrome/Edge 105+,以及啟用 layout.css.has-selector.enabled 標志的Firefox 103。
最近,:not() 選擇器已經增強,可以接受一個選擇器列表,這使得 :not(nav a, footer a) 成為有效的語法。然而,與 :is() 和 :where() 不同,這個更新并沒有使 :not() 對于無效的選擇器更加寬容,因為需要保持向后兼容性支持。
下面的兩個新偽類都會影響焦點行為。當子元素處于焦點狀態時,可以使用 :focus-within 選擇器來為父元素設置樣式,比如表單字段周圍的容器。對于元素焦點樣式,我們現在可以使用 :focus-visible ,它最近取代了 :focus 成為跨瀏覽器默認的元素焦點樣式。
下面是 :focus-within 的一些關鍵點和與 :focus 的區別:
:focus-within 選擇器:
:focus 選擇器:
假設有以下 HTML 結構:
<div class="container">
<input type="text" id="username" />
<input type="password" id="password" />
</div>
現在,我們可以使用 :focus 和 :focus-within 來添加一些樣式:
/* 當輸入框具有焦點時,樣式化輸入框本身 */
input:focus {
border: 2px solid blue;
}
/* 當包含有焦點輸入框的容器具有焦點時,樣式化整個容器 */
.container:focus-within {
background-color: lightgray;
}
在上面的示例中,當用戶點擊輸入框時,輸入框自身會具有藍色邊框(使用 :focus 選擇器),同時包含有焦點輸入框的容器 .container 也會變為灰色背景(使用 :focus-within 選擇器)。這使得用戶在與表單交互時,不僅輸入框本身被強調,整個表單容器也能夠獲得焦點的可視反饋。
總之,:focus-within 選擇器用于選擇包含有焦點元素的祖先元素,而 :focus 選擇器用于樣式化具有焦點的元素本身。這兩個選擇器可以一起使用,以創建更豐富的交互體驗。
最后但并非最不重要的是,偽元素 ::marker 允許我們直接選擇和樣式化 <ul> 和 <ol> 元素上的列表項符號和編號,以及 <summary> 元素的“插入符號”。這意味著我們可以使用 ::marker 來僅改變列表的符號顏色!
accent-color
框架和設計系統最常見的改變之一是本地表單字段樣式。在 accent-color 屬性出現之前,甚至改變表單元素的顏色都是不可能的。現在,我們可以通過 accent-color 影響單選按鈕和復選框的選中外觀,以及范圍輸入和進度元素的填充狀態。
下面是一個示例,演示了如何使用 accent-color 屬性:
a {
accent-color: blue;
}
在這個示例中,accent-color 屬性應用于所有鏈接元素 (<a>),并將鏈接的強調顏色設置為藍色。
如果我們想要根據用戶的淺色或深色模式偏好來調整我們的界面,可以使用自定義切換和/或 prefers-color-scheme 查詢,我們還應該添加color-scheme屬性。這提供了一種選擇,可以適應瀏覽器的UI元素,如滾動條、表單控件和CSS系統顏色。而 accent-color 讓我們可以為一些元素選擇自定義顏色, color-scheme 則要求瀏覽器進行更多的適應,例如要求文本輸入和文本區域以淺色或深色主題顯示。
建議將此應用于 :root 元素,并按照網站默認值的順序列出這些值。換句話說,如果我們默認為淺色但支持深色,則列出 light dark 。如果我們默認為深色但支持淺色,則列出 dark light 。如果我們只支持 light 或 dark ,只需列出單個值即可:
:root {
color-scheme: light dark;
}
例如,你可以這樣定義一個明亮模式和一個暗模式的顏色方案:
/* 明亮模式 */
@media (prefers-color-scheme: light) {
body {
background-color: white;
color: black;
}
}
/* 暗模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
為了完善關于顏色的主題,還有一個偏好查詢和屬性對需要討論。在Windows上,一些用戶需要“高對比度”主題,其中操作系統強制使用減少的調色板來代替我們定義的顏色。調色板填充系統顏色的值,替換背景、文本、按鈕和鏈接顏色等內容,而像盒子陰影這樣的樣式則被刪除。
如果我們有使用顏色的關鍵樣式,比如產品顏色樣本,我們可能需要在 forced-colors 屬性旁邊使用 force-color-adjust 查詢。根據以下配對,我們原始的 .swatch 顏色將被保留:
@media (forced-colors: active) {
.swatch {
forced-color-adjust: none;
}
}
強制使用顏色應該謹慎使用,只有在用戶體驗受到高對比度主題顏色交換的負面影響時才使用。如果您對高對比度主題不熟悉,請了解如何使用強制顏色進行樣式設置。
在文本裝飾方面,我們現在有可用的 text-underline-offset 屬性,它允許我們調整定義的 text-decoration 的位置,使其偏離原始位置。 text-decoration-thickness 伴隨屬性允許我們控制 text-decoration 的描邊粗細。結合使用這些屬性,可以消除使用邊框甚至偽元素來樣式化鏈接下劃線的hack。
以下樣式規則將文本下劃線向下偏移 2 像素:
a {
text-decoration: underline;
text-underline-offset: 2px;
}
由于文章內容篇幅有限,今天的內容就分享到這里,文章結尾,我想提醒您,文章的創作不易,如果您喜歡我的分享,請別忘了點贊和轉發,讓更多有需要的人看到。同時,如果您想獲取更多前端技術的知識,歡迎關注我,您的支持將是我分享最大的動力。我會持續輸出更多內容,敬請期待。
html開發中,表單是頁面上重要的內容,用戶輸入內容大部分內容都是通過表單收集的,在html4中表單元素是相對繁瑣的,在html5中,吸納了web forms2.0標準,大大加強了針對表單元素的功能。下面為大家介紹html5中新增的表單元素。
form元素
在html4中表單內的從屬元素必須寫在表單內部,在html5中沒有這個限制,可以寫在頁面任何地方,然后給該元素一個from屬性,屬性值為該表單的id,這樣就可以聲明該元素從屬于指定的表單了。示例代碼:<form id="test"><input type="text"></form><textarea form="test"></textarea>textarea屬性被寫在form表單之外,但它從屬于form表單,所以將form表單id指定給textarea元素的form屬性。這樣的好處在于我們可以方便添加元素的樣式,因為它們不是分散在各表單之內。不過現在只是部分瀏覽器支持這一屬性。
formaction屬性
在html4中,一個表單所有的元素只能通過表單的action屬性統一提交另一頁面,而在HTML5中可以給所有的提交按鈕(<input type="submit">、<input type="image">、<button type="submit">),都增加了不同的formaction屬性,點擊不同的按鈕提交給不同的頁面。
placeholder屬性
placeholder是指當文本框(<input type="text">或<textarea>)處于未輸入狀態時文本框顯示的輸入提示。只要加上了placeholder屬性,在指定提示文字就可以了。
autofocus屬性
給文本框、選擇框或按鈕加上該屬性,當畫面打開時,控件自動獲得焦點。在html4中做到這個效果需要使用JavaScript如“control.focus()”。不建議隨意使用該屬性,比如搜索頁面中的搜索文本框。
list屬性
在html5中,為單行文本框增加了一個list屬性,該屬性的值為某個datelist元素的id。datelist也是html5新增的元素,該元素類似選擇框(select)。但是當用戶想要設定的值不在選擇列表時,允許自行輸入。該元素本身并不顯示,而是文本框獲得焦點時提示輸入的方式顯示。為了避免在沒有支持元素的瀏覽器顯示錯誤,可以用css將它設置為不顯示。
autocomplete屬性
輔助輸入所有的自動完成功能,節省輸入時間,同時也十分方便。可以指定“on”、“off”、“不指定”這三種值,不指定時,取決各個瀏覽器。屬性為on時,可以顯示指定候補輸入的數據列表,off反之。
如果有漏掉其他方法,歡迎大家補充。每天學習一個知識點,每日寄語“失敗只有一種,那就是半途而廢。”
類選擇器以冒號開頭,并基于當前元素的狀態進行匹配。狀態可能和DOM樹相關,也可能和狀態的改變有關,比如:hover 和 :checked。
兼容性還行;
可以匹配具有href屬性的<a>和<area>,不管這些鏈接是否被訪問過。
:any-link等價于:link 加上 :visited。
值得注意的是,:any-link 比a標簽選擇器優先級要高,下面的例子中 color: purple; 會勝出。
:any-link {
color: purple;
}
a {
color: red;
}
我敢打賭,PC網頁上一個常見的可訪問性設計不好的地方就是諸如<a><button><input>這些元素在獲取焦點后沒有顯示outline。這對于那些習慣使用鍵盤進行頁面訪問的用戶來說非常不友好,在一串Tab操作后,他們不知道自己停留在了哪個頁面元素上。
:focus-visible的出現就是為了解決這個問題,它會在瀏覽器覺得需要給與用戶反饋的時候顯示出一個獲取到焦點的圈圈(focus ring)。
safari目前不支持。以下是demo:
<style>
.wrapper {
background: black;
text-align: center;
width: 360px;
height: 100px;
padding: 40px;
box-sizing: border-box;
color: blanchedalmond;
}
.image-nav-button {
color: blanchedalmond;
text-decoration: none;
font-size: 20px;
line-height: 1em;
}
.next {
float: right;
}
.prev {
float: left;
}
.image-nav-button:focus {
outline: none;
/* Try uncommenting below, then clicking the buttons */
/* outline: 3px solid red; */
}
.image-nav-button:focus-visible {
outline: 3px solid blanchedalmond;
}
</style>
<div class="wrapper">
<a href="#" tabindex="1" class="image-nav-button prev">← Prev Image</a>
<a href="#" tabindex="2" class="image-nav-button next">Next Image →</a>
</div>
<p><small>
See caniuse.com for more details
</small></p>
:focus-within的行為類似于一個父元素選擇器。:focus-within應用于一個容器,并且某個后代元素獲取到焦點時,某些樣式會被加到容器上(或者是容器內的其他后代元素上)。
<style>
.form-group:focus-within {
outline: 2px dashed blue;
}
.form-group:focus-within label{
color: blue;
}
</style>
<div class="form-group">
<label for="abcdef">Example form field</label>
<input type="text" id="abcdef">
</div>
假設你熟悉:is(), 那么:where()也很簡單。:where()和:is()不一樣的一點就是:where()是零特異性的(zero-specificity),比如下面這段代碼:
:where(article) img {
border: 5px solid green;
}
img {
border: 5px solid orange;
}
最終img的border是orange色的,和直觀經驗不一樣,原因就是:where() img的權重和img是一樣的。這個選擇器經常是做框架的人使用。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。