【css】重排与重绘


margin-top:-20px;代替元素position:relative,top:-20且不占用文档流

渐变边框实现:

  1. background-clip

    核心原理:图层叠加法

    我们要实现的效果其实是三层信息的叠加:

    1. 最底层:深色的、明显的边框渐变色(铺满整个 border-box)。
    2. 中间层:半透明的、淡淡的内部背景色(铺在 padding-box,也就是边框以内)。
    3. 最顶层:文字和标签。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    .gradient-border-card {
    margin: 30rpx;
    border-radius: 40rpx;
    position: relative;

    /* 【关键点】 */
    /* 1. 设置透明边框,预留出 4rpx 的宽度 */
    border: 4rpx solid transparent;

    /* 2. 背景绘制两个层级:
    第一个背景是纯白色,裁切到 padding-box(不包含边框区);
    第二个背景是渐变色,裁切到 border-box(包含边框区)。
    */
    background-image: linear-gradient(#fff, #fff),
    linear-gradient(to right, #F8D7E8, #E2D9F3);
    background-origin: border-box;
    background-clip: padding-box, border-box;
    }
  2. “遮罩反选法” (Mask Composite)

    1. 铺满背景

    首先,你在伪元素 ::before 上设置了一个完整的渐变背景。如果不做任何处理,它就是一个实心的、带渐变的圆角矩形,会把卡片内部的文字全部遮住。

    2. 画两个“遮罩面积”

    关键在于这一行: -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);

    这里其实画了两层遮罩(虽然颜色是白色,但遮罩只看透明度):

    • **第一层 (content-box)**:只覆盖内容区域(不含边框)。
    • **第二层 (默认 border-box)**:覆盖整个卡片(含边框)。

    3. “减法”运算(最核心的一步)

    代码里最神奇的是这行: -webkit-mask-composite: destination-out; (或者标准写法 mask-composite: exclude;)

    它的逻辑是:“用第二层减去第一层”

    • 想象你有一张完整的大饼(第二层:整个卡片)。
    • 你拿一个模具从中间压下去,把中间的部分扣掉(第一层:内容区)。
    • 剩下的,就只有那一圈 4rpx 宽的边缘了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    <style lang="scss" scoped>.gradient-border-card {
    position: relative;
    margin: 30rpx;
    border-radius: 40rpx; // 卡片的圆角
    background: #ffffff; // 卡片内部的背景色
    overflow: hidden;

    /* 使用伪元素 ::before 来制作渐变边框 */
    &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 4rpx; // 【这个值就是边框的粗细吖!】
    border-radius: 40rpx; // 必须和父级的圆角一致

    /* 1. 设置渐变背景色 */
    background: linear-gradient(to right, #F8D7E8, #E2D9F3);

    /* 2. 使用 mask (遮罩) 核心技术 */
    /* 我们画两个纯色遮罩,一个覆盖内容区(content-box),一个覆盖整个边框区(border-box) */
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);

    /* 3. 关键点:把两个遮罩重叠的部分“减去” */
    /* 这样就只剩下 border 那个圈圈显示渐变色了! */
    -webkit-mask-composite: destination-out;
    mask-composite: exclude;

    pointer-events: none; // 确保伪元素不会阻碍卡片内部的点击事件
    }
    }/* 内部装饰样式 */.content {
    padding: 40rpx 30rpx;
    .title {
    font-size: 32rpx;
    font-weight: bold;
    color: #4A4A8A; // 这里的颜色可以根据图片微调
    }
    }.tags {
    display: flex;
    margin-top: 30rpx;
    gap: 20rpx;

    .tag-item {
    padding: 10rpx 30rpx;
    border-radius: 40rpx;
    font-size: 26rpx;
    border: 1px solid #E2D9F3;
    color: #666;

    &.active {
    background: #E2D9F3;
    color: #4A4A8A;
    border: none;
    }
    }
    }
    </style>
  3. 外面套一层盒子,背景为渐变吖吖

发就开了;的

渐变可以多层叠加,是顶层到底层,第一层有透明度就会显示第二层,第二层有透明度就会显示第三层吖吖。

在 CSS 布局中,**gap** 是一个非常实用的属性,它专门用来设置子元素之间的间距

你可以把它想象成元素之间的“防火隔离带”,它只存在于元素与元素之间,而不会在容器的边缘(四周)产生多余的空格。


1. 它解决了什么痛点?

在没有 gap 之前,我们如果想让一排按钮之间有 20px 的间距,通常得这么写:

  • 给每个按钮加 margin-right: 20px;
  • 然后还得用 :last-child 把最后一个按钮的 margin-right 删掉,否则最后一项会把整个容器撑大,导致不对称。

有了 gap 之后: 你只需要在父容器上写一行 gap: 20px;,剩下的浏览器全帮你算好了。


2. gap 的构成

gap 实际上是两个属性的简写:

  1. **row-gap**:行与行之间的间距。
  2. **column-gap**:列与列之间的间距。

语法示例:

  • gap: 20px; —— 水平和垂直间距都是 20px。
  • gap: 10px 30px; —— 行间距 10px,列间距 30px。

3. 它在哪里可以用?

gap 最初只能在 Grid(网格) 布局里用,但现在它在 Flex(弹性) 布局里也得到了完美支持(这也是目前最常用的场景)。

在 Flex 里的用法:

CSS

1
2
3
4
5
.tags {
display: flex;
flex-wrap: wrap; /* 换行 */
gap: 20rpx; /* 无论横向还是纵向,只要元素碰面了,中间就有 20rpx */
}

4. 为什么大家现在都爱用 gap

  • 干净:不会在容器的最左边或最右边多出空位。
  • 省事:不需要用 :first-child:last-child 去修补 margin。
  • 直观:在父元素上统一管理间距,不用去每个子元素里找 margin 设置。

5. 小提醒

虽然现在 gap 在微信小程序和现代浏览器中支持得非常好,但如果你需要兼容非常老旧的安卓手机系统(比如 2020 年以前的),Flex 里的 gap 可能会失效。不过在目前绝大多数开发场景下,它已经是“标配”了。

你之前代码里的那一段:

CSS

1
2
3
4
5
.tags {
display: flex;
margin-top: 30rpx;
gap: 20rpx; /* 就是这里! */
}

它的作用就是让“饭搭子”、“运动搭子”这些标签之间保持 20rpx 的距离。


简单来说:**margin: 0 auto 是“自动推开”,而 translateX 是“手动位移”。**


1. 什么时候用 margin: 0 auto;

适用场景: 固定宽度的块级元素(如 div)。

  • 条件: 1. 必须有明确的宽度(比如 width: 300pxwidth: 50%)。 2. 元素必须是块级(display: block)。
  • 原理: 浏览器会自动计算左右剩余的空间,并将它们平分给左右外边距。
  • 优点: 性能最好,代码最简洁。
  • 注意: 它不需要配合 transform

2. 什么时候用 transform: translateX(-50%);

适用场景: 绝对定位position: absolute)的元素。 这种情况就是你记忆中出现“50%偏移”的地方。

原理拆解:

  1. left: 50%;:这会把元素的左边缘推到父容器的正中间。此时元素整体偏右了。
  2. transform: translateX(-50%);:这会让元素向左移动它自身宽度的一半

为什么不直接用 margin? 因为绝对定位的元素脱离了文档流,margin: auto 拿不到剩余空间,失效了。