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绘制图标的相关教程:

除此之外,社区中还有两个非常有意思的东东。比如 @Lynn Fisher 整理的 使用一个 div 绘制各种图形 CSSBattle (使用最少的代码量绘制图形):

如果你去查阅了别人的代码,你会发现在CSS中,可以通过 borderbox-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 中的新特性。

在该规范中新增了两个特性: 鼠标悬停指针

如果你对这方面的新特性感兴趣的话,还可以阅读下面相关文章:

另外,在 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 animationSplitting JS 结合在一起,还可以做一些更有意思的文本效果,比如:

上面的Demo来自于《 Variable Font Animation with CSS and Splitting JS 》一文。

@Mandy Michael 创建了 VariableFonts.dev ,用不同的字体创建了令人惊艳的字体变量的动效。

亚像素渲染和边框

亚像素渲染 一直是一个头痛的问题。社区有关于这方面的讨论也比较多:

特别是在一些布局方案中,比如Flexible布局, vw 布局 或者 % 单位 的运用等,不同的浏览器转换出来的值都带有不同位数的小数。

就最近, @hj_chen 在墨尔本首届 Talk.CSS大会 上就聊到 亚像素和 border 相关的话题 。首先和大家聊了不同浏览器中盒模型中 padding 最小值会有何不同,直接上文章中的图吧:

Firefox中的截图

Chrome中的截图

Safari中的截图

回到文章中有关于 border-width 的讨论。这里多的不说, 直接W3C规范中的一段描述贴过来

The lengths corresponding to thin , medium , and thick are not specified, but the values are constant throughout a document and thin ≤ medium ≤ thick . A UA could, e.g., make the thickness depend on the medium font size: one choice might be 1 , 3 & 5px when the medium font size is 17px or less. Negative values are not allowed.

详细的讨论还是阅读原文吧 !

Flexbox中的两个小技巧

第五届CSS Conf大会 上, @hj_chen 分享的《 新时代CSS布局 》的话题:

这里面有一个关于Flexbox的小技巧,估计大家在平时使用的过程中会忽略:

经如下面这样的一个Demo:

有关于Flexbox中关于 margin 更多的使用可以看下面这个示例:

如果你对这方面感兴趣的话,还可以阅读下面相关教程:

在《 你所不知道的CSS Overflow Module 》一文中和大家一起聊了有关于CSS Overflow Module中的相关知识。但我们有一个关于Flexbox容器上使用 overflowpadding 的场景忽略了。即: 忽略滚动容器末端边缘的 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 》一文,详细介绍了其中的为什么?下面的案例就是来自于该教程中的:

再见了

BBC已经将 移到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 */
}

来看一个示例: