虽然CSS简单,但CSS是一门非常有意思的语言,CSS每年都有变化,而且都有不同的博主都在不同的时间段总结一些CSS的新特性。虽然这些新特性无法立刻得到众多浏览器的支持,但总是随着时间的发展,这些特性都会得到浏览器的支持。哪怕未得到支持,也有一些方法让浏览器支持,比如最为出外的cssnext,就可以让很多未来的CSS特性就立马使用,并且不用花太多时间来考虑浏览器的兼容性。

接下来要介绍的五个CSS新特性是:

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

这些CSS特性,估计有些同学已经接触过了,如果你未接触过,建议你继续跟随着下面的步骤继续往下阅读。

案例:创建一个新闻提要(Newsfeed)

通过一个新闻提要为例,分不同的步骤向大家阐述这个新闻提要是怎么制作的,以及在制作这个案例的时候,这五个CSS特性是如何在案例中得到运用。

Step1:新闻提要的HTML模板

我们这个案例其实很简单,并未使用任何JavaScript框架,还是使用原始的HTML结构来做这个Demo。所以我们需要一些简单的HTML的标签,帮助我们创建Demo。这里使用了一个类名为.containerdiv,该div包含了一个类名为.feedul,然后创建了十个li,每个li包含了一个类名为.carddiv

在第五个和第六个li之间创建了另一个名为nestedli,其包含了一个无序列表ul,而且包含了三个li创建三个卡片。


web前端开发学习Q-q-u-n: 767273102 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频)
<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)影响了整体的布局效果:

其实我们想要的,或者说理想状态下,所有的卡片按流的方式排列,但事实并未如此。造成这种现象的原因是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项目。

对web前端这门技术感兴趣的小伙伴可以加入到我们的学习圈来,正因为我不是211,985,只是个普通的本科生,英语不是特别好,数学不是特别好。所以我选择了前端。工作第六个年头了,我庆幸自己选择了这条路。767-273-102 秋裙。与大家分享一些学习方法,实战开发需要注意的细节。从零基础开始怎么样学好前端。都是一群有梦想的人,我们可能在不同的城市,但我们会一起结伴同行前端前端前端

首先删除现有.feed li的类名,然后在ulli是使用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查询特性,而不是某一种操作符。它的工作方式和你预期的一样,因此我们可以通过@supportsnot关键词对那些不支持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查询特性的魅力与潜力了,上面用到的仅仅是查查询特性中的部分功能,更强大的是你可以andornot结合起来,让你的条件表达式更为强大。比如说,你的降级方案除了考虑display:contents之外,还会说有可能用户的浏览器对display:flex也不支持。在这样的情况之下,咱们可以继续降级到float的布局。

不过我们在这里不会考虑降级到float的布局。但我们可以对display: flexdisplay:contents进行降级处理。这里会用到@supports中的andnot关键词。上面的代码就变成像下面这样:

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

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

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

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

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

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

  • auto:其默认值。元素(容器)的滚动会传播给其祖先元素。有点类似JavaScript中的冒泡行为一样
  • contain:阻止滚动链接。滚动行为不会传播给其祖先元素,但会影响节点内的局部显示。例如,Android上的光辉效果或iOS上的回弹效果。当用户触摸滚动边界时会通知用户。注意,overscroll-behavior:containhtml元素上使用,可以阻止导航滚动操作
  • none:和contain一样,但它也可以防止节点本身的滚动效果

overscroll-behavior属性是overscroll-behavior-xoverscroll-behavior-y的简写,如果你只想控制其中一个方向的滚动行为,可以使用其中的某一个属性。

回到我们的示例来,在.messages类中添加下面这行代码:

.messages {overscroll-behavior-y: contain;
}

现在你再尝试一下,在聊天框中的消息列表中上下滚动。此时你再滚动到消息列表末端时,它不再会影响body的滚动了(页面的滚动):

