{"id":333618,"date":"2021-02-08T13:07:56","date_gmt":"2021-02-08T21:07:56","guid":{"rendered":"https:\/\/css-tricks.com\/?p=333618"},"modified":"2021-02-08T13:07:59","modified_gmt":"2021-02-08T21:07:59","slug":"svg-within-css","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/svg-within-css\/","title":{"rendered":"SVG within CSS"},"content":{"rendered":"\n

Stefan Judis has a “Today I Learned” (TIL) post explaining how SVGs filters can be inlined in CSS<\/a>. The idea is that CSS has the filter<\/a><\/code> property which supports some built-in functions, like grayscale(100%)<\/code> and stuff like that.<\/p>\n\n\n\n

But it can also point to a filter defined by SVG. So you could do filter: url(#my-custom-filter)<\/code> which is in some inline <svg><\/code> as <filter id=\"my-custom-filter\"><\/code>. It’s kinda funny to have to refer out to the HTML like that. A filter is such a visual thing that it makes sense to bring it into the CSS. That looks like this:<\/p>\n\n\n\n\n\n\n\n

img {\n  filter: url('data:image\/svg+xml,\\\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\\\n      <filter id=\"waves\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\" filterUnits=\"objectBoundingBox\" primitiveUnits=\"userSpaceOnUse\" color-interpolation-filters=\"linearRGB\">\\\n        <feTurbulence type=\"turbulence\" baseFrequency=\"0.01 0.01\" numOctaves=\"1\" seed=\"1\" stitchTiles=\"noStitch\" result=\"turbulence\" \/>\\\n        <feDisplacementMap in=\"SourceGraphic\" in2=\"turbulence\" scale=\"20\" xChannelSelector=\"G\" yChannelSelector=\"A\" result=\"displacementMap\" \/>\\\n      <\/filter>\\\n    <\/svg>#waves')\n  ;\n}<\/code><\/pre>\n\n\n\n

That’s Stefan’s turbulence filter example, something CSS alone definitely cannot do.<\/p>\n\n\n\n

Look at all those backslashes (\\<\/code>). Makes ya wish CSS had template literals, eh? Makes me nervous that a code formatter or minifier would choke on that, but I don’t actually know, maybe it would be fine. <\/p>\n\n\n\n

What’s nice is that the SVG remains fairly intact (readable and editable). So here you can edit the SVG filter in the CSS and have a play:<\/p>\n\n\n\n