阮一峰 CSS Grid 网格布局教程
https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html
为什么使用 grid 布局?
因为看到需要实现 n 行 n 列的效果,自然就会想到使用 grid 布局。
grid 布局默认的放置方式是先行后列,如果要想先列后行,可以使用 grid-auto-flow: column
这个属性来实现。
阮一峰 CSS Grid 网格布局教程
https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html
因为看到需要实现 n 行 n 列的效果,自然就会想到使用 grid 布局。
grid 布局默认的放置方式是先行后列,如果要想先列后行,可以使用 grid-auto-flow: column
这个属性来实现。
本质上就是通过判断某个时机来去修改样式,实现方案就分解成:时机、修改样式这两个问题了。
常见的方法有:
媒体查询
/* 系统设置浅色模式 */
@media (prefers-color-scheme: light) {}
/* 系统设置深色模式 */
@media (prefers-color-scheme: dark) {}
通过媒体查询可以获取到系统当前的设定,从而直接修改对应的样式。
在支持 css 变量的浏览器环境中,更常见的做法是通过媒体查询动态地修改 root 下面的 css 变量,然后具体的组件样式使用 css 变量来作为样式值,这样可以将样式都收拢到一个地方,方便维护。
这个方法的缺点是,浅色模式和深色模式会跟着系统设置来,并没有办法由用户手动地去切换。
data set + css 属性选择器
我们可以通过元素标签上的 data set 存放一些属性,自然也可以在根元素上去定义一个 data-theme 属性,属性值可以是 light 和 dark。
在用户第一次进入页面的时候,可以通过 window.matchMedia('(prefers-color-scheme: dark)').matches
来获取系统当前的设置,为 data-theme 属性配置一个默认值,然后通过 css 属性选择器来定义 css 变量,和上面的方法一样实现深色模式。
这个方法的好处是 data-theme 这个属性是可以由 js 修改的,我们可以做一个按钮或者选择器来给用户手动切换与自动跟随系统,这个也是现在许多系统都有提供的功能。同时由于有了 js 的加入,我们也可以将这个值记录在 localStorage 这种持久化存储里面,记录用户上次的使用习惯,在用户再次进入页面的时候就取出来,而不是通过媒体查询去查询了。
在我们开发过程中,有些时候会遇到容器内添加元素的需求,一般往下添加是没问题的,但是当我们有在运行过程中动态往上方添加元素时,就会发现不同浏览器有不同的行为。很常见的一种场景就是消息列表向上滚动加载的场景。
这一段代码可以模拟这种case:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="container" style="display: flex; gap: 10px; flex-direction: column;">
<div style="background: red; height: 100px; width: 100px;"></div>
<div>bottom</div>
</div>
<script>
const container = document.getElementById('container')
setInterval(() => {
const div = document.createElement('div')
div.style.background = 'red'
div.style.height = '100px'
div.style.width = '100px'
container.insertBefore(div, container.firstChild)
}, 300)
</script>
</body>
</html>
在开发通知的编辑页面时,使用到了 mavon-editor 这个库。这个富文本编辑器库有提供一些方便的功能,比如添加链接时友好的弹窗,可以方便不了解 markdown 语法的人进行编辑。
但在使用过程中发现,这个弹窗的遮罩层无法遮住面包屑与头部菜单。在「元素」页面下,我们看到了这其实是 z-index 与层叠上下文导致的。
在页面中,我们经常会有用到 z-index
这个属性,而配合这个属性使用的一般还有 position
属性,z-index
一般会运用在脱离文档流的元素中,比如绝对定位、固定定位等元素。
有同学反映「权限申请」按钮的动画效果会导致 GPU 占用高的问题,在我的 m1 macbook pro 13 上表现为占用 20~25%,但是那位同学说在他电脑上占用率高达 130%,因此想搞明白为什么 animation 会导致 GPU 占用如此高。
@keyframes flowlight {
// 0% {
// background-position: 0 0;
// }
100% {
background-position: -400% 0;
}
}
// 按钮的类名
.permission-url {
background-image: linear-gradient(
-89deg,
#fcab9b,
#f1d3af,
#afc9f1,
#bb9cfc,
#fcab9b
);
background-size: 400%;
animation: flowlight 3.5s linear infinite;
}
举个例子,我们在 .container
类下面有一个 iView
的 poptip
组件,按往常我们的写法,都套一层 :deep
比较稳妥。
但这里由于 .ivu-poptip
和 .ivu-poptip-rel
是同一个组件,组件内层并没有使用 scoped
作用域的 css,因此我们只需要加一层 :deep
到组件的第一级,后续的子类选择器就会选择到对应父类下的子类。