Bóng đổ SVG bằng css3


379

Có thể đặt bóng đổ cho phần tử svg bằng css3, đại loại như

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

Tôi thấy một số nhận xét về việc tạo bóng bằng hiệu ứng bộ lọc. Có một ví dụ về việc sử dụng css một mình. Dưới đây là một mã làm việc trong đó kiểu cusor được áp dụng chính xác, nhưng không có hiệu ứng bóng. Xin hãy giúp tôi để có được hiệu ứng bóng với ít mã nhất.

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>

Câu trả lời:


353

Đây là một ví dụ về việc áp dụng dropshadow cho một số svg bằng cách sử dụng thuộc tính 'bộ lọc'. Nếu bạn muốn kiểm soát độ mờ đục của dropshadow, hãy xem ví dụ này . Cácslope thuộc tính điều khiển bao nhiêu opacity để cung cấp cho các DropShadow.

Các bit có liên quan từ ví dụ:

<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)"/>

Bóng hộp được định nghĩa để hoạt động trên các hộp CSS (đọc: hình chữ nhật), trong khi svg biểu cảm hơn một chút so với chỉ hình chữ nhật. Đọc Primer SVG để tìm hiểu thêm một chút về những gì bạn có thể làm với các bộ lọc SVG.


1
Có cách nào để kiểm soát độ mờ đục của dropshadow không?
Hugh Guiney

5
@HughGuiney: vâng, tất nhiên rồi. Đây là một ví dụ về một cách để làm điều đó, xn--dahlstrm-t4a.net/svg/filters/ ,. Chỉ cần thay đổi slopethuộc tính để điều chỉnh độ mờ bạn muốn.
Erik Dahlström

1
@LorenzoPolidori IE10 và Safari 5.2 đều hỗ trợ bộ lọc SVG.
Erik Dahlström

3
Ví dụ về cách triển khai phương pháp này trong D3.js: bl.ocks.org/cpbotha/5200394
mb21


559

Sử dụng thuộc tính CSS mớifilter .

Được hỗ trợ bởi các trình duyệt webkit , Firefox 34+ và Edge .

Bạn có thể sử dụng polyfill này sẽ hỗ trợ FF <34, IE6 +.

Bạn sẽ sử dụng nó như vậy:

