Web技巧(17)
上周又断档一期了,这周不能再断了。这两天翻阅了@hj_chen在新家坡组织的Talk.css沙龙中的一些PPT,有些内容还是蛮有意思了。国外氛围真不错,其实国内也有不少同学在搞沙龙。前面社区活动也不少,这周参加了腾讯Live前端大会。下个月@裕波在成都举办第五届FEDay。
想去参加的可以点击上面的链接购票了哟。
广告插入完了,我们接着今天的内容。
CSS绘制图形
CSS绘制图形在社区中已经不是什么新东西了,上次团队周会也有同学问起我,怎么用CSS来绘制图形呢,有没有什么工具?有没有什么技巧。其实使用CSS来绘制图形并没有什么捷径,只是一些内功。内功练习好了,绘制图形还是很简单的。比如@wentin就曾用纯CSS绘制了512
个图标:
前两天@张鑫旭 老司机也整了一个CSS绘制图标的库:
@张鑫旭 老司机还专门为这方面写了两篇文章:《常见纯CSS图标的代码分离与整理》和《是时候了,无外链的CSS开发策略》。
@hj_chen在Talk.css中也分享过这方面的主题《Creating art with CSS》:
在PPT后面还提供了很多有关于如何使用CSS绘制图标的相关教程:
- Single Div Drawings with CSS
- A Beginner’s Guide to Pure CSS Images
- How I started drawing CSS Images
- How to create pure CSS illustrations and animate them: Part1、Part2和Part3
- Pure CSS Drawing Essentials
除此之外,社区中还有两个非常有意思的东东。比如@Lynn Fisher整理的 使用一个div
绘制各种图形 和 CSSBattle(使用最少的代码量绘制图形):
如果你去查阅了别人的代码,你会发现在CSS中,可以通过
border
、box-shadow
和渐变绘制一些图形或纹理图案。
这样来介绍background-blend-mode
记得在Web技巧的第五期中介绍了CSS混合模式的计算方式,在第六期中介绍了混合模式在CSS中的使用场景。@Natalie在她的教程《background-blend-mode
property》一文中使用另一种方式来介绍background-blend-mode
:
交错的CSS transition
效果
首先用下列的效果来告诉大家什么是交错的CSS transition
效果:
其中最关键的是在不同的列表上的transition-delay
使用了不同的值:
@media (hover: hover) {
.list li a span {
transform: translateY(100px);
transition: 0.2s;
}
.list:hover span {
transform: translateY(0);
}
.list li:nth-child(1) span {
transition-delay: 0.0s;
}
.list li:nth-child(2) span {
transition-delay: 0.05s;
}
.list li:nth-child(3) span {
transition-delay: 0.1s;
}
.list li:nth-child(4) span {
transition-delay: 0.15s;
}
.list li:nth-child(5) span {
transition-delay: 0.2s;
}
.list li:nth-child(6) span {
transition-delay: 0.25s;
}
}
看上去没啥特殊之处。但这里有一个我们平时不怎么关注的点,即在@media
的条件设置中还可以使用(hover:hover)
。原来这是CSS Media Queries Level 4中的新特性。
如果你对这方面的新特性感兴趣的话,还可以阅读下面相关文章:
- What the hell’s up with
@media
not? - Detect a touch device with only CSS
- Introducing CSS Interaction Media Queries
- Using Media Queries For Responsive Design In 2018
- Useful CSS Media Query Features
另外,在CSS Media Query Level 5的版本中新增的特性会让媒体查询变得更容易,更灵活。比如:
// BEFORE
@media (min-width: 20em), (min-height: 40em) {
@media not all and (pointer: none) { … }
}
@media (min-width: 20em) and (max-width: 40em) { … }
// AFTER
@media ((min-width: 20em) or (min-height: 40em)) and (not (pointer: none)) { …}
@media (20em <= width <= 40em) { … }
CSS的@
规则中你不知道的知识点
在图解CSS系列中,有一个章节是专门来介绍 条件CSS 相关的属性,比如@media
、@supports
、@viewport
等。这几个属性又是CSS的@
规则中的一部分属性。
其中有些@
规则的知识我们平时是并不怎么关注的。比如@
规则中选择器的权重。就拿@media
、@keframes
和@supports
来举例吧。
比如下面这个示例:
body {
background: red;
}
@media (min-width: 1px) {
body {
background: black;
}
}
结果页面的背景颜色是black
。这是因为@media
增加了选择器的权重?带着这个疑问再看下面这个示例:
@media (min-width: 1px) {
body {
background: black;
}
}
body {
background: red;
}
结果背景是red
。如此来看,@media
并不影响选择器权重。
再来看@keyframes
:
@keyframes winner {
100% { background: green; }
}
body {
background: red !important;
animation: winner forwards;
}
你可能会认为最终背景色是red
,尤其是有!important
加持的情况之下。在Chrome中它是green
(不过在Firefox是red
,据说自2014年起这就是Firefox的一个坑)。其实@keyframes
并没有增加选择器的权重,只不过@keyframes
中的样式覆盖了规则外的样式。给你造成一个假象:@keyframes
的选择器权重更大。
相关的介绍可以阅读 @Chris Coyier的《How much specificity do @rules
have, like @keyframes
and @media
?》一文。
在上面的基础上扩展一下,那@supports
对选择器权重会有影响吗?比如下面这个示例,最终的背景颜色是什么呢?
@supports (--a: b){
body {
background: red;
}
}
body {
background: green;
}
@supports (--a: b){
body {
background: yellow;
}
}
如果看不出来,可以尝试着在浏览器中跑一下上面的示例代码。
@
规则中还有一个比较有意思的东西,那就是@support
和@media
可以相互嵌套,而且不依赖于任何的CSS处理器:
@supports (--a: b) {
@media (min-width: 1px) {
body {
background: red;
}
}
}
或者:
@media (min-width: 1px) {
@supports (--a: b) {
body {
background: #f36;
}
}
}
甚至还可以更复杂一些:
@media (min-width: 2px) {
@media (min-width: 1px) {
@supports (--a: b) {
@supports (display: flex) {
body {
background: pink;
}
}
}
}
}
虽然这样写,浏览器可以识别。但要注意哟,嵌套的层级越深给自己挖的坑会更深。
斜线体和字体变量
在字体变体font-variation-*
一文中,介绍了字体变量的使用。比如下面这样的一个效果,就是font-variation-*
实现的:
在font-variable-settings
中我们可以使用slnt
来设置斜体文本效果。除了该方法之外,我们可以使用font-style:oblique
来替代该方法。另外还可以使用字体变量wght
来给文本加粗。换句话说:
font-variable-settings: "wght" 500;
// 等效于
font-weight: 500
font-variable-settings: "slnt" 4;
// 等效于
font-style: oblique 4deg
即:
/* BEFORE */
h2 {
font-variation-settings: "wght" 500, "slnt" 4;
}
/* AFTER */
h2 {
font-weight: 500;
font-style: oblique 4deg;
}
有关于这方面的更多的介绍可以阅读:
如果把CSS animation
和 Splitting JS结合在一起,还可以做一些更有意思的文本效果,比如:
上面的Demo来自于《Variable Font Animation with CSS and Splitting JS》一文。
@Mandy Michael创建了VariableFonts.dev,用不同的字体创建了令人惊艳的字体变量的动效。
亚像素渲染和边框
亚像素渲染一直是一个头痛的问题。社区有关于这方面的讨论也比较多:
- Sub-Pixel Problems in CSS
- Not so pixel perfect in Firefox
- Sub-Pixel Font Rendering Technology: How it works?
- Subpixel rendering and image resizing
- Improving Font Rendering With CSS
- CSS Sub-pixel Background Misalignments
- Antialiasing 101
- Browser Rounding and Fractional Pixels
特别是在一些布局方案中,比如Flexible布局,vw
布局或者%
单位的运用等,不同的浏览器转换出来的值都带有不同位数的小数。
就最近,@hj_chen在墨尔本首届Talk.CSS大会上就聊到亚像素和border
相关的话题。首先和大家聊了不同浏览器中盒模型中padding
最小值会有何不同,直接上文章中的图吧:
Firefox中的截图
Chrome中的截图
Safari中的截图
回到文章中有关于border-width
的讨论。这里多的不说,直接W3C规范中的一段描述贴过来:
The lengths corresponding to
thin
,medium
, andthick
are not specified, but the values are constant throughout a document andthin ≤ medium ≤ thick
. AUA
could, e.g., make the thickness depend on the medium font size: one choice might be1
,3
&5px
when themedium
font size is17px
or less. Negative<length>
values are not allowed.
Flexbox中的两个小技巧
在第五届CSS Conf大会上,@hj_chen分享的《新时代CSS布局》的话题:
这里面有一个关于Flexbox的小技巧,估计大家在平时使用的过程中会忽略:
经如下面这样的一个Demo:
有关于Flexbox中关于margin
更多的使用可以看下面这个示例:
如果你对这方面感兴趣的话,还可以阅读下面相关教程:
- The peculiar magic of flexbox and auto margins
- Everything You Need To Know About Alignment In Flexbox
- 探秘 flex 上下文中神奇的自动 margin
在《你所不知道的CSS Overflow Module》一文中和大家一起聊了有关于CSS Overflow Module中的相关知识。但我们有一个关于Flexbox容器上使用overflow
和padding
的场景忽略了。即:忽略滚动容器末端边缘的padding
。比如:
.container {
display: flex;
overflow-x: scroll;
padding: 1em; /* browsers ignore the padding-right component */
}
你将看到的效果会如下:
解决这个问题,很简单:
.container::after {
content: '';
padding-right: 0.02px; /* smallest size that is cross browser */
}
有关于方面可以阅读《Flexbox and padding》一文,详细介绍了其中的为什么?下面的案例就是来自于该教程中的:
再见了<iframe>
BBC已经将<iframe>
移到Shadow DOM中了,据说性能提高了近25%
。@Toby Cox在Medium上就写了一篇有关于这方面的文章。要是感兴趣的话,可以阅读《Goodbye iframes》。
tab-size
也来了
现在可以使用tab-size
来调整tab
字符显示的空格量:
pre {
tab-size: 8; /* default. Pretty big! */
tab-size: 2;
tab-size: 13px; /* you can set a width-per-tab also */
}
来看一个示例:
上面的示例来自于@Chris Coyier的《tab-size》一文。
Day/Night Ambient Light Animation
最后给大家展示一个@Mandy Michael的一个案例,根据环境能切换白天和晚上。有意思吧: