news 2026/10/27 15:01:00

CSS背景图片与渐变叠加:图层顺序、蒙层调色与排错

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CSS背景图片与渐变叠加:图层顺序、蒙层调色与排错

上周改版头图,设计给的原图很漂亮,铺到页面上却傻眼了:图片底部和下面的白底之间是一条硬邦邦的切割线,标题文字压在图片的亮部上完全读不出来。设计师的反馈只有一句——“加个渐变过渡一下”。听起来简单,真上手写 CSS 才发现,把一个渐变和一张背景图片同时塞进background-image里,写出来的结果十次有八次不按预期走:渐变跑到图片下面去了、蒙层只盖住了一半、图片被拉变形、明暗交界处还泛着一层脏灰。

这篇就把这件事从头到尾捋一遍。核心讲的是 CSS 里背景图片与渐变共存、叠加、互相调色的完整做法,包括多层背景的图层模型、渐变的语法细节、尺寸与裁剪属性的对应关系,以及效果没出来时怎么一步步查。不管你是刚学会background: url(...)就上手的初学者,还是写了好几年但一直靠试错调蒙层的熟手,应该都能从里面捡到点东西。

1. 多层背景的图层模型:渐变和图片为什么能写在一起

很多人第一次看到background-image: linear-gradient(...), url(...)这种写法是懵的——一个属性怎么能塞两个值?这不是什么语法糖,而是 CSS 背景从设计之初就支持多图层堆叠。搞不清这个模型,后面所有关于覆盖、调色、渐隐的问题都会变成玄学调参。

1.1 background-image 从设计上就是复数

background-image的取值本身就是一个逗号分隔的列表,每一项都是一张“图像”。这里的图像是个宽泛概念,url()引用的位图是图像,linear-gradient()、radial-gradient()、conic-gradient()生成的也是图像,image-set()挑出来的还是图像。它们在 CSS 眼里地位完全平等,都只是待绘制的图层。

换句话说,渐变在 CSS 里从来不是“背景色的一种高级形式”,它是实打实的一张图,只不过这张图是由浏览器实时计算出来的,没有文件、没有固有尺寸、也没有固定比例。理解了这一点,很多行为就顺了:为什么渐变能被background-size缩放、为什么它能被background-blend-mode混合、为什么它能和url()互换位置——因为它们本来就是同一类东西。

实际写的时候我习惯按“从上到下”的顺序读这段代码:

.hero { background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0)), url("hero.jpg"); background-repeat: no-repeat, no-repeat; background-position: center, center; background-size: cover, cover; }

第一项是渐变,第二项是图片,视觉上渐变压在图上面,形成一层从上往下逐渐变透明的暗色蒙层。这个顺序不能反,反了就等于把图盖在渐变上,蒙层直接看不见。

1.2 谁压着谁:写在最前面的图层在最上面

图层顺序是background-image列表的顺序,先写的在最上层,后写的在下面,background-color永远在最底层。这跟z-index一点关系都没有,纯靠书写顺序决定,也没法用别的属性调换。这一点跟直觉有点拧:很多绘图软件里“后加的图层在上面”,而 CSS 恰恰相反。

我刚接触多背景时被这个顺序坑过一次,当时为了省事把图片写在前面、渐变写在后面,调了半天以为是渐变颜色太淡,最后才发现是层级写反了。所以现在的习惯是:脑子里先想清楚“谁是蒙层、谁是底图”,蒙层永远写在第一个。

另外要记住,background-color是不参与这个列表的,它单独一个值,且永远垫在最底下。如果所有渐变图层都带透明度,最终透出来的就是它。这其实是个很好用的兜底:图片加载失败或者还没加载完时,底色能先顶住,不至于露出一片白。

1.3 子属性列表的“循环补齐”规则

多背景真正麻烦的地方不在background-image,而在它的那堆兄弟属性。background-position、background-size、background-repeat、background-origin、background-clip、background-attachment每一个都是独立的逗号分隔列表,各自按顺序和图层对应。

问题在于它们的长度可以不一样。规则是:如果某个属性的值个数少于图层数,这个列表会被重复循环使用来补齐。比如两个图层,background-size: cover只写了一个值,那两层都用cover;写成background-size: 100% 100%, cover才是各自独立。

