现代 CSS 选择器的简单应用
因为业务需求,使得需要手写一个日期范围选择组件,组件要求可以展示用户所选择范围。
原本是定义了几个枚举,使用 JS 进行判断,然后根据枚举来逐个给样式。
const RangeStatus = {
NOT_IN: 0,
IS_START: 1 << 0,
IN_RANGE: 1 << 1,
IS_END: 1 << 2,
IS_SELF: 1 << 3
} as const
const InRange =
RangeStatus.IN_RANGE |
RangeStatus.IS_START |
RangeStatus.IS_END |
RangeStatus.IS_SELF
但是其实可以不用这么麻烦,改成一个布尔值 inRange 就行,然后只需要 JS 判断日期是否在选择范围内即可。
剩下的,可以交给 CSS 来完成。
已知需求如下:
- 范围内的日期格子需要高亮背景色。
- 选择范围的首尾格子需要带有半圆边。
- 如果范围首尾是同一天(即只选择了一天),则显示为完整的圆形。
我们为所有日期格子赋予 .item 类名,激活状态使用 .active 类名。
第一条需求的 CSS 样式如下:
.item {
&.active {
background: skyblue;
}
}
第二条和第三条需求的 CSS 样式如下:
.item {
&.active {
background: skyblue;
}
/**
最后一个 active 项
自身是 .active, 且没有后面的 .active 项
*/
&.active:not(:has(~ .active)) {
&,
&:before {
border-top-right-radius: 2rem;
border-bottom-right-radius: 2rem;
}
}
/**
第一个 active 项
自身不是 .active, 且后一个元素是 .active 项
*/
&:not(.active) + .active {
&,
&:before {
border-top-left-radius: 2rem;
border-bottom-left-radius: 2rem;
}
}
&.active:not(:has(~ .active)),
&:not(.active) + .active {
color: white;
&:after {
content: '';
position: absolute;
width: 1.5rem;
height: 1.5rem;
background: blue;
border-radius: 2rem;
z-index: 0;
}
}
}
通过这种方式,我们就仅用一个布尔状态 inRange 控制逻辑,JS 只负责计算选中范围,而复杂的首尾识别,半圆端点,单日圆点等效果都交由 CSS 自动判断完成。
现代 CSS 选择器的简单应用
https://www.inksha.com/archives/xian-dai-css-xuan-ze-qi-de-jian-dan-ying-yong