如果你想在PWA中实现下拉刷新的效果,比如下拉时刷新Newsfeed,那么这个属性就非常方便。只需要在bodyhtml元素中添加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的魔力。

首先调整一下现有的样式。默认情况下,我们希望聊天框是处理一个折叠状态,因此把.messagemax-height值重置一下,在此设置为0,并且把padding也重置为0。因为这个值刚刚好折叠了聊天框,而且又不影响其美观。为了让聊天框折叠和展开时有一个过渡的动画效果,借助CSS的transition属性来实现。

.messages {...max-height: 0;padding: 0;transition: max-height 500ms;
}

效果看起来还不错,如下所示:

Step11:当聊天框得到焦点时,展开聊天框

现在我们的聊天框中的信息列表是看不到。因为我们前面把信息列表折叠起来了。现在我们要思考的是如何通过CSS来将其展开。这就会用到CSS的另一新特性 —— :focus-within

有点类似于:focus伪类选择器一样,但是:focus-within与其不同之处是,如果元素的任何后代元素得到焦点,它就会被匹配。这就是这个属性特别之处,因为它与CSS通常的工作方式相反,通常我们只能根据元素的祖先来选择元素。

在我们这个示例中,当.chat区域内的任何内容得到焦点时,重置一下.messagemax-heightpadding值。请记住,一个元素必须接受键盘或鼠标事件或其他形式的输入,以便接收焦点。比如我们这个示例,点击<input>输入框就符合这个要求,可以达到我们想要的预期效果。

.chat:focus-within .messages {max-height: 300px;padding: 10px;
}

你现在可以尝试一下效果。点击input让其得到焦点,可以看到聊天框可以展开,反之聊天框又会折叠起来:

Step12:进一步突显:focus-within的魔力

如果仅仅实现聊天框的折叠和展开效果,到上一步其实已经完成了。但对于一位有追求的前端,总是在尝试很多极限性。回到我们的示例中来,如果PM跟你提了一个新需求,当文本输入框得到焦点之后,除了能展开聊天框之外,还希望聊天框底下的Newsfeed变得模糊。对于这样的一个效果,怎么来实现呢?

要实现这样的效果,其实并不复杂,如果你有做过自定义单选按钮或复选框(当然是纯CSS),你应该会想到解决方案。我们可以使用CSS选择器中的兄弟组合器~,就可以很容易的做到这一点。使用~选择器有一个前提需要注意,聊天框.chat需要在Newsfeed(.container)前面(指的是HTML结构,事实上我们已经这样做了)。只有这样才能通过下面的方式让Newsfeed变得模糊:

.chat:focus-within ~ .container {filter: blur(5px)
}

当然,这可能不是最佳的一个方案,但仅通过CSS的技术手段就能达到预期的效果,已经很酷了。感兴趣的话,自己可以体验一下:

注意,Newfeed添加了filter效果,这将会改变元素的层叠顺序,造成聊天框在Newsfeed下面。所以需要显式的.chat中添加z-index的值。比如这里设置了z-index: 1001。具体原因可以查阅@张鑫旭老师的《深入理解CSS中的层叠上下文和层叠顺序》一文。

探索:placeholder-shown

首先要先分清楚,: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;
}

仅从外观上看,似乎好像没多出什么,就是在文本框中多了一个占位符文本:

虽然没多大区别,但这为后续的效果已埋下了一个伏笔。接着往下看。

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随便输入一点内容,哪怕是空格,也能看到提示信息被展示出来了:

不管: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键时,你将看到你输入的消息添加到消息列表的底部。

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的伪元素来做:

.message--mine::after {content: attr(data-timestamp);
}

这个时候你所看到的效果是这样的:

这个效果并不是我们想要的。我们在样式上稍做修改,鼠标悬浮到新添加的消息列表上时才能看到时间戳,而且这个时间戳固定在消息区域的顶部。