写法图层 1(渐变)图层 2(图片)实际结果
background-size: covercovercover两层都铺满
background-size: 100% 40%, cover100% 40%cover渐变只占上半部分
background-size: 100% 40%100% 40%100% 40%图片被压扁,常见事故
background-repeat: no-repeatno-repeatno-repeat两层都不重复

第三行那个写法是最典型的翻车现场:本来只想控制渐变的高度,结果图片跟着被拉成了奇怪的形状。列表属性要么全写,要么确认默认值能接受。我现在的做法是,只要图层数超过一个,这六个属性就老老实实写全,多敲几个字符换来的是不用猜。

2. 渐变盖在图片上的三种做法与取舍

知道了图层模型,接下来是选型:同样是“图片上加渐变”,业内其实有三条路线,分别适合不同的视觉目标。选错了不是做不出来,而是做出来别扭、改起来费劲。

2.1 均质蒙层:一行代码解决文字可读性

最刚需的场景是图片上压白字,图片本身明暗不定,文字经常糊掉。最直接的办法是盖一层均匀的半透明黑,让整张图整体压暗,文字就有稳定的底衬了。

.banner { background-image: linear-gradient(rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.55)), url("banner.jpg"); background-size: cover; background-position: center; color: #fff; }

这里的linear-gradient两个色标颜色完全一样,等于一个纯色矩形。看着有点绕,为什么不直接用background-color?因为background-color永远在最底层,压不到图片上面去。用同色双色标的渐变,是让“纯色块”变成一张可以叠在上层的图,这是绕开层级限制的常用手法。

蒙层的透明度是核心参数,不能拍脑袋。粗算一下:纯白图(亮度 255)叠上rgba(0,0,0,a)之后,合成亮度约为255 × (1 - a),按 sRGB 的 gamma 2.2 近似换算成相对亮度,再套 WCAG 的对比度公式,白色文字的对比度大致如下。

蒙层 alpha合成后灰度白字对比度(估算)评价
0.40约 153约 2.8:1不够,正文级别不达标
0.50约 128约 3.9:1勉强,大字号标题可用
0.60约 102约 5.7:1正文基本安全
0.70约 77约 8.8:1偏重,画面会闷

这组数字是估算,实际以工具测出来的为准,但量级能帮你建立直觉:0.5是个心理上觉得“够暗了”、实际却不达标的危险值。更麻烦的是,真实图片很少有纯白,暗部叠 0.5 就黑成一片,亮部又不够。所以均质蒙层只适合图片整体亮度比较均匀的情况,明暗差异大的图,得上下面这种。

2.2 单侧渐隐:让图片边缘融进页面底色

回到开头那个需求——图片底部要和白色页面无缝衔接。做法是让渐变从透明过渡到一个和页面底色一致的颜色,只作用在图片底部一小段。

