{"id":115,"date":"2024-06-02T06:37:45","date_gmt":"2024-06-02T06:37:45","guid":{"rendered":"https:\/\/webaffair.net\/blog\/?p=115"},"modified":"2024-06-02T06:45:52","modified_gmt":"2024-06-02T06:45:52","slug":"using-svg-filters-in-css","status":"publish","type":"post","link":"https:\/\/webaffair.net\/blog\/code\/basics\/using-svg-filters-in-css\/","title":{"rendered":"Using SVG Filters in CSS"},"content":{"rendered":"\n<p>Firstly, you&#8217;ll need the svg itself. <\/p>\n\n\n\n<pre class=\"wp-block-code html\"><code>&lt;svg style=\"height:0; overflow:hidden;\"&gt;\n&lt;defs&gt;\n  &lt;filter id=\"wavy2\"&gt;\n    &lt;feTurbulence x=\"0\" y=\"0\" baseFrequency=\"0.02\" numOctaves=\"5\" seed=\"1\"&gt;&lt;\/feTurbulence&gt;\n    &lt;feDisplacementMap in=\"SourceGraphic\" scale=\"20\"&gt;&lt;\/feDisplacementMap&gt;\n  &lt;\/filter&gt;\n  &lt;filter id=\"goo\"&gt;&lt;feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"8\" result=\"blur\"&gt;&lt;\/feGaussianBlur&gt;    \n    &lt;feColorMatrix in=\"blur\" mode=\"matrix\" values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9\" result=\"goo\"&gt;&lt;\/feColorMatrix&gt;\n    &lt;feComposite in=\"SourceGraphic\" in2=\"goo\" operator=\"atop\"&gt;&lt;\/feComposite&gt;\n  &lt;\/filter&gt;\n&lt;\/defs&gt;\n&lt;\/svg&gt;<\/code><\/pre>\n\n\n\n<p>Three things to note:<\/p>\n\n\n\n<p>1: Like empty images, empty svgs still take up some minimum space by default. If you&#8217;re borrowing a filter from an svg image that you&#8217;re actually using, that&#8217;s not an issue. If you&#8217;re just using the svg for filters, the svg itself needs to be hidden but still part of the page. You can do this by making it take up 0px rather than using display:hidden;<\/p>\n\n\n\n<pre class=\"wp-block-code html\"><code>&lt;svg style=\"height:0; overflow:hidden;\"&gt;<\/code><\/pre>\n\n\n\n<p>2: If you want to use multiple filters, you can include them all in the &lt;defs&gt; area of a single &lt;svg&gt;, I find this just helps keeps my code organized.<\/p>\n\n\n\n<p>3: Each &lt;filter&gt; tag needs a completely unique id. (Remember that there should never be more than one element on a page using the same id; this becomes critical any time you&#8217;re referring to that id with anything except css.)<\/p>\n\n\n\n<pre class=\"wp-block-code html\"><code>&lt;filter id=\"wavy2\"&gt;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">On to the CSS<\/h2>\n\n\n\n<p>You can now apply the filter in your style sheet with the same filter: attribute as the built-in filters:<\/p>\n\n\n\n<pre class=\"wp-block-code css\"><code>.wavy2 {\n    filter: url(#wavy2);\n}<\/code><\/pre>\n\n\n\n<p>Two things to note here:<\/p>\n\n\n\n<p>1: There can&#8217;t be &#8221; around the filter id; that trips me up sometimes since image url() do take quotes around them.<\/p>\n\n\n\n<p>2: Filters apply to the entire element including contents, and unlike transformations, can&#8217;t be undone by applying contradictory styles to a child element.<\/p>\n\n\n\n<p>If you want to apply the filter only to the background, you will need to have the background (and therefore the filter) separated from the content and positioned behind it, so that the other child elements aren&#8217;t affected. You could use a placeholder element of some sort, but :before works just fine:<\/p>\n\n\n\n<pre class=\"wp-block-code css\"><code>.torn-parchment, .torn-parchment &gt; * {\n    position: relative;\n}\n.torn-parchment::before {\n    box-shadow: 2px 3px 10px var(--subtle), 0 0 125px #8f5922 inset;\n    background: #fffef0 var(--parchment-texture-image);\n}\n.torn-parchment::before {\n    content: '';\n    display: block;\n    position: absolute !important;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    filter: url(#wavy2);\n}<\/code><\/pre>\n\n\n\n<p>The position:relative on the element is needed on the parent to constrain the absolutely positioned element, and on the child elements to bring those into the same stacking context so they don&#8217;t get hidden behind the background. If you are already using :before for something else, you could do exactly the same with :after instead, but in that case you&#8217;ll also need to add some z-indexes to bring the contents up in front of the background.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"229\" src=\"https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-1024x229.png\" alt=\"No filter vs. filtered element vs. filtered background\" class=\"wp-image-116\" srcset=\"https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-1024x229.png 1024w, https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-300x67.png 300w, https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-768x172.png 768w, https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-1536x344.png 1536w, https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM-1568x351.png 1568w, https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-05-29-at-5.21.25-PM.png 1982w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Firstly, you&#8217;ll need the svg itself. Three things to note: 1: Like empty images, empty svgs still take up some minimum space by default. If you&#8217;re borrowing a filter from an svg image that you&#8217;re actually using, that&#8217;s not an issue. If you&#8217;re just using the svg for filters, the svg itself needs to be&#8230; <a class=\"read-more\" href=\"https:\/\/webaffair.net\/blog\/code\/basics\/using-svg-filters-in-css\/\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":118,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[21],"tags":[18],"class_list":["post-115","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-basics","tag-css"],"jetpack_featured_media_url":"https:\/\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/filter2.png","jetpack-related-posts":[{"id":9,"url":"https:\/\/webaffair.net\/blog\/code\/basics\/funky-cursor-colours\/","url_meta":{"origin":115,"position":0},"title":"Changing the Colors of Input Elements","author":"Jay","date":"September 16, 2021","format":false,"excerpt":"Ever been on a forum site with a really nice dark theme, but then you go to make a post, and are presented with a large blindingly white text area to type in? Maybe with tiny, hard to read font? Of course you have. But this is a 100% fixable\u2026","rel":"","context":"In &quot;Basics&quot;","block_context":{"text":"Basics","link":"https:\/\/webaffair.net\/blog\/category\/code\/basics\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":317,"url":"https:\/\/webaffair.net\/blog\/code\/basics\/introduction-to-browser-development-tools\/","url_meta":{"origin":115,"position":1},"title":"Introduction to Browser Development Tools","author":"Jay","date":"December 18, 2025","format":false,"excerpt":"All modern desktop browsers now have integrated browser tools, however, there are subtle (and sometimes less subtle) differences between each. I find that Firefox has the best overall, though I do switch to Chrome for some specific debugging tasks. I personally only use Edge or Safari when trying to isolate\u2026","rel":"","context":"In &quot;Basics&quot;","block_context":{"text":"Basics","link":"https:\/\/webaffair.net\/blog\/category\/code\/basics\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2025\/12\/DevToolsSettingsFirefox-1-scaled.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":127,"url":"https:\/\/webaffair.net\/blog\/portfolio\/current\/learn-css-discord-activity-game\/","url_meta":{"origin":115,"position":2},"title":"Learn CSS Discord Activity Game","author":"Jay","date":"June 7, 2024","format":false,"excerpt":"I'll name it something cool eventually, hopefully. Bored and unable to sleep one day, I decided: what the heck, I want to figure out this discord app\/activity thing, and I need to learn REACT, and I've somehow acquired this group of people who are looking at me to explain web\u2026","rel":"","context":"In &quot;Current Projects&quot;","block_context":{"text":"Current Projects","link":"https:\/\/webaffair.net\/blog\/category\/portfolio\/current\/"},"img":{"alt_text":"Screenshot of the game","src":"https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/webaffair.net\/blog\/wp-content\/uploads\/2024\/06\/Screen-Shot-2024-06-04-at-1.26.33-AM.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":49,"url":"https:\/\/webaffair.net\/blog\/code\/snippets\/my-favourite-text-gradients\/","url_meta":{"origin":115,"position":3},"title":"My Favourite Text Gradients","author":"Jay","date":"September 26, 2021","format":false,"excerpt":"Note: I am using -webkit prefixed styles for all three relevant rules to ensure that only browsers that implement all three will load the background gradient at all. I could use a proper polyfill and\/or @supports, but honestly this creates more readable code. Non-webkit browsers have started using webkit prefixes\u2026","rel":"","context":"In &quot;Snippets and Notes&quot;","block_context":{"text":"Snippets and Notes","link":"https:\/\/webaffair.net\/blog\/category\/code\/snippets\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6,"url":"https:\/\/webaffair.net\/blog\/code\/snippets\/data-binding-updates-and-sqldatasource\/","url_meta":{"origin":115,"position":4},"title":"Data Binding, Updates, and SQLDataSource","author":"Jay","date":"September 16, 2021","format":false,"excerpt":"Random Things to remember: SQLDataSource won't bind parameters properly if you don't specify a type, but the GUI data source setup window doesn't guess nor prompt you to provide them. It's under 'Advanced'; or go into the code and add them.GridView will automatically add anything with 'id' in the field\u2026","rel":"","context":"In &quot;Snippets and Notes&quot;","block_context":{"text":"Snippets and Notes","link":"https:\/\/webaffair.net\/blog\/category\/code\/snippets\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":16,"url":"https:\/\/webaffair.net\/blog\/code\/snippets\/automatically-generate-google-fonts-link\/","url_meta":{"origin":115,"position":5},"title":"Automatically generate Google Fonts link.","author":"Jay","date":"September 17, 2021","format":false,"excerpt":"Useful if you are making a customizable skin, or if you allow users to set font preferences in their account settings. Of course, the basic way you include google fonts on your page is like this: HTML (preconnects are technically optional): <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"> <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin> <link href=\"FONT\u2026","rel":"","context":"In &quot;Snippets and Notes&quot;","block_context":{"text":"Snippets and Notes","link":"https:\/\/webaffair.net\/blog\/category\/code\/snippets\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/posts\/115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/comments?post=115"}],"version-history":[{"count":3,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/posts\/115\/revisions"}],"predecessor-version":[{"id":120,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/posts\/115\/revisions\/120"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/media\/118"}],"wp:attachment":[{"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/media?parent=115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/categories?post=115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webaffair.net\/blog\/wp-json\/wp\/v2\/tags?post=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}