

Web技巧(15)
source link: https://www.tuicool.com/articles/AZFZfqJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

上一期咱们围绕着Web动画展开,其中有的动画对部分用户群体会造成不良的反应,会引起 癫痫 。为此,为了避免这种现象出现,可以使用条件CSS中 @media
中的 prefers-reduced-motion
条件来做处理。除此之外, prefers-reduced-motion
在 <picture>
元素中还有一些小技巧,可以帮我们做一些其他有意义的事情。这一期,就从这个特性开始讲起。
prefers-reduced-motion
和 <picture>
的结合
<picture>
是HTML5的一个元素 ,可以使用该元素来较好的实现响应式图片。另外,HTML的 <img>
元素的 srcset
和 sizes
属性也能实现类似的效果。
如果你对Web中图像相关的知识感兴趣的话,可以花点时间阅读下面相关的文章:
回到 prefers-reduced-motion
和 <picture>
上来。
当用户系统中开启 减弱动态效果 之后,我们就可以通过媒体查询 @media
中 prefers-reduced-motion
来减弱动态效果,即 元素直接不启用任何动效 :
/* 开启 减弱动态效果 的设备会禁用 aniName动画 */ @media screen and (prefers-reduced-motion) { / * 禁用不必要的动画 * / .element { animation: none; } }
上面对于CSS控制的动效可以得到很好的降级处理,但Web页面会启用一些 .gif
动态图片。那么对于使用媒体查询就不好处理。不过,值得庆幸的是,HTML5的 <picture>
可以基于 source
中的 media
值来对动态图做一些降级处理。当然,在 media
中也同样需要基于 prefers-reduced-motion
的取值。比如下面这个示例:
<picture> <source srcset="static.png" media="(prefers-reduced-motion: reduce)" /> <img srcset="animated.gif" alt="animated image" /> </picture>
就上面的示例而言,在 <picture>
中的 <img>
元素引入了默认的动态图片,然后在 <source>
中引入降级处理的图片。一旦用户系统启用了“减弱动态效果”:
Web终端(比如Safari浏览器)就会启用降级图片 static.png
。
虽然 .gif
动图可以让视觉效果动起来(Web动效中模式之一),但 .gif
文件的引用在性能上是有所制约,特别是在移动终端上。不过,除了 .gif
动图之外,还可以使用 .mp4
这样的视频文件也能让Web视觉效果动起来,而且视频要比 .gif
图性能好得多。事实上,有不少同学开始 将 .gif
文件转换成视频文件 ,然后再将其运用到Web中。
那么我们就可以在 <picture>
的 <source>
中引入一个 .mp4
文件。只不过这样我们就需要三个源媒体文件:
- 当开启“减弱动态效果”,会启用非动态图片,比如
static.png
- 同样在
<img>
中引用一个动态图片做为默认资源,比如animated.gif
- 如果识别
<picture>
中引用的资源,而且未开启“减弱动态效果”,则会启用视频文件来替代.gif
图,比如animated.mp4
例如:
<picture> <source srcset="static.png" media="(prefers-reduced-motion: reduce)" /> <source srcset="animated.mp4" type="video/mp4" /> <img srcset="animated.gif" alt="animated image" /> </picture>
就上例,在不同的浏览器会加载不同的源媒体:
虽然Firefox也支持 <picture>
元素,但它似乎不能正常工作,加载的依旧是 animated.gif
文件。具体原因不名,有可能是Firefox对 <source>
的支持还有一定的缺陷。
有关于这方面更详细的介绍可以阅读@Chris Coyier的《 Reduced Motion Picture Technique, Take Two 》一文。
Flexbox 和 Grid 容器中的伪元素
熟悉 Flexbox 和Grid布局的同学都应该知道。 如果在元素上显式的设置 display
的值为 flex/inline-flex
或 grid/inline-grid
就会创建Flex容器或Grid容器,同时就创建了FFC(Flexbox Formatting Context)或GFC(Grid Formatting Context) 。那么Flex容器或Grid容器的子元素就自动成为 Flex项目或Grid项目 。同时相应的Flex项目属性或Grid项目属性就可以运用到这些元素之上。
在Flex容器或Grid容器上可以使用伪元素 ::before
或 ::after
。运用于容器的伪元素在很大程度上就像一个子元素,因此也自动会变成Flex项目或Grid项目。
Flex容器或Grid容器中的伪元素 ::before
或 ::after
看上去像一个子元素。不过有一个棘手的问题,除了用于创建它的选择器之外,没有其他选择器可以选中它。
ul::before { content: 'x'; display: inline-flex; justify-content: center; align-items: center; min-height: 10vh; background: #f36; margin: 5px; color: #fff; }
或许你会想到,既然伪元素看上去像一个子元素,那么结构性选择器,比如 :nth-child()
或 :nth-last-child()
可以选中。事实是不可以的,如果伪元素和子元素完全一样,将会影响这些选择器。
ul > :nth-child(1) { background: #f90; border:2px solid #09f; } ul > :nth-last-child(2) { background: #09f; border:2px solid #f90; }
另外一个问题就是,在JavaScript中不能像选择常规子元素那样选择伪元素。比如, document.querySelector('.flex::before')
将返回一个 null
。如果你想在JavaScript选中伪元素以及想看看它的样式规则,可以使用CSSOM中的相关特性来获取到:
const styles = window.getComputedStyle( document.querySelector('.flex'), '::before' ) console.log(styles.content) // ❯ "x" console.log(styles.color) // ❯ rgb(255, 255, 255) console.log(styles.getPropertyValue('color')) // ❯ rgb(255, 255, 255)
基于CSS自定义属性和 em
单位的吶应式布局
响应式布局中会根据不同的终端屏幕设计不同的字号、间距等。在以前的相关教程介绍了精准流体布局的方法:
其实他们的原理非常简单,利用 视窗单位 vw
等和 calc()
函数 来计算 font-size
或者 padding
等属性的值。
@guerriero_se在的新博文 中介绍了另一种实现响应式布局的方法,即 基于 CSS自定义属性 和 em
单位 。
主要分为两部分,一部分是对 font-size
、 line-height
相关的设计(有关于文字排版);另一部分就是有关于间距的设计。
响应式排版
为了控制文本相关的缩放,定义了两个自定义属性: --text-base-size
和 --text-scale-ratio
。第一个是 body
元素的 font-size
;第二个是用于缩放的比例。而且 --text-base-size
的默认值是 1em
。
:root { // body font size --text-base-size: 1em; // type scale --text-scale-ratio: 1.2; --text-xs: calc((1em / var(--text-scale-ratio)) / var(--text-scale-ratio)); --text-sm: calc(var(--text-xs) * var(--text-scale-ratio)); --text-md: calc(var(--text-sm) * var(--text-scale-ratio) * var(--text-scale-ratio)); --text-lg: calc(var(--text-md) * var(--text-scale-ratio)); --text-xl: calc(var(--text-lg) * var(--text-scale-ratio)); --text-xxl: calc(var(--text-xl) * var(--text-scale-ratio)); --text-xxxl: calc(var(--text-xxl) * var(--text-scale-ratio)); // line-height --body-line-height: 1.4; --heading-line-height: 1.2; // capital letters - used in combo with the lhCrop mixin --font-primary-capital-letter: 1; }
注意,在定义每种文本大小类型的自定义属性时,使用 1em
乘以 --text-scale-ratio
。 1em
不是基于 --text-base-size
的值。你可以根据自己的需要设置 --text-base-size
的值不等于 1em
。由于 em
单位是基于当前 font-size
的大小计算的,如果我们在不同的媒体查询中更新 --text-base-size
的值,那么就会更新 body
的 font-size
,并使用级联效应,更新所有文本大小自定义属性。这样一来,整个排版都会受到影响。
@supports(--css: variables) { :root { @include breakpoint(md) { --text-base-size: 1.25em; } } }
响应式间距
响应式间距和响应式排版有点类似:
:root { --space-unit: 1em; --space-xxxxs: calc(0.125 * var(--space-unit)); --space-xxxs: calc(0.25 * var(--space-unit)); --space-xxs: calc(0.375 * var(--space-unit)); --space-xs: calc(0.5 * var(--space-unit)); --space-sm: calc(0.75 * var(--space-unit)); --space-md: calc(1.25 * var(--space-unit)); --space-lg: calc(2 * var(--space-unit)); --space-xl: calc(3.25 * var(--space-unit)); --space-xxl: calc(5.25 * var(--space-unit)); --space-xxxl: calc(8.5 * var(--space-unit)); --space-xxxxl: calc(13.75 * var(--space-unit)); }
设置了一个自定义属性 --space-unit
的值为 1em
,而且模块化缩放比例是基于斐波那契数列(Fibonacci sequence)。同样的,在不同的媒体查询中, --space-unit
可以设置不同的的值:
@supports(--css: variables) { :root { @include breakpoint(md) { --space-unit: 1.25em; } } }
有关于更详细的代码,可以查阅读 CodyHouse Framework 。
图解JavaScript的 map()
、 filter()
和 reduce()
JavaScript中有关于数组的API有很多:
其中有关于 map()
、 filter()
和 reduce()
的几个方法,有很多非常形象的图来阐述,比如 @Una Kravets的手绘图 :
@JavaScript Teacher还为这几个API设计了相应的动态图 :
有关于这方面更多的介绍,可以阅读:
- Map, Filter and Reduce – Animated
- An Illustrated (and Musical) Guide to Map, Reduce, and Filter Array Methods
- JavaScript’s Reduce Method Explained By Going On a Diet
- JavaScript Map() Method Explained by Going On a Hike
- JavaScript’s Filter Function Explained By Applying To College
小结
在这一期中主要围绕三个部分展开,其一介绍了 prefers-reduced-motion
媒体查询条件和HTML5的 <picture>
的 <source>
结合在一起对动态图片做降级处理,或者说在最适合的环境加载最适合的源媒体;其二介绍了如何使用CSS自定义属性和 em
单位实现响应式布局的另一种方法;其三介绍了Flexbox和Grid容器中的伪元素会生成相对应的项目,具备Flex项目、Grid项目的属性,不过他们看上去类似子元素,但结构性选择器无法运用到其身上,如果使用JavaScript来操作伪元素的样式的话,需要借助CSSOM等特性。最后用收集了不同的图来阐述JavaScript的 map
、 filter
和 reduce
等API特性。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK