【问题标题】:SVG drop shadow using css3使用 css3 的 SVG 投影
【发布时间】:2011-08-30 14:41:34
【问题描述】:

是否可以使用 css3 为 svg 元素设置投影,例如

box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;

我看到了一些关于使用滤镜效果创建阴影的评论。有没有单独使用css的例子。下面是正确应用 cusor 样式但没有阴影效果的工作代码。请帮助我用最少的代码获得阴影效果。

svg .shadow { 
  cursor:crosshair; 
  -moz-box-shadow: -5px -5px 5px #888;
  -webkit-box-shadow: -5px -5px 5px #888;
  box-shadow: -5px -5px 5px #888; 
}	
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full"  viewBox="0 0 120 70">	
    <rect class="shadow" x="10" y="10" width="100" height="50" fill="#c66" />
</svg>

【问题讨论】:

    标签: html css svg svg-filters


    【解决方案1】:

    使用 new CSS filter 属性。

    Supported by webkit browsers、Firefox 34+ 和 Edge

    你可以使用这个polyfill,它将支持 FF

    你会这样使用它:

    /* Use -webkit- only if supporting: Chrome < 54, iOS < 9.3, Android < 4.4.4 */
    
    .shadow {
      -webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
      filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
      /* Similar syntax to box-shadow */
    }
    <img src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Star_wars2.svg" alt="" class="shadow" width="200">
    
    <!-- Or -->
    
    <svg class="shadow" ...>
        <rect x="10" y="10" width="200" height="100" fill="#bada55" />
    </svg>

    这种方法与 css box-shadow 效果的不同之处在于它考虑了不透明度,并且不将阴影效果应用于框,而是应用于 svg 元素本身的轮廓。

    请注意:这种方法仅适用于将类单独放在&lt;svg&gt; 元素上的情况。您可以在诸如 &lt;rect&gt; 的内联 svg 元素上使用它。

    <!-- This will NOT work! -->
    <svg><rect class="shadow" ... /></svg>
    

    html5rocks 上阅读有关 css 过滤器的更多信息。

    【讨论】:

    • 这似乎适用于图像或整个 svg,但适用于 svg 内的选择。 the fiddle
    • 这不适用于以任何方式将阴影应用于 svg 元素。 不要使用它。失败示例:jsbin.com/bepurahuwa/1/edit?html,css,js,output
    • @AndyRay 就像一个魅力...jsbin.com/peviso/edit?html,css,js,output。你把类放在 标签上。
    • @hitautodestruct 是的,它确实是这样工作的。 真正的问题出现在您需要将过滤器应用到一个元素而不是其他元素时。
    • 我猜@AndyRay 和 hitautodestruct 都是正确的,因为作为pointed out here,这看起来像是 Chrome 渲染问题:Firefox 正在正确渲染 SVG 特定元素上的过滤器。
    【解决方案2】:

    这是一个 example 使用“过滤器”属性将阴影应用于某些 svg。如果您想控制阴影的不透明度,请查看this exampleslope 属性控制赋予阴影的不透明度。

    示例中的相关位:

    <filter id="dropshadow" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
      <feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
      <feComponentTransfer>
        <feFuncA type="linear" slope="0.5"/> <!-- slope is the opacity of the shadow -->
      </feComponentTransfer>
      <feMerge> 
        <feMergeNode/> <!-- this contains the offset blurred image -->
        <feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
      </feMerge>
    </filter>
    <circle r="10" style="filter:url(#dropshadow)"/>
    

    Box-shadow 被定义为在 CSS 盒子(阅读:矩形)上工作,而 svg 比矩形更具表现力。阅读SVG Primer,了解更多关于 SVG 滤镜可以做什么的信息。

    【讨论】:

    【解决方案3】:

    您可以使用 drop-shadow() CSS 函数和 rgba 颜色值轻松地为 svg 元素添加阴影效果。通过使用 rgba 颜色值,您可以更改阴影的不透明度。

    img.light-shadow{
      filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4));
    }
    
    img.dark-shadow{
      filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 1));
    }
    <img class="light-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />
    <img class="dark-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />

    【讨论】:

    • @Foxhoundn 这绝对是现代解决方案,应该被接受为答案。
    • Internet Explorer 11:失败(无投影但显示原始 SVG 图像)。 Firefox(发布和 ESR):好的。谷歌浏览器:好的。 Edge Legacy:好的。
    • dam,如果这只适用于 SVG 中的组和形状!
    【解决方案4】:

    我发现最简单的方法是使用feDropShadow

    <filter id="shadow" x="0" y="0" width="200%" height="200%">
      <feDropShadow dx="40" dy="40" stdDeviation="35" flood-color="#ff0000" flood-opacity="1" />
    </filter>
    

    在元素上:

    <path d="..." filter="url(#shadow)"/>
    

    【讨论】:

    • 我做了一些阅读,现在我理解了你的答案,你肯定会得到支持。这个答案没有得到足够的重视。但是,多一点解释会很好。例如:developer.mozilla.org/en-US/docs/Web/SVG/Element/…
    • 为此,您需要将filter:url(#shadow) 添加到您想要有阴影的元素(#shadowfilter 标签的ID)。例如&lt;path d="..." style="filter:url(#shadow)"/&gt;。也许您应该将其添加到您的答案中。
    • feDropShadow dx="40" dy="40" stdDeviation="35" 中使用较小的值,例如 3,3,1 而不是 40,40,35 可能会避免一些混乱。
    【解决方案5】:

    带有白色阴影的黑色文本

    另一种方式,我用于白色阴影(在文本上):为阴影创建克隆:

    注意:这需要 xmlns:xlink="http://www.w3.org/1999/xlink" 在 SVG 声明中。

    实际文本值位于&lt;defs&gt; 部分,有位置和样式,但没有fill 定义。

    文本被克隆两次:第一次用于阴影,第二次用于文本本身。

    <svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
        xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
      <filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
      <text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
          id="Text"><tspan x="12" y="19">
            Black text with white shadow
        </tspan></text>
      </defs>
      <rect style="fill:#8AB" width="640" height="70" />
      <use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
          transform="translate(1.8,.9)"/>
      <use style="fill:black;" xlink:href="#Text"/>
    </svg>

    更多远处阴影,最大值为模糊偏差

    <svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
        xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
      <filter id="Blur"><feGaussianBlur stdDeviation="3" /></filter>
      <text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
          id="Text"><tspan x="12" y="19">
            Black text with white shadow
        </tspan></text>
      </defs>
      <rect style="fill:#8AB" width="640" height="70" />
      <use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
          transform="translate(7,5)"/>
      <use style="fill:black;" xlink:href="#Text"/>
    </svg>

    您可以对常规 SVG 对象使用相同的方法。

    具有相同要求:&lt;defs&gt; 部分没有填充定义

    <svg xmlns="http://www.w3.org/2000/svg" width="364" height="172"
        xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
        <g transform="matrix(.7,0,0,.7,-117.450795,-335.320895)" id="Img">
            <g transform="matrix(12.997776,0,0,-12.997776,389.30313,662.04015)">
                <path d="m 0,0 -1.107,0 c -0.039,0 -0.067,0.044 -0.067,0.086 0,0.015 0.589,1.914 0.589,1.914 0.021,0.071 0.023,0.073 0.031,0.073 l 0.001,0 c 0.009,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.899 0.589,-1.914 C 0.067,0.044 0.037,0 0,0 M 1.493,4.345 C 1.482,4.383 1.448,4.411 1.408,4.414 l -4.065,0 C -2.698,4.41 -2.731,4.383 -2.742,4.346 c 0,0 -2.247,-7.418 -2.247,-7.432 0,-0.037 0.029,-0.067 0.067,-0.067 l 2.687,0 c 0.021,0.008 0.037,0.028 0.042,0.051 l 0.313,1 c 0.01,0.025 0.033,0.042 0.061,0.043 l 2.479,0.002 c 0.027,-0.002 0.051,-0.021 0.061,-0.045 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.068,0.028 0.068,0.065 0,0.013 -2.302,7.433 -2.302,7.433" />
            </g>
            <g transform="matrix(12.997776,0,0,-12.997776,508.27177,644.93113)">
                <path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 7.916,0.645 3.741,0 0,2.453 -4.81,0 C 6.397,3.098 5.764,2.866 5.401,2.597 5.038,2.328 4.513,1.715 4.513,0.87 c 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.005 0.925,-1.005 0.015,-0.016 0.024,-0.037 0.024,-0.061 0,-0.051 -0.041,-0.092 -0.092,-0.092 l -3.705,0 c -0.451,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.096 0.57,3.096 l -5.287,0 c 0,0 0,-7.52 0,-7.522 0,-0.024 0.022,-0.043 0.046,-0.043 l 2.943,0 0,2.11 c 0,0.037 0.057,0 0.057,0 l 1.533,-1.54 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 5.796,0.001 c 0.989,0 1.539,0.538 1.69,0.688 0.15,0.151 0.651,0.714 0.651,1.647 0,0.932 -0.426,1.409 -0.608,1.628 C 8.675,-0.309 8.029,0.375 7.894,0.517 7.878,0.53 7.868,0.55 7.868,0.572 c 0,0.033 0.019,0.064 0.048,0.073" />
            </g>
            <g transform="matrix(12.997776,0,0,-12.997776,306.99861,703.01559)">
                <path d="m 0,0 c 0.02,0 0.034,0.014 0.04,0.036 0,0 2.277,7.479 2.277,7.486 0,0.02 -0.012,0.042 -0.031,0.044 0,0 -2.805,0 -2.807,0 -0.014,0 -0.023,-0.011 -0.026,-0.026 0,-0.001 -0.581,-1.945 -0.581,-1.946 -0.004,-0.016 -0.012,-0.026 -0.026,-0.026 -0.014,0 -0.026,0.014 -0.028,0.026 L -1.79,7.541 c -0.002,0.013 -0.012,0.025 -0.026,0.025 -10e-4,0 -3.1,0.001 -3.1,0.001 -0.009,-0.002 -0.017,-0.01 -0.02,-0.018 0,0 -0.545,-1.954 -0.545,-1.954 -0.003,-0.017 -0.012,-0.027 -0.027,-0.027 -0.013,0 -0.024,0.01 -0.026,0.023 l -0.578,1.952 c -0.001,0.012 -0.011,0.022 -0.023,0.024 l -2.992,0 c -0.024,0 -0.044,-0.02 -0.044,-0.045 0,-0.004 10e-4,-0.012 10e-4,-0.012 0,0 2.31,-7.471 2.311,-7.474 C -6.853,0.014 -6.839,0 -6.819,0 c 0.003,0 2.485,-0.001 2.485,-0.001 0.015,0.002 0.03,0.019 0.034,0.037 10e-4,0 0.865,2.781 0.865,2.781 0.005,0.017 0.012,0.027 0.026,0.027 0.015,0 0.023,-0.012 0.027,-0.026 L -2.539,0.024 C -2.534,0.01 -2.521,0 -2.505,0 -2.503,0 0,0 0,0" />
            </g>
            <g transform="matrix(12.997776,0,0,-12.997776,278.90126,499.03369)">
                <path d="m 0,0 c -0.451,0 -1.083,-0.232 -1.446,-0.501 -0.363,-0.269 -0.888,-0.882 -0.888,-1.727 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.01 0.925,-1.01 0.015,-0.016 0.024,-0.037 0.024,-0.06 0,-0.051 -0.041,-0.093 -0.092,-0.093 -0.008,0 -6.046,0 -6.046,0 l 0,-2.674 7.267,0 c 0.988,0 1.539,0.538 1.69,0.689 0.15,0.15 0.65,0.713 0.65,1.646 0,0.932 -0.425,1.414 -0.607,1.633 -0.162,0.196 -0.808,0.876 -0.943,1.017 -0.016,0.014 -0.026,0.034 -0.026,0.056 0,0.033 0.019,0.063 0.048,0.073 l 3.5,0 0,-5.114 2.691,0 0,5.101 3.267,0 0,2.466 L 0,0 Z" />
            </g>
            <g transform="matrix(12.997776,0,0,-12.997776,583.96822,539.30215)">
                <path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 2.178,-1.79 c -0.45,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.098 0.57,3.098 l -5.287,0 c 0,0 0,-7.522 0,-7.524 0,-0.024 0.022,-0.043 0.046,-0.043 0.005,0 2.943,0 2.943,0 l 0,2.109 c 0,0.038 0.057,0 0.057,0 l 1.533,-1.539 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 4.525,0 0,2.679 -3.655,0 z" />
            </g>
            <g transform="matrix(12.997776,0,0,-12.997776,466.86346,556.40203)">
                <path d="m 0,0 -1.107,0 c -0.041,0 -0.067,0.044 -0.067,0.086 0,0.016 0.589,1.914 0.589,1.914 0.021,0.071 0.027,0.073 0.031,0.073 l 0.001,0 c 0.004,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.898 0.589,-1.914 C 0.067,0.044 0.04,0 0,0 M 1.49,4.347 C 1.479,4.385 1.446,4.412 1.405,4.414 l -4.065,0 C -2.7,4.412 -2.734,4.385 -2.745,4.348 c 0,0 -2.245,-7.42 -2.245,-7.434 0,-0.037 0.03,-0.067 0.067,-0.067 l 2.687,0 c 0.022,0.007 0.038,0.028 0.043,0.051 l 0.313,1.001 c 0.01,0.024 0.033,0.041 0.061,0.042 l 2.478,0 C 0.687,-2.061 0.71,-2.078 0.721,-2.102 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.067,0.028 0.067,0.066 0,0.012 -2.304,7.434 -2.304,7.434" />
            </g>
        </g>
      </defs>
      <rect style="fill:#8AB" width="364" height="172" />
      <use style="fill:white;" filter="url(#Blur)" xlink:href="#Img"
        transform="translate(1.8,.9)"/>
      <use style="fill:black;" xlink:href="#Img"/>
    </svg>

    【讨论】:

    • 不能只用flood-color吗?
    • Blur 用于使阴影看起来有点模糊。查看我的第二个文本版本More distant shadow...(刚刚添加)
    【解决方案6】:

    可能是一种演变,内联 css 过滤器似乎以某种方式很好地处理元素。

    如前所述,在 svg 元素中,在类或内联中声明一个阴影 css 过滤器 NOT 有效。

    但是,至少在 Firefox 中,具有以下魔法:

    附加过滤器声明内联,使用javascript,在DOM加载后

    // Does not works, with regular dynamic css styling:
    
    shadow0.oninput = () => {
      rect1.style.filter = "filter:drop-shadow(0 0 " + shadow0.value + "rem black);"
    }
    
    // Okay! Inline styling, appending.
    
    shadow1.oninput = () => {
      rect1.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
      rect2.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
    }
    <h2>Firefox only</h2>
    <h4>
    Does not works! 
    <input id="shadow0" type="number" min="0" max="100" step="0.1">
    
     | Okay!
    <input id="shadow1" type="number" min="0" max="100" step="0.1">
    
    <svg viewBox="0 0 120 70">  
        <rect id="rect1" x="10" y="10" width="100" height="50" fill="#c66" />
        
        <!-- Inline style declaration does NOT works at svg level, no shadow at loading: -->
        <rect id="rect2" x="40" y="30" width="10" height="10" fill="#aaa" style="filter:drop-shadow(0 0 20rem black)" />
        
    </svg>

    【讨论】:

      【解决方案7】:

      如果你的 SVG 元素是 &lt;text&gt;,你可以使用 CSS 属性 text-shadow 没有任何问题。语法是text-shadow: color x-offset-px y-offset-px blur-px

      【讨论】:

        【解决方案8】:

        我不知道只有 CSS 的解决方案。

        正如您所提到的,滤镜是在 SVG 中创建投影效果的规范方法。 SVG 规范包括一个这样的例子。

        【讨论】:

        • -webkit-filter: drop-shadow() 是肯定要走的路。请参阅@hitautodestruct 的答案。
        • @clayzermk1 如果您希望它仅在 webkit 中工作......那么是的。我们正在寻找更可靠的解决方案,我认为,我认为这也不再受支持。
        • @jbeard4 链接已损坏,最好将内容粘贴到此处。
        • 提交的链接指向Removed: Filter Effects This chapter is no longer part of the SVG specification!!
        • 这是一个非答案。
        猜你喜欢
        • 1970-01-01
        • 2022-07-20
        • 2018-01-15
        • 1970-01-01
        • 2019-03-25
        • 2015-08-09
        相关资源
        最近更新 更多