.message--mine:hover::after {background: #000;color: #ff2089;content: attr(data-timestamp);left: 0;padding: 5px;position: fixed;top: 0;width: 100%;
}

这个效果现在变成这样了:

现在时间戳固定在页面的顶部,可以继续优化一下,在.messages中添加position: relative

但也不起作用,那是因为固定定位是相对于viewport的,而不是相对于其祖先元素。那么这个时候,最后一个CSS新特性应该要出场了。

Step19:探索Containment

CSS Containment是一个令人兴奋的新命题。它有许多选项,可以限制浏览器的样式、布局和对特定元素的绘制。这在修改DOM时特别有用。在浏览器中,哪怕是很小的变化都有可能造成浏览器重绘整个页面,这样的消费是很贵,即使浏览器努力为我们做了很多优化,页面的重绘还是对性能有一定影响的。

使用CSS Containment,我们可以把页面的部分圈起来,然后说“这里发生了什么,只在这里做相应的事”。这也是另一种方法,可以保护元素不受外部的变化而受影响。

CSS的Containment是一个新属性,使用关键字contain,它支持四个属性值:

  • layout:这个值打开该元素的布局控制。这确保所包含元素对布局目的完全不透明;外部不能影响其内部布局,反之亦然
  • paint:这个值打开该元素的绘制控制。这确保包含元素的后代节点不显示在其边界外,因此,如果一个元素在屏幕外或是不可见的,它的后代节点同样也被保证是不可见的
  • size:这个值打开该元素的尺寸控制。这确保包含元素可以无需检查其后代节点进行布局。
  • style:这个值打开该元素的样式控制。这确保了,对于性能这会不仅仅作用于一个元素及其后代,这些效果也不忽视包含的元素

您还可以结合关键字,如contain: layout paint,这将仅适用于一个元素的这些行为。但也包含支持两个额外的值:

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

每个值都有点不透明,所以我建议你阅读规范并在开发者工具中使用它们来查看实际发生的情况。

layoutpaint是两个重要的值,因为它们在需要大量操作DOM时,对性能有一定的优化。然而,在我们的演示中,我们可以利用contain: paint我助我们进行时间戳定位。

根据规范所描述,当使用paint时,“元素作为一个包含绝对定位和固定定位后代的块”。这意味着,我们可以在.chat上设置contain: paint,这样一来,.chat中元素的固定定位将基于card而不是viewport。你可以通过使用transform: translateZ(0)获得相同的效果。

对web前端这门技术感兴趣的小伙伴可以加入到我们的学习圈来,正因为我不是211,985,只是个普通的本科生,英语不是特别好,数学不是特别好。所以我选择了前端。工作第六个年头了,我庆幸自己选择了这条路。767-273-102 秋裙。与大家分享一些学习方法,实战开发需要注意的细节。从零基础开始怎么样学好前端。都是一群有梦想的人,我们可能在不同的城市,但我们会一起结伴同行前端前端前端

尝试一下下,效果完美了:

CSS Containment是较新的特性,目前只在Chrome 52+版本可以看到。

