SVG và CSS
Trang này minh họa cách áp dụng CSS vào ngôn ngữ chuyên biệt dùng để tạo đồ họa: SVG.
Phía dưới, bạn sẽ tạo một minh họa có thể chạy trong trình duyệt.
Note:
Các phần tử được tham chiếu bởi phần tử <use> sẽ kế thừa kiểu từ phần tử đó. Vì vậy, để áp dụng các kiểu khác nhau cho chúng, bạn nên dùng CSS custom properties.
Ví dụ
Tạo một tài liệu SVG mới dưới dạng tệp văn bản thuần, doc8.svg. Sao chép và dán nội dung từ đây, nhớ cuộn để lấy hết toàn bộ nội dung:
<svg
width="600px"
height="600px"
viewBox="-300 -300 600 600"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<link
xmlns="http://www.w3.org/1999/xhtml"
rel="stylesheet"
href="style8.css"
type="text/css" />
<title>SVG demonstration</title>
<desc>Mozilla CSS Getting Started - SVG demonstration</desc>
<defs>
<radialGradient
id="fade"
cx="0"
cy="0"
r="200"
gradientUnits="userSpaceOnUse">
<stop id="fade-stop-1" offset="33%" />
<stop id="fade-stop-2" offset="95%" />
</radialGradient>
</defs>
<text id="heading" x="-280" y="-270">SVG demonstration</text>
<text id="caption" x="-280" y="-250">
Move your mouse pointer over the flower.
</text>
<g id="flower">
<circle
id="overlay"
cx="0"
cy="0"
r="200"
stroke="none"
fill="url(#fade)" />
<g id="outer-petals">
<g class="quadrant">
<g class="segment">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(18)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(36)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(54)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(72)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(90)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(108)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(126)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(144)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(162)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(180)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(198)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(216)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(234)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(252)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(270)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(288)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(306)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(324)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(342)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
</g>
<g id="inner-petals" transform="rotate(9) scale(0.33)">
<g class="quadrant">
<g class="segment">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(18)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(36)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(54)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(72)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(90)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(108)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(126)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(144)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(162)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(180)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(198)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(216)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(234)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(252)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
<g class="quadrant">
<g class="segment" transform="rotate(270)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(288)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(306)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(324)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g class="segment" transform="rotate(342)">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
</g>
</g>
</g>
</svg>
Tạo một tệp CSS mới, style8.css trong cùng thư mục với doc8.svg. Sao chép và dán nội dung từ đây, nhớ cuộn để lấy hết toàn bộ nội dung:
/*** SVG demonstration ***/
/* page */
svg {
background-color: beige;
}
#heading {
font-size: 24px;
font-weight: bold;
}
#caption {
font-size: 12px;
}
/* flower */
#flower:hover {
cursor: crosshair;
}
/* gradient */
#fade-stop-1 {
stop-color: blue;
}
#fade-stop-2 {
stop-color: white;
}
/* petals */
.segment-fill {
fill: var(--segment-fill-fill);
stroke: var(--segment-fill-stroke);
stroke-width: var(--segment-fill-stroke-width);
}
.segment-fill:hover {
fill: var(--segment-fill-fill-hover);
stroke: var(--segment-fill-stroke-hover);
}
.segment-edge {
fill: var(--segment-edge-fill);
stroke: var(--segment-edge-stroke);
stroke-width: var(--segment-edge-stroke-width);
}
.segment-edge:hover {
stroke: var(--segment-edge-stroke-hover);
}
/* outer petals */
#outer-petals {
opacity: 0.75;
--segment-fill-fill: azure;
--segment-fill-stroke: lightsteelblue;
--segment-fill-stroke-width: 1;
--segment-edge-fill: none;
--segment-edge-stroke: deepskyblue;
--segment-edge-stroke-width: 3;
--segment-fill-fill-hover: plum;
--segment-fill-stroke-hover: none;
--segment-edge-stroke-hover: slateblue;
}
/*
Non-standard way of styling elements referenced via <use> elements,
supported by some older browsers
*/
#outer-petals .segment-fill {
fill: azure;
stroke: lightsteelblue;
stroke-width: 1;
}
#outer-petals .segment-edge {
fill: none;
stroke: deepskyblue;
stroke-width: 3;
}
#outer-petals .segment:hover > .segment-fill {
fill: plum;
stroke: none;
}
#outer-petals .segment:hover > .segment-edge {
stroke: slateblue;
}
/* inner petals */
#inner-petals {
--segment-fill-fill: yellow;
--segment-fill-stroke: yellow;
--segment-fill-stroke-width: 1;
--segment-edge-fill: none;
--segment-edge-stroke: yellowgreen;
--segment-edge-stroke-width: 9;
--segment-fill-fill-hover: darkseagreen;
--segment-fill-stroke-hover: none;
--segment-edge-stroke-hover: green;
}
/*
Non-standard way of styling elements referenced via <use> elements,
supported by some older browsers
*/
#inner-petals .segment-fill {
fill: yellow;
stroke: yellow;
stroke-width: 1;
}
#inner-petals .segment-edge {
fill: none;
stroke: yellowgreen;
stroke-width: 9;
}
#inner-petals .segment:hover > .segment-fill {
fill: darkseagreen;
stroke: none;
}
#inner-petals .segment:hover > .segment-edge {
stroke: green;
}
Hãy mở tài liệu doc8.svg trong trình duyệt có hỗ trợ SVG của bạn. Di chuyển con trỏ chuột qua đồ họa để xem điều gì xảy ra.
Kết quả
Một vài ghi chú về minh họa này:
-
Tài liệu SVG liên kết stylesheet bằng thẻ HTML
<link>sau:html<link rel="stylesheet" href="style8.css" type="text/css" />Nó cũng có thể được liên kết bằng quy tắc
@importbên trong thẻ<style>:html<style> @import "style8.css"; </style> -
SVG có các thuộc tính và giá trị CSS riêng. Một số trong đó tương tự với các thuộc tính CSS dành cho HTML.
Thử thách
Hãy thay đổi stylesheet để tất cả cánh hoa bên trong đều chuyển sang màu hồng khi con trỏ chuột nằm trên bất kỳ một trong số chúng, mà không thay đổi cách các cánh hoa bên ngoài hoạt động.
Nhấp vào đây để xem lời giải
Di chuyển vị trí của pseudo-class :hover từ một cánh hoa cụ thể sang tất cả cánh hoa:
#inner-petals {
--segment-fill-fill-hover: pink;
}
/* Non-standard way for some older browsers */
#inner-petals:hover .segment-fill {
fill: pink;
stroke: none;
}
Cấu trúc đơn giản hóa
Cấu trúc SVG ở trên có thể được viết ngắn gọn hơn nhiều bằng cách tham chiếu các phần riêng lẻ của bông hoa thông qua các phần tử <use>. Hành vi này đã được chuẩn hóa, mặc dù hiện tại chỉ có một vài trình duyệt hỗ trợ pseudo-class :hover và các bộ chọn CSS phức tạp hơn trên các phần tử được tham chiếu qua phần tử <use>. Hiện có một số thảo luận về các quy tắc áp dụng cho những phần tử được tham chiếu như vậy.
Xem bên dưới để biết cấu trúc khi đó trông như thế nào.
<svg
width="600px"
height="600px"
viewBox="-300 -300 600 600"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<link
xmlns="http://www.w3.org/1999/xhtml"
rel="stylesheet"
href="style8.css"
type="text/css" />
<title>SVG demonstration</title>
<desc>Mozilla CSS Getting Started - SVG demonstration</desc>
<defs>
<g id="segment" class="segment">
<path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z" />
<path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10" />
</g>
<g id="quadrant">
<use href="#segment" />
<use href="#segment" transform="rotate(18)" />
<use href="#segment" transform="rotate(36)" />
<use href="#segment" transform="rotate(54)" />
<use href="#segment" transform="rotate(72)" />
</g>
<g id="petals">
<use href="#quadrant" />
<use href="#quadrant" transform="rotate(90)" />
<use href="#quadrant" transform="rotate(180)" />
<use href="#quadrant" transform="rotate(270)" />
</g>
<radialGradient
id="fade"
cx="0"
cy="0"
r="200"
gradientUnits="userSpaceOnUse">
<stop id="fade-stop-1" offset="33%" />
<stop id="fade-stop-2" offset="95%" />
</radialGradient>
</defs>
<text id="heading" x="-280" y="-270">SVG demonstration</text>
<text id="caption" x="-280" y="-250">
Move your mouse pointer over the flower.
</text>
<g id="flower">
<circle
id="overlay"
cx="0"
cy="0"
r="200"
stroke="none"
fill="url(#fade)" />
<use id="outer-petals" href="#petals" />
<use id="inner-petals" href="#petals" transform="rotate(9) scale(0.33)" />
</g>
</svg>
Tiếp theo là gì?
Trong minh họa này, trình duyệt có hỗ trợ SVG của bạn đã biết cách hiển thị các phần tử SVG. Stylesheet chỉ điều chỉnh việc hiển thị theo một số cách nhất định. Điều này cũng đúng với tài liệu HTML. Nhưng bạn có thể dùng CSS cho các tài liệu XML mục đích chung, nơi không có cách hiển thị phần tử nào được định nghĩa sẵn. Trang tiếp theo minh họa điều này: Giới thiệu XML