Web技巧(17)

1,053 阅读9分钟

上周又断档一期了,这周不能再断了。这两天翻阅了@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

See the Pen background-blend-mode example by Airen (@airen) on CodePen.

交错的CSS transition效果

首先用下列的效果来告诉大家什么是交错的CSS transition效果:

See the Pen Staggered Animations by Chris Coyier (@chriscoyier) on CodePen.

其中最关键的是在不同的列表上的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;
                }
            }
        }
    }
}

虽然这样写,浏览器可以识别。但要注意哟,嵌套的层级越深给自己挖的坑会更深。

See the Pen Nest and Specificity in @rules by Airen (@airen) on CodePen.

斜线体和字体变量

字体变体font-variation-*一文中,介绍了字体变量的使用。比如下面这样的一个效果,就是font-variation-*实现的:

See the Pen Grassy Text with Variable fonts. by Airen (@airen) on CodePen.

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

See the Pen Variable font animation by Michelle Barker (@michellebarker) on CodePen.

上面的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 <length> values are not allowed.

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

Flexbox中的两个小技巧

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

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

经如下面这样的一个Demo:

See the Pen Flexbox Nav by willcodes (@willcodes) on CodePen.

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

See the Pen css: Flexbox - margin property by goerk (@goerk) on CodePen.

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

在《你所不知道的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》一文,详细介绍了其中的为什么?下面的案例就是来自于该教程中的:

See the Pen Flex container padding hack by Chen Hui Jing (@huijing) on CodePen.

再见了<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 */
}

来看一个示例:

See the Pen Demos of `tab-size` by Chris Coyier (@chriscoyier) on CodePen.

上面的示例来自于@Chris Coyier的《tab-size》一文。

Day/Night Ambient Light Animation

最后给大家展示一个@Mandy Michael的一个案例,根据环境能切换白天和晚上。有意思吧:

See the Pen Day/Night Ambient Light Animation by Mandy Michael (@mandymichael) on CodePen.