web前端入门到实战:五个最新的CSS特性以及如何使用它们相关推荐

  1. web前端入门到实战:11种常用css样式之滚动条与显示隐藏

    滚动条展示 overflow-x: hidden;/是否对内容的左/右边缘进行裁剪/overflow-y: hidden;/是否对内容的上/下边缘进行裁剪/overflow:scroll;/左右滚动/ ...

  2. html前端页面的基本骨架是,web前端入门到实战:css实现的骨架屏方案

    web前端入门到实战:css实现的骨架屏方案 发布时间:2020-08-04 01:32:03 来源:51CTO 阅读:152 作者:前端向南 优点 简单,不需要工程,不用puppeteer生成骨架d ...

  3. 转圈加载html,web前端入门到实战:纯CSS实现加载转圈样式

    web前端入门到实战:纯CSS实现加载转圈样式 发布时间:2020-05-27 18:11:33 来源:51CTO 阅读:134 作者:前端向南 不同的项目中对于等待加载时转圈圈的样式是不同的,有的是 ...

  4. web前端入门到实战:CSS3两大实用属性,以及网页制作技巧

    一.使用 :not() 在菜单上应用/取消应用边框 我们通常的做法是先给每个菜单项设置边框,然后在设置最后一个菜单的边框为零 /* add border */ .nav li {border-righ ...

  5. web前端入门到实战:css绘制各种形状图形

    虽然我们现在大都使用字体图标或者svg图片,似乎使用 CSS 来做图标意义不是很大,但怎么实现这些图标用到的一些技巧及思路是很值得我们的学习. 一.实心圆 .circle {width: 120px; ...

  6. web前端入门到实战:实现图形验证码

    什么是图形验证码 图形验证码是验证码的一种.验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers a ...

  7. web前端入门到实战:CSS 滚动捕捉技术(Scroll Snapping)

    CSS 滚动捕捉允许用户完成滚动之后将视口锁定到某个元素的位置.非常适合用来建立下面这样的应用: 基本使用 实现滚动捕捉主要依靠两个属性:容器元素的 scroll-snap-type 属性,以及子元素 ...

  8. web前端入门到实战:HTML5 VideoAPI,打造自己的Web视频播放器

    本文将使用HTML5提供的VideoAPI做一个自定义的视频播放器,需要用到HTML5提供的video标签.以及HTML5提供的对JavascriptAPI的扩展. 一.基础知识 1.用法 <v ...

  9. web前端入门到实战:HTML属性选择器(下)

    一.格式 标签[属性=值]:{属性:值:} 1.属性的取值是以什么开头的 attribute |= value(CSS2)attribute^=value(CSS3)两者之间的区别:CSS2中只能找到 ...

最新文章

  1. VSCode中屏蔽文件files.exclude和屏蔽文件搜索search.exclude
  2. java面向对象测试_Java面向对象测试题(一).doc
  3. 企业管理系统java web_JavaWeb 基于 web的 企业人事管理系统 Jsp/Servlet 242万源代码下载- www.pudn.com...
  4. 关于负载均衡的一切:总结与思考
  5. 美团扫码付的前端可用性保障实践
  6. LeetCode 435. 无重叠区间(贪心/动态规划)
  7. 一个Python爬虫工程师学习养成记
  8. 《Spring Data实战》——导读
  9. jQuery源码阅读(一)---jQuery源码整体架构
  10. ezcad旋转轴标刻参数_EzCad 2.0 扩展轴标刻插件使用说明书简体中文(.pdf
  11. 【NLP】文本情感分析
  12. springboot整合apache ftpserver详细教程(看这一篇就够了)
  13. 在Visual Studio 2019 搭建 QGIS3.22 二次开发环境
  14. qtableview点击行将整行数据传过去_三部评分达到九分以上的电视剧,琅琊榜甄嬛传在列...
  15. 性价比打过折的故宫紫禁城
  16. DBeaver 给id设置为键 以及执行sql查询语句
  17. 给出一个不多于五位的正整数,求出它是几位数
  18. Python爬虫-利用xpath解析爬取58二手房详细信息
  19. 8421码、5421码、2421码及余三码
  20. python遇到错误跳过_python跳过错误

热门文章

  1. Win10安装GCC/G++运行环境
  2. Button的学习教程
  3. Ubuntu 立即更新网卡配置,重启网卡
  4. 从To C到To B,小米如何做好一门“慢”生意?
  5. 分布式系统认证解决方案SpringSecurityOAuth2.0(二)分布式系统认证流程分析与实现
  6. centos7删除文件夹命令_centos彻底删除文件夹、文件命令
  7. 浏览器的一些滚动行为鉴赏
  8. 微服务注册中心 Nacos 实现原理详解!
  9. Linux C语言 Zlib 实现解压zip文件
  10. 忘了Excel 2003文档的密码怎么办