.hero { position: relative; background-image: linear-gradient(180deg, rgba(255, 255, 255, 0) 55%, #ffffff 100%), url("hero.jpg"); background-size: cover; background-position: center; background-repeat: no-repeat; }

几个细节值得掰开说。第一,起始色写的是rgba(255, 255, 255, 0)而不是transparent,原因在第 5 章会专门讲,这里先记住结论。第二,55%这个位置决定了渐隐的起点,数值越小过渡带越宽、越柔和,但吃掉的画面也越多;45%~65%是实际项目里比较舒服的区间,具体看图的主体内容在哪个位置。第三,终止色必须和下方区域的实际背景色一致,如果下方是浅灰底而不是纯白,这里写#fff就会露出一条亮边。

这种单侧渐隐还可以横过来用,做左右两侧的羽化,或者反过来做“顶部渐隐”让图片从导航栏里淡出。原理都一样,只是角度换一下。

2.3 混合模式:让图片整体染上品牌色

前面两种都是“叠加”,混合模式是另一条路:不盖一层东西,而是让图片和下面的颜色发生化学反应。

.cover { background-image: url("cover.jpg"); background-color: #1f4b8f; background-blend-mode: multiply; }

multiply是正片叠底,图片和底色相乘,结果只会更暗,非常适合把五花八门的配图统一到品牌色系里。这个用法在内容列表页特别管用,几十张风格各异的封面图,套上同一个底色和混合模式,视觉上立刻就整齐了。

常用的几个模式的实际效果差异挺大:

混合模式效果描述适合场景
multiply相乘变暗,白色变透明统一深色品牌调性
screen反相乘变亮,黑色变透明深色页面上的图片提亮
overlay对比增强,暗更暗亮更亮需要画面更有冲击力
soft-light柔和着色,保留原图细节轻微的色调倾向
luminosity取底色的色相饱和度、图的明度强行染色但保留明暗结构

background-blend-mode也是个列表,第一个值对应最上层图层,它的作用对象是“这一层和它下方所有内容”。单层图片加background-color时,就是图和底色混合,这是最省事的一种用法;多层时要注意列表顺序,写错位置会得到完全不同的结果。

需要提醒的是,混合模式会改变最终呈现的颜色,如果图片上有商品、有人物,染色之后颜色失真可能引发投诉。所以用在装饰性强的封面图上比较稳妥,用在内容主体图上要谨慎。

3. 把渐变当成一张图来调:语法里那些真正会出错的地方

渐变函数本身的参数不算多,但每一处都有容易写反或者写漏的地方。这一章挑三个实际出问题频率最高的点。

3.1 角度、方向关键字与“魔法角”

linear-gradient的第一个参数可以是角度,也可以是to <方向>。角度的参照系是:0deg指向正上方,顺时针递增,所以90deg向右、180deg向下、270deg向左。而to bottom等于180deg,to right等于90deg,to top等于0deg。

最容易搞混的是对角方向。to bottom right的含义不是“从左上角到右下角画一条线”,而是“渐变线指向右下角方向,并且保证等值线正好穿过两个相邻角”。对于正方形盒子,它恰好约等于135deg;但对于长方形盒子,这个角度是动态计算的,会随宽高比变化。所以想要精确控制,就别用对角关键字,直接写角度。

还有个细节:这四个角方向关键字被称为“魔法角”,它的存在是为了让渐变线和盒子的对角线垂直交叉,从而让两个对角处的色标正好落在角上。做斜向条纹、对角线切割效果时用关键字比算角度省心,做需要精确复现的设计还原时用角度更稳。

.diagonal-stripes { background-image: repeating-linear-gradient( 45deg, #f4f6f8 0px, #f4f6f8 12px, #e6ebf1 12px, #e6ebf1 24px ); }

这类条纹图案在设计稿里很常见,repeating-linear-gradient的色标必须带明确的长度单位或百分比,只给颜色的话它无法确定重复周期,整个渐变会退化成一个实色块,看起来就像“没生效”。

3.2 色标的硬边、中间点与位置回退

色标的标准写法是颜色 位置,位置可以省略,省略时会由浏览器自动均分。但有两个行为很多人不知道:

硬边——同一个位置上写两个不同颜色的色标,中间不会产生任何过渡,形成一条锐利的分界。这招用来做一半白一半灰的分割背景非常干净,比用两个绝对定位的div省事得多:

.split { background-image: linear-gradient(90deg, #ffffff 0 50%, #f0f3f7 50% 100%); }

位置回退——如果某个色标的位置比它前一个还小,浏览器会把它钳制到前一个的值上,不会报错也不会倒着过渡。这就是为什么写错顺序时页面看着“怪但没崩”,排查起来很费劲。

另外,中间色标可以只写位置不写颜色,用来指定过渡的中点:

.eased { background-image: linear-gradient(180deg, #1f4b8f, 30%, #4a90d9); }

上面这段里#1f4b8f在 0%、#4a90d9在 100%,而“过渡中点”落在 30% 的位置,意思是 0~30% 这段就完成了前半程的颜色变化,之后放缓。这个技巧能让渐变的视觉重心偏移,做背景氛围时比均分过渡更有层次。我一般用在卡片背景上,让深色区域多占一点,文字区更稳。

3.3 径向与锥形渐变的形状参数

radial-gradient的参数顺序容易记混,标准形式是“形状 尺寸 at 位置, 色标列表”:

.glow { background-image: radial-gradient( circle at 30% 20%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 70% ); }

形状可以是circle或ellipse,尺寸可以用closest-side、farthest-side、closest-corner、farthest-corner这些关键字,也可以直接给两个长度值。默认值随形状而定,circle默认是farthest-corner,ellipse也是,所以不写尺寸时渐变通常会铺得比预想的更大,光晕效果显得发虚——把尺寸写死成60% 60%之类会好控很多。

conic-gradient是后来加入的,围绕一个中心点按角度扫过:

.pie { background-image: conic-gradient(from 0deg at 50% 50%, #1f4b8f 0 25%, #4a90d9 25% 100%); }

它的角度方向是顺时针,from指定起始角,at指定圆心。做进度环、饼图、色轮都靠它,但要注意它的色标位置是角度百分比,和线性渐变的语义不一样。

新版本浏览器还支持在渐变里声明插值色彩空间,把in oklab之类的声明写在方向和第一个色标之间,能避免中间过渡发灰的问题。这个特性兼容性还不算全面,用在生产环境时最好配合@supports兜底,或者干脆在构建阶段用工具生成降级方案。

4. 尺寸、位置、裁剪:多图层下最容易错位的三个属性

图层模型懂了、渐变语法也熟了,剩下的差错基本都出在这三个属性上。它们各自独立成列表,和多图层的对应关系是排错时最先要看的地方。

4.1 background-size 对渐变图意味着什么

前面提过,渐变没有固有尺寸和固定比例。这类“无内在尺寸”的图像在cover和contain下的行为很特殊——两者都会退化成把图像拉伸到定位区域的大小,因为没办法按比例缩放一张没有比例的图。所以给两层都写cover,对渐变来说等于100% 100%,这没问题;但如果只给一个值,列表循环补齐会让图片也套用同样的规则,就可能出问题。

真正好用的地方在于:给渐变单独设尺寸,可以让它只覆盖局部。比如只想让图片下半部分有一层渐变遮罩:

.card__media { background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0)), url("photo.jpg"); background-size: 100% 45%, cover; background-position: 0 100%, center; background-repeat: no-repeat, no-repeat; background-origin: border-box, border-box; }

这里渐变层尺寸是100% 45%,位置0 100%贴底,图片层cover居中,两者各管各的。background-repeat必须两层都写no-repeat,因为渐变层尺寸小于容器时,默认的repeat会让它在空白处平铺一次,页面底下就多出一截莫名其妙的色块。

反过来,repeat配小尺寸还能做出图案效果——把渐变尺寸缩到 20px 见方再允许重复,就是一张平铺的纹理图。这个用法在背景装饰里挺常见,但要注意在低分辨率屏幕上可能出现拼接缝。

4.2 background-clip 与 background-origin 的分工

这两个属性名字像、作用也容易混,一句话区分:background-origin决定背景图的定位基准矩形从哪开始,background-clip决定背景的绘制裁剪区在哪结束。

前者影响background-position的参照系,默认padding-box,也就是从内边距外沿算起;后者默认border-box,绘制到边框外沿。两者都支持content-box、padding-box、border-box,也能接受text(仅clip)。

实用场景很明确:卡片有内边距、背景图想铺满到边框内沿,用默认值就行;想让背景严格避开内边距区域,把background-clip设成content-box;想做渐变文字,就是background-clip: text配上透明文字色。

.gradient-text { background-image: linear-gradient(90deg, #1f4b8f, #4a90d9); -webkit-background-clip: text; background-clip: text; color: transparent; }

多层背景时这两个属性也是列表,得逐层写。如果只给一个值,会循环应用到所有层——对background-clip来说这通常没坏处,但对background-origin可能会让某一层的定位基准跑偏,尤其是配合background-size做局部定位的时候。

4.3 简写属性会把没写的东西一起重置

background简写能省字符,但它的行为是“重置所有子属性到初始值,然后再应用你写的值”。这意味着只要用了简写,background-size、background-repeat、background-blend-mode这些没显式写的东西全被清空。

/* 下面这两行,第二行会把第一行设的 blend-mode 清掉 */ .cover { background-blend-mode: multiply; } .cover { background: url("cover.jpg") center / cover no-repeat; }

这是实战中最隐蔽的一类 bug——样式表里明明写了混合模式,页面上就是不生效,因为后面某个更具体的规则用了简写属性把它重置了。DevTools 里表现得很直观:被划掉的属性,或者 Computed 面板里显示的是初始值。

我的做法是:涉及多图层、混合模式的元素,一律用展开属性,background-image、background-size、background-position、background-repeat、background-color分开写。字符多一点,但改的时候不用重新推演简写的重置逻辑。如果非要用简写,那么颜色只能写在最后一层里,比如background: url(a.jpg) center / cover, linear-gradient(...) #fff;,这个语法位置很多人不知道,写错位置整个声明会失效。

5. 效果没出来的完整排查链路

写 CSS 最耗时的不是写,是“为什么没反应”。这一章把我在实际项目里踩出来的排查顺序整理出来,基本能覆盖九成以上的情况。

5.1 从 Computed 面板倒查图层栈

第一步永远是打开开发者工具,看 Computed 面板里的background-image。这个面板显示的是最终计算值,能同时看到两件事:一是这条声明有没有被别的规则覆盖,二是图层顺序到底是不是你想的那样。

展开background-image那一行,浏览器会把每一层单独列出来,渐变显示为linear-gradient(...)加一段颜色预览,图片显示为可点开的缩略图。哪一层缺失、哪一层顺序错了,一眼就看出来。这个信息比 Styles 面板里一堆被划掉的声明直观得多。

如果 Computed 里的background-image已经是none,说明整条声明都没生效,往前找覆盖它的规则;如果值对但页面没变化,问题多半在尺寸、定位或者层叠上下文上。这时候第二步是给元素临时加个background-color: red,确认它的实际盒模型大小——元素高度塌成 0 是“背景看不见”的经典原因,尤其是用了绝对定位或者内部全是浮动元素没清浮动的时候。

还有一个高频陷阱:渐变的定位顺序或尺寸写在列表里但数量对不上,导致列表循环补齐后,渐变的background-size恰好变成了auto,而容器又没有明确高度。这种情况在 DevTools 里能看到渐变层存在,但页面上一片空白。

5.2 transparent 这个关键字带来的脏色

这个坑值得单独占一节,因为几乎所有人都踩过。

transparent在 CSS 里其实就是rgba(0, 0, 0, 0),一个完全透明但颜色分量是黑色的值。当它在支持插值的渐变里充当色标时,浏览器是拿它的颜色分量参与计算的,于是从红色到transparent的过渡,中间会出现一段发暗发脏的灰褐色,而不是干净地淡出。

/* 有脏色:中间会泛灰 */ .bad { background-image: linear-gradient(180deg, #e74c3c, transparent); } /* 干净:中间是同一色相的纯透明 */ .good { background-image: linear-gradient(180deg, #e74c3c, rgba(231, 76, 60, 0)); }

修法就是写rgba()或现代语法里的同色透明值,让颜色分量保持一致。现在部分浏览器对transparent做了特殊处理,在 sRGB 空间下能识别出这是“透明的同色”,但它依赖实现细节,跨浏览器不稳定。这个习惯我从很多年前一直保留到现在,从没出过问题。

同理,做图片渐隐时不要图省事写transparent,一定要写rgba(255, 255, 255, 0)或对应底色的透明值,否则图片边缘会浮起一层灰雾。

5.3 色带、移动端涂抹感与渐变性能

渐变在纯色大面积上很容易出现一圈一圈的色带,尤其在暗色调、低端屏幕、以及系统开了色彩压缩的情况下更明显。这是 8 位色深的必然结果,不是代码写错了。

几个缓解方向:一是给渐变加一点噪点,用极细的重复纹理或者内联 SVG 叠加,配合background-blend-mode: overlay和很低的透明度,把色阶打散;二是把大面积的纯线性渐变改成带一点径向变化的组合,视觉上的突变感会弱一些;三是控制渐变跨度,不要让一个渐变覆盖整屏那么大的范围。

性能上要注意两点。第一,background-attachment: fixed会让背景在滚动时重新绘制,在移动端和大面积图片上是明确的性能风险,非必要不用。第二,渐变的颜色变化无法用transition直接过渡——background-image不是可插值的属性,写transition: background-image 0.3s不会报错但也不会生效。想要渐变“动起来”,得换思路,这个放到第 6 章讲。

移动端还有个体感差异:同一个渐变在桌面端看着柔和,在手机上因为像素密度和屏幕调校不同,过渡带看起来会窄一截,色带的可见度也更高。做验收的时候一定要在真机上过一遍,别只看桌面模拟器。

6. 可直接抄的六个配方与它们背后的计算

前面是原理,这里是能直接贴进项目的写法。每个配方我都标了关键参数为什么这么取,改的时候知道该动哪里。

6.1 头图底部渐隐融进白底

.hero { height: 420px; background-image: linear-gradient(180deg, rgba(255, 255, 255, 0) 50%, #ffffff 100%), url("hero.jpg"); background-size: cover, cover; background-position: center, center; background-repeat: no-repeat, no-repeat; background-color: #ffffff; }

关键点三个:起始色用同色透明值避免泛灰;渐隐起点50%保证上半部分画面完整,过渡带占下半屏;background-color兜底成白色,图片没加载出来时页面也不会塌。如果头图高度会随视口变化,尽量用vh或者min-height配合,别写死像素,否则渐隐的视觉比例会跟着变形。

6.2 调暗垫底保证文字对比度

.banner { background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.72)), url("banner.jpg"); background-size: cover; background-position: center; color: #ffffff; }

这里不是均质蒙层,而是从 0.2 渐变到 0.72。理由很实际:文字通常放在下半部分,上半部分要保留画面,所以暗度往下递增。如果文字在中间,就把两个色标的位置调整一下,让加深的区间对准文字所在的水平带。这种做法比全图压到 0.6 更耐看,也比 0.5 均质更安全。

6.3 统一色调的封面卡

.card-cover { background-image: url("cover.jpg"); background-size: cover; background-position: center; background-color: #12305c; background-blend-mode: multiply; }

单层图片配单层底色,multiply让白色区域变成底色、暗部保持暗,整体落到深蓝调上。如果原图整体偏暗,multiply之后会糊成一团,这时候换成soft-light或者把底色提亮,效果会好很多。这个配方在列表页里批量使用时尤其香——不需要逐张处理图片资源。

6.4 渐变色文字

.title-gradient { background-image: linear-gradient(90deg, #1f4b8f, #4a90d9, #4a90d9); -webkit-background-clip: text; background-clip: text; color: transparent; padding-bottom: 0.1em; }

两个经验点。第一,末尾多停一个色标(上面第三个#4a90d9),能防止文字最右侧的颜色被截断得不自然。第二,加上padding-bottom是因为background-clip: text在部分浏览器下会把下伸部(比如g、y的尾巴)裁掉一点点,留一点空间能规避。另外这个技巧对line-height比较敏感,行高太小时相邻行会互相干扰。

6.5 渐变动画的两种可靠做法

第一种是不依赖新特性的老办法:把渐变图做得比容器宽一倍,通过移动background-position制造流光效果。

.shimmer { background-image: linear-gradient( 100deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 70% ); background-size: 200% 100%; background-repeat: no-repeat; animation: sweep 1.8s linear infinite; } @keyframes sweep { from { background-position: 150% 0; } to { background-position: -50% 0; } }

第二种依赖@property注册一个角度变量,让渐变的角度本身可以插值,从而转起来。

@property --ring-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; } .ring { background-image: conic-gradient( from var(--ring-angle), #1f4b8f, #4a90d9, #1f4b8f ); animation: spin 4s linear infinite; } @keyframes spin { to { --ring-angle: 360deg; } }

第二种写法代码更短、渲染成本更低,但对浏览器版本有要求,用在需要覆盖老设备的页面上要加降级。第一种是纯background-position动画,兼容性没得挑,缺点是渐变图的尺寸要算准,200%配150% → -50%这个组合是我试出来的“首尾无缝”参数,改宽度就得重新调位置区间。

6.6 图片边缘羽化与遮罩

有时候要的不是叠一层颜色,而是让图片边缘自然消失。这时候用mask-image比叠渐变更合适,因为它作用在整张图(包括后续可能加的内容)上,而且不会留下半透明色块。

.fade-bottom { -webkit-mask-image: linear-gradient(180deg, #000 65%, transparent 100%); mask-image: linear-gradient(180deg, #000 65%, transparent 100%); }

注意遮罩的语义和蒙层相反:黑色代表完全显示,透明代表完全隐藏。这里的transparent反而可以放心用,因为遮罩只看 alpha 通道,不参与颜色插值,不存在脏色问题。65%是羽化起点,想羽化得更长就调小,更短就调大。

四个方向都做羽化也可以,用四层遮罩叠加,但要小心相交区域的叠加会让角落变得过于透明。真要做,我更建议直接写一个径向遮罩,控制起来更直观。


最后分享一条我自己反复验证过的小习惯:凡是图片叠渐变的结构,我都会在图片元素上先加一层 1px 的红色半透明渐变,确认图层顺序、尺寸、覆盖范围都对了,再换成真正的颜色。看起来笨,但比对着页面猜“到底是没生效还是颜色太淡”要快得多。渐变这种东西,颜色稍有偏差在视觉上就接近于不存在,靠肉眼判断是真的不靠谱。

另外,遇到设计稿给的渐变,别急着抄色值。同一条渐变在浏览器里渲出来的效果和设计软件里往往有肉眼可见的差异,尤其是多色标和大跨度的情况。把设计稿截图放进页面做半透明对比,调上两三次色标位置,比来回沟通十句都管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 15:00:03

SQL连接条件:ON与WHERE子句的核心区别与最佳实践

1. SQL连接条件的核心争议 这个问题困扰着无数SQL初学者甚至部分有经验的开发者。当我们在编写包含JOIN操作的SQL语句时&#xff0c;连接条件到底应该放在ON子句还是WHERE子句&#xff1f;这两种写法在大多数情况下确实会产生相同的结果&#xff0c;但它们的语义和执行逻辑存在…

作者头像 李华
网站建设 2026/10/27 14:59:50

Java泛型原理与类型安全实践指南

1. 为什么Java泛型是类型安全的基石2004年Java 5引入泛型时&#xff0c;我正在参与一个金融交易系统的开发。当时代码里充斥着这样的强制类型转换&#xff1a;List accountList new ArrayList(); Account acc (Account)accountList.get(0); // 运行时可能抛出ClassCastExcep…

作者头像 李华
网站建设 2026/10/27 14:59:19

impeccable 工具实战:AI 编码代理与前端设计审查自动化

1. 从“impeccable”说起&#xff1a;一个被低估的前端设计关键词第一次看到“impeccable”这个词&#xff0c;是在一个前端项目的代码注释里。当时团队里有人在 review 一个组件的样式实现&#xff0c;留了一句“this spacing is not impeccable”。后来我查了一下&#xff0c…

作者头像 李华
网站建设 2026/10/27 14:59:07

e2e测试工程化实战:从profile配置到CI集成与稳定性优化

1. 从"e2e"这个标题说起&#xff1a;它到底指什么第一次看到"e2e"这个标题&#xff0c;很多人会愣一下。三个字符&#xff0c;没有上下文&#xff0c;没有修饰词&#xff0c;放在任何技术社区里都像是一个暗号。但如果你在软件工程、测试开发或者质量保障这…

作者头像 李华
网站建设 2026/10/27 14:58:00

Text-to-CAD:工业级参数化建模的语义桥梁

1. “Text-to-CAD”不是又一个AI画图玩具&#xff0c;而是工程设计链路的断点缝合者“Text-to-CAD”这个词最近在工程师群、高校实验室和工业软件论坛里频繁冒头&#xff0c;但很多人第一反应是&#xff1a;“这不就是让AI写个提示词&#xff0c;自动生成三维模型&#xff1f;跟…

作者头像 李华
网站建设 2026/10/27 14:58:00

Matlab车牌识别系统设计:从HSV定位到模板匹配的完整实现

简介&#xff1a;基于Matlab车牌识别系统并配有GUI界面的毕业设计项目&#xff0c;面向计算机视觉方向的本专科学生与课程设计使用者。项目已通过导师指导并实际运行&#xff0c;覆盖车牌图像预处理、定位、字符分割与识别等核心环节&#xff0c;可直接作为毕业设计主代码或期末…

作者头像 李华