SVG 阴影
阴影效果可以为 SVG 元素增加立体感和层次感。SVG 提供多种方式来创建阴影效果。
使用 feDropShadow(推荐)
feDropShadow 是创建阴影最简单的方式:
html
<svg width="250" height="100">
<defs>
<filter id="shadow">
<feDropShadow dx="4" dy="4" stdDeviation="3" flood-color="#00000040"/>
</filter>
</defs>
<rect filter="url(#shadow)" x="30" y="20" width="80" height="50" rx="8" fill="#3b82f6"/>
<circle filter="url(#shadow)" cx="190" cy="45" r="30" fill="#22c55e"/>
</svg>feDropShadow 属性
| 属性 | 描述 |
|---|---|
dx | 水平偏移 |
dy | 垂直偏移 |
stdDeviation | 模糊程度 |
flood-color | 阴影颜色 |
flood-opacity | 阴影透明度 |
不同的阴影效果
html
<svg width="500" height="150">
<defs>
<!-- 轻柔阴影 -->
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="2" dy="2" stdDeviation="4" flood-color="#00000020"/>
</filter>
<!-- 硬阴影 -->
<filter id="hardShadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="4" dy="4" stdDeviation="0" flood-color="#00000040"/>
</filter>
<!-- 深阴影 -->
<filter id="deepShadow" x="-30%" y="-30%" width="160%" height="160%">
<feDropShadow dx="6" dy="6" stdDeviation="6" flood-color="#00000060"/>
</filter>
<!-- 彩色阴影 -->
<filter id="colorShadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="3" dy="3" stdDeviation="4" flood-color="#3b82f680"/>
</filter>
</defs>
<g>
<rect x="30" y="30" width="70" height="70" rx="10" fill="#3b82f6" filter="url(#softShadow)"/>
<text x="65" y="125" text-anchor="middle" font-size="11">轻柔</text>
</g>
<g>
<rect x="140" y="30" width="70" height="70" rx="10" fill="#22c55e" filter="url(#hardShadow)"/>
<text x="175" y="125" text-anchor="middle" font-size="11">硬阴影</text>
</g>
<g>
<rect x="250" y="30" width="70" height="70" rx="10" fill="#f59e0b" filter="url(#deepShadow)"/>
<text x="285" y="125" text-anchor="middle" font-size="11">深阴影</text>
</g>
<g>
<rect x="360" y="30" width="70" height="70" rx="10" fill="#8b5cf6" filter="url(#colorShadow)"/>
<text x="395" y="125" text-anchor="middle" font-size="11">彩色</text>
</g>
</svg>使用滤镜组合创建阴影
对于更精细的控制,可以组合多个滤镜元素:
html
<svg width="300" height="120">
<defs>
<filter id="customShadow" x="-20%" y="-20%" width="140%" height="140%">
<!-- 获取alpha通道 -->
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
<!-- 偏移 -->
<feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
<!-- 着色 -->
<feFlood flood-color="#000000" flood-opacity="0.3" result="color"/>
<feComposite in="color" in2="offsetBlur" operator="in" result="shadow"/>
<!-- 合并阴影和原图 -->
<feMerge>
<feMergeNode in="shadow"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<rect x="40" y="30" width="100" height="60" rx="10" fill="#3b82f6" filter="url(#customShadow)"/>
<text x="210" y="70" font-size="24" font-weight="bold" fill="#ef4444" filter="url(#customShadow)">TEXT</text>
</svg>内阴影
创建凹陷效果的内阴影:
html
<svg width="300" height="120">
<defs>
<filter id="innerShadow" x="-50%" y="-50%" width="200%" height="200%">
<!-- 创建偏移的阴影 -->
<feOffset dx="3" dy="3" in="SourceAlpha" result="offset"/>
<feGaussianBlur stdDeviation="3" in="offset" result="blur"/>
<!-- 反转 -->
<feComposite operator="out" in="SourceGraphic" in2="blur" result="inverse"/>
<!-- 着色 -->
<feFlood flood-color="black" flood-opacity="0.4" result="color"/>
<feComposite operator="in" in="color" in2="inverse" result="shadow"/>
<!-- 合并 -->
<feComposite operator="over" in="shadow" in2="SourceGraphic"/>
</filter>
</defs>
<rect x="40" y="25" width="100" height="70" rx="10" fill="#e5e7eb" filter="url(#innerShadow)"/>
<circle cx="220" cy="60" r="40" fill="#e5e7eb" filter="url(#innerShadow)"/>
</svg>多层阴影
创建更真实的多层阴影效果:
html
<svg width="200" height="120">
<defs>
<filter id="multiShadow" x="-30%" y="-30%" width="160%" height="160%">
<!-- 第一层:近阴影 -->
<feDropShadow dx="1" dy="1" stdDeviation="1" flood-color="#00000015" result="shadow1"/>
<!-- 第二层:中阴影 -->
<feDropShadow dx="3" dy="3" stdDeviation="3" flood-color="#00000015" result="shadow2"/>
<!-- 第三层:远阴影 -->
<feDropShadow dx="6" dy="6" stdDeviation="8" flood-color="#00000010"/>
</filter>
</defs>
<rect x="40" y="25" width="120" height="70" rx="12" fill="white" filter="url(#multiShadow)"/>
</svg>底部阴影(接触阴影)
模拟物体接触表面的阴影:
html
<svg width="200" height="150">
<defs>
<filter id="contactShadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur"/>
<feOffset in="blur" dx="0" dy="15" result="offset"/>
<feComposite in="offset" in2="SourceAlpha" operator="out" result="shadow"/>
<feMerge>
<feMergeNode in="shadow"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- 椭圆阴影 -->
<filter id="ellipseShadow">
<feGaussianBlur stdDeviation="5"/>
</filter>
</defs>
<!-- 椭圆阴影 -->
<ellipse cx="100" cy="130" rx="50" ry="12" fill="#00000030" filter="url(#ellipseShadow)"/>
<!-- 物体 -->
<rect x="50" y="40" width="100" height="70" rx="10" fill="#3b82f6"/>
</svg>长阴影
流行的扁平化设计阴影:
html
<svg width="200" height="200">
<defs>
<linearGradient id="longShadowGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#00000030"/>
<stop offset="100%" stop-color="#00000000"/>
</linearGradient>
<clipPath id="shadowClip">
<rect x="0" y="0" width="200" height="200"/>
</clipPath>
</defs>
<!-- 背景 -->
<rect x="0" y="0" width="200" height="200" fill="#3b82f6"/>
<!-- 长阴影 -->
<g clip-path="url(#shadowClip)">
<polygon points="100,60 180,140 260,220 180,220 100,140" fill="url(#longShadowGrad)"/>
</g>
<!-- 图标 -->
<circle cx="100" cy="100" r="40" fill="white"/>
</svg>实际应用示例
卡片阴影
html
<svg width="250" height="180">
<defs>
<filter id="cardShadow" x="-10%" y="-10%" width="120%" height="130%">
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#00000015"/>
</filter>
</defs>
<rect x="25" y="20" width="200" height="130" rx="12" fill="white" filter="url(#cardShadow)"/>
<rect x="25" y="20" width="200" height="60" rx="12" fill="#3b82f6"/>
<rect x="25" y="68" width="200" height="12" fill="#3b82f6"/>
<text x="125" y="110" text-anchor="middle" font-size="14" fill="#1f2937">Card Title</text>
<text x="125" y="130" text-anchor="middle" font-size="12" fill="#6b7280">Description text</text>
</svg>按钮阴影
html
<svg width="300" height="80">
<defs>
<filter id="btnShadow" x="-10%" y="-10%" width="120%" height="140%">
<feDropShadow dx="0" dy="3" stdDeviation="4" flood-color="#1d4ed880"/>
</filter>
<filter id="btnShadowHover" x="-10%" y="-10%" width="120%" height="160%">
<feDropShadow dx="0" dy="6" stdDeviation="8" flood-color="#1d4ed860"/>
</filter>
</defs>
<!-- 普通按钮 -->
<rect x="20" y="20" width="120" height="44" rx="8" fill="#3b82f6" filter="url(#btnShadow)"/>
<text x="80" y="48" text-anchor="middle" fill="white" font-size="14" font-weight="bold">Normal</text>
<!-- 悬停按钮 -->
<rect x="160" y="16" width="120" height="44" rx="8" fill="#3b82f6" filter="url(#btnShadowHover)"/>
<text x="220" y="44" text-anchor="middle" fill="white" font-size="14" font-weight="bold">Hover</text>
</svg>图标阴影
html
<svg width="250" height="80">
<defs>
<filter id="iconShadow" x="-20%" y="-20%" width="140%" height="150%">
<feDropShadow dx="0" dy="2" stdDeviation="2" flood-color="#00000030"/>
</filter>
</defs>
<!-- 带阴影的图标 -->
<g filter="url(#iconShadow)">
<circle cx="50" cy="40" r="25" fill="#3b82f6"/>
<text x="50" y="47" text-anchor="middle" fill="white" font-size="20">★</text>
</g>
<g filter="url(#iconShadow)">
<circle cx="130" cy="40" r="25" fill="#22c55e"/>
<text x="130" y="47" text-anchor="middle" fill="white" font-size="20">✓</text>
</g>
<g filter="url(#iconShadow)">
<circle cx="210" cy="40" r="25" fill="#ef4444"/>
<text x="210" y="47" text-anchor="middle" fill="white" font-size="20">♥</text>
</g>
</svg>文字阴影
html
<svg width="300" height="80">
<defs>
<filter id="textShadow" x="-10%" y="-10%" width="120%" height="130%">
<feDropShadow dx="2" dy="2" stdDeviation="1" flood-color="#00000050"/>
</filter>
</defs>
<text x="150" y="50" text-anchor="middle" font-size="36" font-weight="bold"
fill="#1f2937" filter="url(#textShadow)">
Shadow Text
</text>
</svg>浮动效果
html
<svg width="200" height="120">
<defs>
<filter id="floatShadow" x="-30%" y="-30%" width="160%" height="180%">
<feDropShadow dx="0" dy="15" stdDeviation="10" flood-color="#00000025"/>
</filter>
</defs>
<rect x="40" y="20" width="120" height="60" rx="10" fill="#3b82f6" filter="url(#floatShadow)"/>
</svg>下一步
学会了阴影效果后,接下来学习 SVG 线性渐变!