<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • css怎么用,divcss布局經典實例


    雖然CSS簡單,但CSS是一門非常有意思的語言,CSS每年都有變化,而且都有不同的博主都在不同的時間段總結一些CSS的新特性。雖然這些新特性無法立刻得到眾多瀏覽器的支持,但總是隨著時間的發展,這些特性都會得到瀏覽器的支持。哪怕未得到支持,也有一些方法讓瀏覽器支持,比如最為出外的 cssnext ,就可以讓很多未來的CSS特性就立馬使用,并且不用花太多時間來考慮瀏覽器的兼容性。

    今天這篇文章, @Daniel Crisp就當下的CSS的新特性 做了一個簡單的總結 —— 五個最新的CSS特性(事實上這些特性,對我而言并不是新特性),并且用示例告訴大家怎么使用這些特性。那么接下來,咱們看看這五個新特性是什么?以及怎么使用。如果您感興趣,歡迎繼續往下閱讀。

    前言

    @Daniel Crisp在他的博文中 ,探討了CSS的五個新特性,介紹了這五個特性能做什么,以及如何將它們應用到你的項目中。而且提供示例每一步的代碼,可以在 GitHub的倉庫中獲取這些代碼 ,不過在接下來,我將會借助 Codepen 來向大家展示。

    接下來要介紹的五個CSS新特性是:

    • CSS Display Module Level 3 : display:contents
    • CSS Conditional Rules Module Level 3 : @support(…){…}
    • CSS Overscroll Behavior Module Level 1 : overscroll-behavior: contain
    • CSS Selectors Module Level 4 : :focus-within , :placeholder-shown
    • CSS Containment Module Level 1 : contain:paint

    這些CSS特性,估計有些同學已經接觸過了,如果你未接觸過,建議你繼續跟隨著下面的步驟繼續往下閱讀。

    案例:創建一個新聞提要(Newsfeed)

    通過一個新聞提要為例,分不同的步驟向大家闡述這個新聞提要是怎么制作的,以及在制作這個案例的時候,這五個CSS特性是如何在案例中得到運用。

    Step1:新聞提要的HTML模板

    我們這個案例其實很簡單,并未使用任何JavaScript框架,還是使用原始的HTML結構來做這個Demo。所以我們需要一些簡單的HTML的標簽,幫助我們創建Demo。這里使用了一個類名為 .container 的 div ,該 div 包含了一個類名為 .feed 的 ul ,然后創建了十個 li ,每個 li包含了一個類名為 .card 的 div 。

    在第五個和第六個 li 之間創建了另一個名為 nested 的 li ,其包含了一個無序列表 ul ,而且包含了三個 li 創建三個卡片。

    <div class=”container”>

    <ul class=”feed”>

    <li><div class=”card”>Card 1</div></li>

    <li><div class=”card”>Card 2</div></li>

    <li><div class=”card”>Card 3</div></li>

    <li><div class=”card”>Card 4</div></li>

    <li><div class=”card”>Card 5</div></li>

    <li class=”nested”>

    <ul>

    <li><div class=”card”>Card A</div></li>

    <li><div class=”card”>Card B</div></li>

    <li><div class=”card”>Card C</div></li>

    </ul>

    </li>

    <li><div class=”card”>Card 6</div></li>

    <li><div class=”card”>Card 7</div></li>

    <li><div class=”card”>Card 8</div></li>

    <li><div class=”card”>Card 9</div></li>

    <li><div class=”card”>Card 10</div></li>

    </ul>

    </div>

    在沒有任何樣式的情況之下,你看到的效果是這樣的:

    Step2:添加樣式

    現在要給示例添加一些基本樣式,使其看起來更像一個新聞提要:

    body {

    background-color: grey;

    }

    .container {

    max-width: 800px;

    margin: 0 auto;

    }

    .card {

    background-color: #fff;

    padding: 10px;

    margin: 10px;

    min-height: 300px;

    }

    最后,在 .feed 上使用Flexbox相關的特性,讓每行有兩張卡片:

    .feed {

    display: flex;

    flex-wrap: wrap;

    li {

    flex: 1 0 50%;

    }

    }

    效果如下:

    如果你從未接觸過Flexbox相關的知識, 強烈建議你花點時間閱讀這些文章 。因為Flexbox發展到今天,已經開始取代 float 來布局,成為最主流的布局方式之一,特別是在移動端上的布局。

    Step03:解決布局問題

    當你向下滾動列表時,你會發現 .nested 下的三個 li (對應的是 CardA ~ CardC )影響了整體的布局效果:

    五個最新的CSS特性以及如何使用它們

    其實我們想要的,或者說理想狀態下,所有的卡片按流的方式排列,但事實并未如此。造成這種現象的原因是Flex容器 —— ul.feed 設置了 display:flex (創建了一個Flex容器),創建Flex容器之后,只會對其子元素( ul.feed > li.card )有影響,即可子元素自動會變成Flex項目。但不會影響其后代子元素,換句話說, .nested > li 是無法自動變成Flex項目。

    通常解決這個問題的唯一方法是更改HTML模板,但有些情況之下,比如說在CMS系統中(假設你沒有修改HTML標簽的權利),那么面對這種情況,你就會束手無策了。當然,你也許會想到使用JavaScript來處理?;蛟S以前你會這么想,但時至今日,咱們可以通過新的CSS特性來解決這個問題 —— display:contents 。

    W3C規范是這樣對 display:contents 描述 的:

    “The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.“

    大至意思是:“ 元素本身不產生任何邊界框,而元素的子元素與偽元素仍然生成邊界框,元素文字照常顯示。為了同時照顧邊界框與布局,處理這個元素時,要想象這個元素不在元素樹型結構里,而只有內容留下。這包括元素在原文檔中的子元素與偽元素,比如 ::before 和 ::after這兩個偽元素,如平常一樣,前者仍然在元素子元素之前生成,后者在之后生成。 ”

    那么 display: contents 這一簡單的代碼實際上讓元素表現得好像不存在一樣。但仍然可以看到元素的后代,而且元素自身并不影響布局。也就是說, .nested 的子元素 .card 也將變成Flex項目。

    首先刪除現有 .feed li 的類名,然后在 ul 和 li 是使用 display: contents :

    .feed ul,

    .feed li {

    display: contents;

    }

    這個時候 .feed 下所有的 .card 都變成了Flex項目(不僅是 .feed 下的子元素 li ,還包括后代的 li 元素):

    五個最新的CSS特性以及如何使用它們

    現在你看到的所有卡片都是有序的排列,但是尺寸不對:

    五個最新的CSS特性以及如何使用它們

    可以通過在 .card 上添加 flex 屬性來解決這個問題:

    .card {

    flex: 1 0 40%;

    }

    這個時候每張卡片的尺寸就又恢復正常了:

    這個時候就好象 ul 不存在了一樣。如果你夠仔細的話,你可以發現 flex-basis 的值設置為 40% 了,雖然我們設置了所有元素的 box-sizing 的值為 border-box ,但大家都知道, box-sizing 可以影響盒模型的計算,但對 margin 不包括在內,所以為了有足夠的空間放置卡片,把 flex-basis 的值重新計算了,也就是大家所看到的 40% 。

    這個示例也再次向大家說明了 display:contents 的神奇之處。當然,這里并沒有對 display:contents 做詳細的介紹,但也足夠向大家展示其強大之處。如果你對該特性感興趣,或者想深入的學習,建議閱讀下面這幾篇文章:

    • 如何理解CSS的 display 屬性
    • CSS的 display:contents
    • 為什么是 display:contents 而不是CSS Grid的 subgrid
    • How display: contents; Works
    • Vanishing boxes with display contents
    • More accessible markup with display: contents

    Step04:探索CSS查詢特性

    盡管 display:contents 實現了我們想要的效果,但它仍然處于W3C的工作草案狀態。目前只在Chrome 65+、Firefox 59+ 中看到效果。

    如果你在瀏覽器開發者工具中,禁掉 display: contents ,你可以看到你的布局又開始混亂了。這樣做只是模擬瀏覽器不支持該屬性時的效果。那么我們接下來能做什么呢?這就引出了下一個CSS新特性 —— CSS查詢特性 。

    它的原理有點類似于CSS中的媒體查詢( @media )一樣,但是它允許你單獨使用CSS表達式,類似于JavaScript語言中的 if / else 之類。如果條件符合應用對應塊中的樣式。接下來讓我們把 display:contents 作為查詢特性的條件,然后將對應的CSS樣式放置在 {…} 塊中。就像下面這樣:

    @supports (display: contents) {

    .feed ul,

    .feed li {

    display: contents;

    }

    .card {

    flex: 1 0 40%;

    }

    }

    在CSS中,查詢特性很多時候也被稱為CSS的條件特性,其主要包括 @media 、 @supports和 @viewport 。有關于這方面的介紹可以閱讀@webinista寫的PPT —— 《 Conditional CSS》。

    可能你第一次接觸到 @supports() 的話會感到很好奇,并不知道該屬性的具體使用,如果你愿意的話,建議你花點時間閱讀早期整理過的文章《 CSS3條件判斷: @supports 》和《 說說CSS中的 @supports 》。

    Step05: 使用 not 關鍵讓代碼變得更清晰

    在CSS的世界中,像 @supports 這樣其實也就是一種 漸進增強和優雅降級的方案 。我們可以使用 @supports 來添加新的樣式,但也可以添加降級所需的一些原始樣式。

    如果忽略IE瀏覽器的話, @supports 已得到很好的支持。實際上你可能希望使用的是CSS查詢特性,而不是某一種操作符。它的工作方式和你預期的一樣,因此我們可以通過 @supports 的 not 關鍵詞對那些不支持 display: contents 瀏覽器添加對應的樣式?;谶@個原因,我們可以把示例的代碼修改成:

    // 支持 display: contents的瀏覽器,采用的是這段代碼

    @supports (display: contents) {

    .feed ul,

    .feed li {

    display: contents;

    }

    .card {

    flex: 1 0 40%;

    }

    }

    // 不支持display:contents的瀏覽器,采用下面這段代碼

    @supports not (display: contents) {

    .feed li {

    flex: 1 0 50%;

    }

    .feed li.nested {

    flex-basis: 100%;

    }

    .feed li.nested ul {

    display: flex;

    flex-wrap: wrap;

    }

    }

    在支持 display:contens 的瀏覽器,你將看到的效果如下:

    五個最新的CSS特性以及如何使用它們

    在不支持 display:contents 的瀏覽器,看到的效果又像下面這樣:

    五個最新的CSS特性以及如何使用它們

    Step06: 更進一步優化

    經過上面的示例,估計你已經體會到了CSS查詢特性的魅力與潛力了,上面用到的僅僅是查查詢特性中的部分功能,更強大的是你可以 and 、 or 和 not 結合起來,讓你的條件表達式更為強大。比如說,你的降級方案除了考慮 display:contents 之外,還會說有可能用戶的瀏覽器對 display:flex 也不支持。在這樣的情況之下,咱們可以繼續降級到 float 的布局。

    不過我們在這里不會考慮降級到 float 的布局。但我們可以對 display: flex 和 display:contents 進行降級處理。這里會用到 @supports 中的 and 和 not 關鍵詞。上面的代碼就變成像下面這樣:

    @supports (display: flex) and (display: contents) {

    .feed ul,

    .feed li {

    display: contents;

    }

    .card {

    flex: 1 0 40%;

    }

    }

    @supports (display: flex) and (not (display: contents)) {

    .feed li {

    flex: 1 0 50%;

    }

    .feed li.nested {

    flex-basis: 100%;

    }

    .feed li.nested ul {

    display: flex;

    flex-wrap: wrap;

    }

    }

    甚至你還可以在 @supports 中使用CSS的自定義屬性,比如像下面這樣:

    @supports (–foo: green) {

    }

    如果你對 @supports 或CSS查詢特性相關的知識點還不足夠滿足的話,建議你閱讀下面的文章,深入的學習這方面的知識:

    • CSS3條件判斷: @supports
    • 說說CSS中的 @supports
    • Conditional CSS
    • 在 CSS 中使用特征查詢
    • Conditional CSS using CSS feature queries
    • Using Feature Queries in CSS
    • How to use CSS Feature Queries
    • Basic grid layout with fallbacks using feature queries
    • Layout Design with CSS Grid & Feature Queries
    • Feature Queries for CSS Grid fallbacks

    案例:聊天框

    現在我們有了一個漂亮的新聞提要(Newsfeed),接下來在前面的Newsfeed基礎上添加一個小的聊天框,這個聊天框固定在屏幕的右下角。

    Step7: 添加聊天框

    我們需要一個消息列表和一個文本域字段,方便用戶輸入消息。那么在 <body> 標簽的后面添加這個聊天框所需要的HTML標簽:

    <div class=”chat”>

    <div class=”messages”>

    <ul>

    <li><div class=”message”>Message 1</div></li>

    <li><div class=”message”>Message 2</div></li>

    <li><div class=”message”>Message 3</div></li>

    <li><div class=”message”>Message 4</div></li>

    <li><div class=”message”>Message 5</div></li>

    <li><div class=”message”>Message 6</div></li>

    <li><div class=”message”>Message 7</div></li>

    <li><div class=”message”>Message 8</div></li>

    <li><div class=”message”>Message 9</div></li>

    <li><div class=”message”>Message 10</div></li>

    </ul>

    </div>

    <input type=”text” class=”input”>

    </div>

    在沒有給聊天添加任何樣式的情況下,我們看到的效果是:

    Step08:給聊天框添加樣式

    先給聊天框添加一些基本樣式,讓它看起來有點像聊天框的樣子:

    .chat {

    background: #fff;

    border: 10px solid #000;

    bottom: 0;

    font-size: 10px;

    position: fixed;

    right: 0;

    width: 300px;

    }

    .messages {

    border-bottom: 5px solid #000;

    overflow: auto;

    padding: 10px;

    max-height: 300px;

    }

    .message {

    background: #000;

    border-radius: 5px;

    color: #fff;

    margin: 0 20% 10px 0;

    padding: 10px;

    }

    .messages li:last-child .message {

    margin-bottom: 0;

    }

    .input {

    border: none;

    display: block;

    padding: 10px;

    width: 100%;

    }

    效果看起來像下面這樣:

    Step09:滾動鏈接

    現在頁面上可以看到已經美化好的聊天框了,這個聊天框有一個可滾動的消息列表和一個文本輸入框,而且位于前面創建子的Newsfeed上面(如果沒有的話,你可以把你的瀏覽器縮?。?,如下:

    五個最新的CSS特性以及如何使用它們

    看上去是不是不錯。但是你有沒有注意到,當你滾動聊天框中的信息列表到底部的時候,會發生什么?感興趣的話,親自試一試。咱們做兩個小測試,先滾動頁面 body ,看看效果:

    五個最新的CSS特性以及如何使用它們

    然后再聊天框的信息列表中滾動,一直滾動到最底端,滾不動為止,看看效果以是:

    五個最新的CSS特性以及如何使用它們

    滾動Newsfeed,和我們想象的并沒有差異;但滾動聊天框中的消息列表時,卻不一樣,滾動到消息列表末端時,可以看到頁面 body 將開始滾動。這種效果被稱為 滾動鏈接 ,即 Scroll Chaining 。

    在我們這個示例中,這可能不是什么大問題,但在某些情況下,它可能就是一大問題了。比如Modal彈框,那就很有必要解決這樣現象。

    比較拙的解決方案就是給 body 添加 overflow:hidden ,但這有可能會影響我們的操作,甚至影響你瀏覽你的頁面。但值得慶幸的是,CSS有一個新特性可以做得更為完美,體驗更佳,而且使用起來并不復雜,只需要一行代碼即可,那就是CSS的 overscroll-behavior ,這個屬性有三個可取值:

    • auto :其默認值。元素(容器)的滾動會傳播給其祖先元素。有點類似JavaScript中的冒泡行為一樣
    • contain :阻止滾動鏈接。滾動行為不會傳播給其祖先元素,但會影響節點內的局部顯示。例如,Android上的光輝效果或iOS上的回彈效果。當用戶觸摸滾動邊界時會通知用戶。注意, overscroll-behavior:contain 在 html 元素上使用,可以阻止導航滾動操作
    • none :和 contain 一樣,但它也可以防止節點本身的滾動效果

    overscroll-behavior 屬性是 overscroll-behavior-x 和 overscroll-behavior-y 的簡寫,如果你只想控制其中一個方向的滾動行為,可以使用其中的某一個屬性。

    回到我們的示例來,在 .messages 類中添加下面這行代碼:

    .messages {

    overscroll-behavior-y: contain;

    }

    現在你再嘗試一下,在聊天框中的消息列表中上下滾動。此時你再滾動到消息列表末端時,它不再會影響 body 的滾動了(頁面的滾動):

    五個最新的CSS特性以及如何使用它們

    如果你想在PWA中實現下拉刷新的效果,比如下拉時刷新Newsfeed,那么這個屬性就非常方便。只需要在 body 或 html 元素中添加 overscroll-behavior:contain 即可。

    值得注意的是,這個屬性還不是W3C標準,而是Web孵化器WICG的一個建議。不過,說不定哪一天,這個特性就進入到W3C工作組中,成為W3C的一個標準。

    有關于這方面的更多介紹,建議閱讀下面幾篇文章:

    • 滾動的特性
    • CSS overscroll-behavior
    • Take control of your scroll: customizing pull-to-refresh and overflow effects

    Step10:折疊聊天框

    目前,聊天框占據了相當大的空間,如果我們不與其交互的話,會有點分散用戶的注意力。辛運的是,我們可以用CSS的選擇器特性來解決這個問題。這也是CSS的另一新特性,再一次向大家展示了CSS的魔力。

    首先調整一下現有的樣式。默認情況下,我們希望聊天框是處理一個折疊狀態,因此把 .message 的 max-height 值重置一下,在此設置為 0 ,并且把 padding 也重置為 0 。因為這個值剛剛好折疊了聊天框,而且又不影響其美觀。為了讓聊天框折疊和展開時有一個過渡的動畫效果,借助 CSS的 transition 屬性來實現。

    .messages {

    max-height: 0;

    padding: 0;

    transition: max-height 500ms;

    }

    效果看起來還不錯,如下所示:

    Step11:當聊天框得到焦點時,展開聊天框

    現在我們的聊天框中的信息列表是看不到。因為我們前面把信息列表折疊起來了?,F在我們要思考的是如何通過CSS來將其展開。這就會用到CSS的另一新特性 —— :focus-within 。

    有點類似于 :focus 偽類選擇器一樣,但是 :focus-within 與其不同之處是, 如果元素的任何后代元素得到焦點,它就會被匹配 。這就是這個屬性特別之處,因為它與CSS通常的工作方式相反,通常我們只能根據元素的祖先來選擇元素。

    在我們這個示例中,當 .chat 區域內的任何內容得到焦點時,重置一下 .message 的 max-height 和 padding 值。請記住,一個元素必須接受鍵盤或鼠標事件或其他形式的輸入,以便接收焦點。比如我們這個示例,點擊 <input> 輸入框就符合這個要求,可以達到我們想要的預期效果。

    .chat:focus-within .messages {

    max-height: 300px;

    padding: 10px;

    }

    你現在可以嘗試一下效果。點擊 input 讓其得到焦點,可以看到聊天框可以展開,反之聊天框又會折疊起來:

    五個最新的CSS特性以及如何使用它們

    Step12:進一步突顯 :focus-within 的魔力

    如果僅僅實現聊天框的折疊和展開效果,到上一步其實已經完成了。但對于一位有追求的前端,總是在嘗試很多極限性?;氐轿覀兊氖纠衼?,如果PM跟你提了一個新需求,當文本輸入框得到焦點之后,除了能展開聊天框之外,還希望聊天框底下的Newsfeed變得模糊。對于這樣的一個效果,怎么來實現呢?

    要實現這樣的效果,其實并不復雜,如果你有做過 自定義單選按鈕或復選框 (當然是純CSS),你應該會想到解決方案。我們可以 使用CSS選擇器中的兄弟組合器 ~ ,就可以很容易的做到這一點。使用 ~ 選擇器有一個前提需要注意,聊天框 .chat 需要在Newsfeed( .container)前面(指的是HTML結構,事實上我們已經這樣做了)。只有這樣才能通過下面的方式讓Newsfeed變得模糊:

    .chat:focus-within ~ .container {

    filter: blur(5px)

    }

    當然,這可能不是最佳的一個方案,但僅通過CSS的技術手段就能達到預期的效果,已經很酷了。感興趣的話,自己可以體驗一下:

    五個最新的CSS特性以及如何使用它們

    注意,Newfeed添加了 filter 效果,這將會改變元素的層疊順序,造成聊天框在Newsfeed下面。所以需要顯式的 .chat 中添加 z-index 的值。比如這里設置了 z-index: 1001 。具體原因可以查閱@張鑫旭老師的《 深入理解CSS中的層疊上下文和層疊順序 》一文。

    探索 :placeholder-shown

    五個最新的CSS特性以及如何使用它們

    首先要先分清楚, :placeholder-shown 和 ::placeholder 是不同的兩個東東。神奇的是 :placholder-shown 是W3C標準規范的一個屬性,而 ::placeholder 卻不是。 ::placeholder-shown 仍然會影響占位符文本的樣式。

    注意: :placeholder-shown 是一個偽類選擇器(它是一個處于特定狀態的元素); ::placeholder 是一個偽元素(一個在DOM中并不存在的可見元素)。

    另外, :placeholder-shown 也是新的選擇器之一(CSS Selectors Module Level 4新增了很多種偽類選擇器),它可以匹配任何顯示占位符文本的輸入。在我們的示例中,文本輸入框( input )并沒有任何占位符文本,所以先在HTML中的 input 元素中,添加 placeholder ,新增占位符文本。

    <input type=”text” class=”input” placeholder=”Enter your message”>

    然后在 input 之后添加一個新的元素,用來幫助用戶操作:

    <div class=”prompt”>Press enter to send</div>

    現在給這個幫助信息 .prompt 添加一些樣式,默認情況之它是被折疊起來了。

    .prompt {

    line-height: 2em;

    max-height: 0;

    overflow: hidden;

    padding: 0 10px;

    text-align: right;

    transition: max-height 500ms;

    }

    僅從外觀上看,似乎好像沒多出什么,就是在文本框中多了一個占位符文本:

    五個最新的CSS特性以及如何使用它們

    雖然沒多大區別,但這為后續的效果已埋下了一個伏筆。接著往下看。

    Step14:使用提示信息可見

    此時提示信息處于折疊狀態,并不可見,我想大家也想到了,要怎么使用 :placeholder-shown 讓其可見?大多數瀏覽器會顯示占位符文本,直到用戶在 input 中輸入真的值。為了 提高用戶使用表單的體驗 ,如果 input 得到對應的焦點之后,占位符文本并不隱藏,還起著提示作用,是不是更有意思,也對用戶有更好的幫助,畢竟我們不希望用戶發送空的消息,所以我們可以將這種行為關聯起來,只有在用戶輸入值時才顯示提示信息(也就是 .prompt 展開可見)。

    :placeholder-shown 表示的是占位文本符可見的狀態,而提示信息可見的時候,占位文本符不可見,也就是 input 有了一個真正的值。換句話來說,我們需要有一個 :placeholder-shown 的反轉(占位文本符不可見),這個時候我們可以借助 :not() 選擇器來幫我們做這樣的反轉。

    .input:not(:placeholder-shown) + .prompt {

    max-height: 2em;

    }

    將 max-height 設置為 font-size:10px 的兩倍,這里使用了 2em ,這個時候可以展開提信信息塊。簡單而有整潔。如果這個看似平凡的偽類選擇器能過通過最終的規范,那么我們將會看到一些巧妙的運用。來到這一步,效果變成:

    親自體驗一下,你在 input 隨便輸入一點內容,哪怕是空格,也能看到提示信息被展示出來了:

    五個最新的CSS特性以及如何使用它們

    不管 :focus-within 還是 :placeholder-shown ,它們都是CSS選擇器新增加的偽類選擇器,如果感興趣,建議你花些時間對這些方面進行了一了解:

    • Focusing on Focus Styles
    • A CSS Approach to Trap Focus Inside of an Element
    • CSS :focus-within
    • CSS :focus-within via @w3cplus
    • :placeholder-shown
    • Visually validate an input field using CSS
    • Intriguing CSS Level 4 Selectors
    • The Future Generation of CSS Selectors: Level 4
    • 下一代選擇器:CSS4
    • 即將推出的CSS4 Level 4 Selectors
    • CSS Level 4 Selectors to Watch Out For

    Step15:讓它充滿生機

    到目前為止,我們通過簡單的HTML和一些CSS特性完成了一個帶有聊天功能的新聞提要的基本架構,但是目前它是沒有生命的,只是一個純靜態的東西。也就是說用戶并不有用它做任何事情。這個案例包含了一些有趣的CSS新特性,但到現在為止不能修改DOM。如果想讓這個案例更為生動,那么就需要借助一些JavaScript功能,以便用戶能通過聊天框添加消息。

    首先,需要向 <input> 和類名 .messages 的子元素 ul 添加一個 ID ,以便JavaScript更好的獲取到對應的元素。同時給 input 元素添加一個 required 屬性,當用戶未輸入任何信息的時候,表單可以自動較驗。

    <ul id=”messages” …

    <input type=”text” id=”input” required …

    然后創建一個名為 script.js 文件,并且放置在 </body> 之前。不過我們的案例是在Codepen上做相應的演示,所以無需考慮創建一個單的 .js 文件。

    Step16:添加一些JavaScript

    我們需要給 <input> 添加一個事件函數,當監聽到鍵盤的 Enter 事件,獲取到 input 的值(如果有效)并將其添加到消息列表的末尾,清除字段并滾動到消息的底部。

    // 獲取相應的元素

    const input = document.getElementById(‘input’);

    const messages = document.getElementById(‘messages’);

    // 監聽input的鍵盤事件

    input.addEventListener(‘keypress’, (event) => {

    // 檢查是否按下Enter鍵

    if (event.keyCode === 13) {

    // 檢查字段是否有效

    if (input.validity.valid) {

    // 使用該值創建DOM元素

    const message = createMessage(input.value);

    // 將新創建的DOM元素添加到消息列表

    messages.appendChild(message);

    // 清除輸入框的值

    input.value = ”;

    // 滾動到消息列表的底部

    messages.parentNode.scrollTop = messages.parentNode.scrollHeight;

    }

    }

    });

    // 將input的值轉換為HTML的字符串

    function createMessage (value) {

    return stringToDom(`<li><div class=”message”>${value}</div></li>`)

    }

    // 將字符串轉換為真實的DOM

    function stringToDom (string) {

    const template = document.createElement(‘template’);

    template.innerHTML = string.trim();

    return template.content.firstChild;

    }

    現在,當你在 input 中輸入字段并按 Enter 鍵時,你將看到你輸入的消息添加到消息列表的底部。

    五個最新的CSS特性以及如何使用它們

    Step17:添加一引起額外的信息

    為了向大家演示最后一個CSS新特性 —— contain ,咱們需要做一些設計。我們將實現一個效果,在消息列表頂部的框中發送新消息的時間。當你將鼠標懸停在消息上時,就會有這個效果。

    首先,我們需要將這些信息添加到我們的新消息中。我們可以修改 createMessage 函數返回的值。

    function createMessage (value) {

    return stringToDom(`

    <li>

    <div class=”message message–mine” data-timestamp=”${new Date().toString()}”> ${value} </div>

    </li>

    `);

    }

    你已經注意到了,在 message 中新增加了一個類 message–mine 。并給這個類添加相應的樣式:

    .message–mine {

    background: #ff2089;

    margin-left: 20%;

    margin-right: 0;

    }

    當你新輸入內容,按下 Enter 鍵時,新增加的消息列表對應的結構就變成像下圖這樣的:

    五個最新的CSS特性以及如何使用它們

    顯示時間戳

    我們的目的是將創建消息的時間戳顯示在消息列表的頂部,我們需要這樣做,以便即使在滾動消息列表時,這個時間戳也總是可見的。這里我們借助CSS的偽元素來做:

    .message–mine::after {

    content: attr(data-timestamp);

    }

    這個時候你所看到的效果是這樣的:

    五個最新的CSS特性以及如何使用它們

    這個效果并不是我們想要的。我們在樣式上稍做修改,鼠標懸浮到新添加的消息列表上時才能看到時間戳,而且這個時間戳固定在消息區域的頂部。

    .message–mine:hover::after {

    background: #000;

    color: #ff2089;

    content: attr(data-timestamp);

    left: 0;

    padding: 5px;

    position: fixed;

    top: 0;

    width: 100%;

    }

    這個效果現在變成這樣了:

    五個最新的CSS特性以及如何使用它們

    現在時間戳固定在頁面的頂部,可以繼續優化一下,在 .messages 中添加 position: relative 。

    但也不起作用,那是因為固定定位是相對于 viewport 的,而不是相對于其祖先元素。那么這個時候,最后一個CSS新特性應該要出場了。

    Step19:探索Containment

    CSS Containment是一個令人興奮的新命題。它有許多選項,可以限制瀏覽器的樣式、布局和對特定元素的繪制。這在修改DOM時特別有用。在瀏覽器中,哪怕是很小的變化都有可能造成瀏覽器重繪整個頁面,這樣的消費是很貴,即使瀏覽器努力為我們做了很多優化,頁面的重繪還是對性能有一定影響的。

    使用CSS Containment,我們可以把頁面的部分圈起來,然后說“這里發生了什么,只在這里做相應的事”。這也是另一種方法,可以保護元素不受外部的變化而受影響。

    五個最新的CSS特性以及如何使用它們

    CSS的Containment是一個新屬性,使用關鍵字 contain ,它支持四個屬性值:

    layout

    paint

    size

    style

    您還可以結合關鍵字,如 contain: layout paint ,這將僅適用于一個元素的這些行為。但也包含支持兩個額外的值:

    • contain: strict 意同 contain: layout style paint size
    • contain: content 意同 contain: layout style paint

    每個值都有點不透明,所以我建議你閱讀規范并在開發者工具中使用它們來查看實際發生的情況。

    layout 和 paint 是兩個重要的值,因為它們在需要大量操作DOM時,對性能有一定的優化。然而,在我們的演示中,我們可以利用 contain: paint 我助我們進行時間戳定位。

    根據規范所描述,當使用 paint 時,“ 元素作為一個包含絕對定位和固定定位后代的塊 ”。這意味著,我們可以在 .chat 上設置 contain: paint ,這樣一來, .chat 中元素的固定定位將基于 card 而不是 viewport 。你可以通過使用 transform: translateZ(0) 獲得相同的效果。

    嘗試一下下,效果完美了:

    五個最新的CSS特性以及如何使用它們

    CSS Containment是較新的特性,目前只在Chrome 52+版本可以看到。如果你想深入的了解這方面的知識,可以閱讀一下下面的文章:

    • CSS Containment in Chrome 52譯文

    總結

    到這里就結束了,我們對這五個新的CSS特性有了一定的了解。其中大多數都是非常簡單的,但對于CSS Containment而言還是較為復雜,建議花更多的時間去詳細了解。雖然這是一些新特性,而且在部分瀏覽器中還未得到較好的支持,但這些新特終將有一天會來到你的身邊,你可以在項目中使用。今天花這么的篇幅,并且通過兩個示例來闡述這五個特性,主要是向大家展示這五個特性有何功能,如何在實際項目中使用。

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费