栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Html/CSS > CSS教程

五个最新的CSS特性以及如何使用它们

CSS教程 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

五个最新的CSS特性以及如何使用它们

虽然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创建三个卡片。

    
        
  • Card 1
  •         
  • Card 2
  •         
  • Card 3
  •         
  • Card 4
  •         
  • Card 5
  •                      
                      
    • Card A
    •                 
    • Card B
    •                 
    • Card C
    •             
                     
  • Card 6
  •         
  • Card 7
  •         
  • Card 8
  •         
  • Card 9
  •         
  • Card 10
  •     

    在没有任何样式的情况之下,你看到的效果是这样的:

    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)影响了整体的布局效果:

    其实我们想要的,或者说理想状态下,所有的卡片按流的方式排列,但事实并未如此。造成这种现象的原因是Flex容器 —— ul.feed设置了display:flex(创建了一个Flex容器),创建Flex容器之后,只会对其子元素(ul.feed > li.card)有影响,即可子元素自动会变成Flex项目。但不会影响其后代子元素,换句话说,.nested > li是无法自动变成Flex项目。

    通常解决这个问题的唯一方法是更改HTML模板,但有些情况之下,比如说在CMS系统中(假设你没有修改HTML标签的权利),那么面对这种情况,你就会束手无策了。当然,你也许会想到使用Javascript来处理。或许以前你会这么想,但时至今日,咱们可以通过新的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元素):

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

    可以通过在.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的浏览器,你将看到的效果如下:

    在不支持display:contents的浏览器,看到的效果又像下面这样:

    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: 添加聊天框

    我们需要一个消息列表和一个文本域字段,方便用户输入消息。那么在标签的后面添加这个聊天框所需要的HTML标签:

        
            
                  
    • Message 1
    •             
    • Message 2
    •             
    • Message 3
    •             
    • Message 4
    •             
    • Message 5
    •             
    • Message 6
    •             
    • Message 7
    •             
    • Message 8
    •             
    • Message 9
    •             
    • Message 10
    •         
             

    在没有给聊天添加任何样式的情况下,我们看到的效果是:

    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上面(如果没有的话,你可以把你的浏览器缩小),如下:

    看上去是不是不错。但是你有没有注意到,当你滚动聊天框中的信息列表到底部的时候,会发生什么?感兴趣的话,亲自试一试。咱们做两个小测试,先滚动页面body,看看效果:

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

    滚动Newsfeed,和我们想象的并没有差异;但滚动聊天框中的消息列表时,却不一样,滚动到消息列表末端时,可以看到页面body将开始滚动。这种效果被称为滚动链接,即Scroll Chaining

    在我们这个示例中,这可能不是什么大问题,但在某些情况下,它可能就是一大问题了。比如Modal弹框,那就很有必要解决这样现象。

    比较拙的解决方案就是给body添加overflow:hidden,但这有可能会影响我们的操作,甚至影响你浏览你的页面。但值得庆幸的是,CSS有一个新特性可以做得更为完美,体验更佳,而且使用起来并不复杂,只需要一行代码即可,那就是CSS的overscroll-behavior,这个属性有三个可取值:

    • auto:其默认值。元素(容器)的滚动会传播给其祖先元素。有点类似Javascript中的冒泡行为一样

    • contain:阻止滚动链接。滚动行为不会传播给其祖先元素,但会影响节点内的局部显示。例如,Android上的光辉效果或iOS上的回弹效果。当��

    作者:大漠

    原文链接:https://www.w3cplus.com/css/5-hot-new-css-features-and-how-to-use-them.html

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/242727.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号