/* 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>

Cách tiếp cận này khác với box-shadowhiệu ứng ở chỗ nó chiếm độ mờ và không áp dụng hiệu ứng đổ bóng cho hộp mà thay vào đó là các góc của chính phần tử svg.

Xin lưu ý : Cách tiếp cận này chỉ hoạt động khi lớp được đặt trên <svg>phần tử một mình. Bạn KHÔNG thể sử dụng điều này trên một phần tử svg nội tuyến như <rect>.

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

Đọc thêm về bộ lọc css trên html5rocks .


47
Điều này dường như hoạt động cho hình ảnh, hoặc cho toàn bộ svg, nhưng cho các lựa chọn bên trong svg. the fiddle
heneryville

14
Điều này không hoạt động để áp dụng bóng đổ cho các phần tử svg theo bất kỳ cách nào. đừng sử dụng nó. Ví dụ về sự thất bại: jsbin.com/bepurahuwa/1/edit?html,css,js,output
Andy Ray

19
@AndyRay hoạt động như một bùa mê ... jsbin.com/peviso/edit?html,css,js,output . Bạn đặt lớp vào thẻ <svg>.
hitautodesturation

4
@hitautodesturation có, nó hoạt động như thế. Các thực vấn đề đến khi bạn cần quá áp dụng bộ lọc để một phần tử, nhưng không phải cho người khác.
Joum

3
Tôi đoán cả @AndyRay và hitautodesturation đều đúng, vì như đã chỉ ra ở đây , điều này trông giống như một vấn đề kết xuất Chrome: Firefox đang hiển thị chính xác bộ lọc trên các thành phần cụ thể của SVG.
Gruber

71

Bạn có thể dễ dàng thêm hiệu ứng đổ bóng vào phần tử svg bằng cách sử dụng hàm CSS drop-Shadow () và các giá trị màu rgba. Bằng cách sử dụng các giá trị màu rgba, bạn có thể thay đổi độ mờ của bóng.

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" />


4
@Foxhoundn Đây chắc chắn là giải pháp hiện đại, và nên được chấp nhận là câu trả lời.
SeedyROM

2
Nhưng nó không hoạt động cho các thành phần phụ của một SVG
mix3d

Internet Explorer 11: Fail (không có bóng đổ nhưng hình ảnh SVG gốc được hiển thị). Firefox (Phát hành & ESR): OK. Google Chrome: OK. Di sản cạnh: OK.
Culip

chết tiệt, nếu điều này chỉ làm việc trên các nhóm và hình dạng trong SVG!
OG Sean

25

Cách dễ nhất mà tôi tìm thấy là với feDropShadow. Tôi sẽ không bao giờ quay lại sử dụng những tên thẻ bộ lọc bí truyền tuyệt vời mà tôi không hiểu.

<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>

4
Tôi đã đọc một số và bây giờ tôi hiểu câu trả lời của bạn, bạn chắc chắn nhận được upvote đó. Câu trả lời này không đủ đánh giá cao. Tuy nhiên, một chút giải thích sẽ ong tốt. Ví dụ này là: developer.mozilla.org/en-US/docs/Web/SVG/Euity/
Kẻ

Bạn hoàn toàn đúng. Cảm ơn bạn!
nikk wong

Để làm việc này, bạn cần thêm filter:url(#shadow)vào phần tử bạn muốn có bóng ( #shadowlà id của filterthẻ). Ví dụ <path d="..." style="filter:url(#shadow)"/>. Có lẽ bạn nên thêm nó vào câu trả lời của bạn.
Vịt Donald

1

Tôi không biết về một giải pháp chỉ CSS.

Như bạn đã đề cập, các bộ lọc là cách tiếp cận chính tắc để tạo hiệu ứng đổ bóng trong SVG. Đặc tả SVG bao gồm một ví dụ về điều này.


3
-webkit-filter: drop-shadow()là cách để đi cho chắc chắn Xem câu trả lời của @hitautodesturation.
clayzermk1

4
@ clayzermk1 nếu bạn muốn nó chỉ hoạt động trong webkit .... thì vâng. Chúng tôi đang tìm kiếm một giải pháp vững chắc hơn, methinks và tôi nghĩ rằng điều này cũng không còn được hỗ trợ.
dudewad

@ jbeard4 liên kết bị hỏng, tốt hơn có thể có nội dung được dán ở đây.
Ezeewei

1
Gửi liên kết điểm đến Removed: Filter Effects This chapter is no longer part of the SVG specification!!
F. Hauri

1
Đây là một câu trả lời không.
Yay295

1

Văn bản màu đen với bóng trắng

Một cách khác, tôi đã sử dụng cho bóng trắng (trên văn bản): tạo bản sao cho bóng:

Lưu ý : Điều này yêu cầu xmlns:xlink="http://www.w3.org/1999/xlink"tại khai báo SVG.

Giá trị văn bản thực được đặt trong <defs>phần, với vị trí và kiểu, nhưng không có fillđịnh nghĩa.

Văn bản được nhân bản hai lần: lần đầu tiên cho bóng và lần thứ hai cho chính văn bản.

<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>

Hơn xa bóng có giá trị lớn nhất là độ lệch mờ :

<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>

Bạn có thể sử dụng cách tiếp cận tương tự với các đối tượng SVG thông thường.

Với cùng một yêu cầu: Không có định nghĩa điền vào <defs>phần !

<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>


Không thể chỉ sử dụng flood-color?
Robert Monfera

Blurđược sử dụng để làm cho bóng trông hơi mờ. Xem phiên bản văn bản thứ hai của tôi More distant shadow...(Chỉ cần thêm bây giờ)
F. Hauri

0

Có lẽ là một sự tiến hóa, có vẻ như các bộ lọc css nội tuyến hoạt động độc đáo trên các yếu tố, theo một cách nhất định.

Khai báo bộ lọc css bóng đổ, trong phần tử svg, trong cả lớp hoặc nội tuyến KHÔNG hoạt động, như đã chỉ định trước đó.

Nhưng, ít nhất là trong Firefox, với thuật sĩ sau:

Áp dụng khai báo bộ lọc nội tuyến , với javascript, sau khi tải DOM .

// Does not works, with regular dynamic css styling:

shadow0.onchange = () => {
  rect1.style.filter = "filter:drop-shadow(0 0 " + shadow0.value + "rem black);"
}

// Okay! Inline styling, appending.

shadow1.onchange = () => {
  rect1.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
  rect2.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
}
<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>

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.