theread.me/site/css-filters/index.html

259 lines
13 KiB
HTML
Raw Normal View History

2022-07-06 17:05:11 +00:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Filters are awesome!</title>
<meta name="description" content="Ive been working on the CSS Filter Editor widget in Firefox Developer Tools for a couple of weeks, thanks to Patrick Brosset for mentoring me and Tim Nguyen...">
<link href="https://fonts.googleapis.com/css?family=Secular+One|Nunito|Mononoki" rel="stylesheet">
<link rel="stylesheet" href="/css/main.css">
<link rel="canonical" href="http://localhost:4000/css-filters/">
<link rel="alternate" type="application/rss+xml" title="mahdi" href="http://localhost:4000/feed.xml" />
<!--<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>-->
<script>
var channel = new BroadcastChannel('egg');
channel.addEventListener('message', message => {
alert('Got a message from the other tab:\n' + message.data);
});
</script>
</head>
<body>
<header class="site-header">
<h1>
<a class='site-title' href='/'>
mahdi
</a>
</h1>
<nav>
<p>
<a href="/snippets">snippets</a>
<a href="/art">pictures</a>
</p>
<!--<p class='categories'>-->
<!---->
<!---->
<!--<a href="">art</a>-->
<!---->
<!---->
<!---->
<!---->
<!--</p>-->
<p>
<a href='mailto:mdibaiee@pm.me'>email</a>
<a href='https://git.mahdi.blog/mahdi'>git</a>
<a href='https://www.librarything.com/profile/mdibaiee'>librarything</a>
<a href="http://localhost:4000/feed.xml">feed</a>
</p>
</nav>
</header>
<div class="page-content">
<div class="wrapper">
<h1 class="page-heading"></h1>
<div class='post lang-en'>
<div class="post-header">
<h1 class="post-title"><p>CSS Filters are awesome!</p>
</h1>
<p class="post-meta">
<span>Mar 28, 2015</span>
<span>Reading time: 6 minutes</span>
</p>
</div>
<article class="post-content">
<p>Ive been working on the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1055181">CSS Filter Editor widget</a> in Firefox Developer Tools for a couple of weeks, thanks to <a href="https://medium.com/@patrickbrosset">Patrick Brosset</a> for mentoring me and <a href="https://github.com/nt1m">Tim Nguyen</a> for his great contributions.</p>
<p>Here is an <a href="http://mdibaiee.github.io/CSS-Filter-Tooltip/">online version</a> to use as a playground. This version is modified to be cross-browser and therefore is a little different from the original widget used in Firefox.</p>
<p>You can also use <a href="http://davidwalsh.name/demo/css-filters.php">David Walshs demo</a>, although it doesnt have as much flexibility.</p>
<p>CSS Filters are supported by most modern browsers (<a href="http://caniuse.com/#feat=css-filters">Can I Use CSS Filters</a>), if your browser doesnt support this, please change your browser (I recommend <a href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a>).</p>
<p>I dont like long-bla-bla-articles, so lets get to it.</p>
<h1 id="introduction">Introduction</h1>
<p>CSS Filters introduce a few useful effects and some image adjusting functions, namely blur, drop-shadow, contrast, brightness, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/filter">and a few others</a> which can be really useful if used properly.</p>
<p>A simple demo showing blur, contrast and brightness combined (hover over image):</p>
<iframe width="100%" height="300" src="//jsfiddle.net/mdibaiee/zLmyhe7t/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>I group filters by the type of value they take, lets explain them briefly:</p>
<h2 id="length">Length</h2>
<p>These filters accept a length value (px, em, cm, <a href="http://www.w3.org/Style/Examples/007/units">etc</a>). blur is the only member of this family.</p>
<h2 id="percentage">Percentage</h2>
<p>These filters accept percentage values, but if you omit the percentage sign, the value is multiplied by 100, e.g. <code class="language-plaintext highlighter-rouge">contrast(2)</code> is another way of writing <code class="language-plaintext highlighter-rouge">contrast(200%)</code>. Negative values have the same effect as zero.</p>
<p>Most filters explain themselves, Im not going to repeat `Adjusts ${x} level` like a parrot.</p>
<ul>
<li>brightness</li>
<li>contrast</li>
<li>grayscale</li>
<li>invert</li>
<li>opacity</li>
<li>saturate</li>
<li>sepia</li>
</ul>
<h3 id="invert">invert</h3>
<p>I first understood how cool this filter can be after I saw Tim Nguyen using this in theme switching. Yeah you cant invert everything and “Yay, I have a new theme”, but you can use invert on some elements and it works flawlessly, believe me.</p>
<iframe width="100%" height="100" src="//jsfiddle.net/mdibaiee/373dnby8/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h3 id="opacity">opacity</h3>
<p>You might wonder why do we have this function, as we already have an opacity property in CSS, thats because the opacity property is not hardware accelerated, but the filter property is hardware accelerated in most browsers, which includes this function.</p>
<h2 id="angle">Angle</h2>
<p>hue-rotate is the only function to accept an angle value (degree / radian).</p>
<p>###hue-rotate
If youre familiar with <a href="https://en.wikipedia.org/wiki/Hue">Hue</a> you probably know that its measured by angles. The hue-rotate rotates the hue circle of an image relative to its current hue value (360 and 0 have the same results).</p>
<iframe width="100%" height="300" src="//jsfiddle.net/mdibaiee/smk922fh/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h2 id="special">Special</h2>
<p>These filters dont fit in any of the groups above, they have special/mixed values.</p>
<h3 id="drop-shadow">drop-shadow</h3>
<p>The drop-shadow filter accepts a <em>shadow-list</em>, four length values, and one color. box-shadow and text-shadow also accept shadow lists.</p>
<p>Youre probably familiar with shadow lists already: <code class="language-plaintext highlighter-rouge">drop-shadow(x y radius spread color)</code>. Unfortunaly spread doesnt work in either Chrome or Firefox as of this writing — It is treated as an error.</p>
<p>drop-shadow is pretty cool, as it doensnt have the limitations of box-shadow and text-shadow. box-shadow applies a shadow to the outer shape, but drop-shadow applies a shadow to elements independant to their shape, they might be triangles, PNGs with transparent background or just anything.</p>
<p>drop-shadow clones the elements image, moves it to the offset defined, applies blur and changes its color, putting it under the original element. Couldnt do it better:</p>
<p><img src="/img/dropshadow.gif" alt="drop-shadow explained" /></p>
<p>Here is an example, a PNG image with transparent background and a CSS triangle made using the border hack:</p>
<iframe width="100%" height="150" src="//jsfiddle.net/mdibaiee/z077vbs0/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h3 id="url">url</h3>
<p>With the url function we have the power of CSS and SVG Filters in one place. You can reference an SVG element by linking to it with a hash of the filter elements ID:</p>
<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">filter</span><span class="o">:</span> <span class="nt">url</span><span class="o">(/</span><span class="nt">example</span><span class="nc">.svg</span><span class="nf">#filter</span><span class="o">)</span></code></pre></figure>
<p>If you want to know more about SVG Filters, I recommend <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Filter_effects">MDNs tutorial on SVG Filters</a>.</p>
<h3 id="custom">Custom</h3>
<p>Now those filters are pretty cool, but what if I told you this is [going to be] done with CSS?</p>
<p><img src="/img/map.jpg" alt="Map Folding with Custom CSS Filters" /></p>
<p><span class="image-caption">Source: http://www.adobe.com/devnet/archive/html5/articles/css-shaders.html</span></p>
<p>Custom Filters allows usage of vertex and fragment shaders which run directly in the GPU. Custom filters specs is subject to change, so theres no implementation yet. For more info on this topic follow the links below:</p>
<ul>
<li><a href="http://alteredqualia.com/css-shaders/article/#shaders">Getting started with CSS custom filters</a></li>
<li><a href="http://www.adobe.com/devnet/archive/html5/articles/css-shaders.html">Introducing CSS shaders: Cinematic effects for the web</a></li>
<li><a href="http://dev.w3.org/fxtf/custom/">CSS shaders specifications</a></li>
</ul>
<h1 id="gotchas">Gotchas</h1>
<p>You now have a basic understanding of filters, good. Here are a few gotchas youd better know.</p>
<h2 id="order-matters">Order matters</h2>
<p>The order in which filters are applied matters. Take this example:</p>
<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">filter</span><span class="o">:</span> <span class="nt">blur</span><span class="o">(</span><span class="err">10</span><span class="nt">px</span><span class="o">)</span> <span class="nt">contrast</span><span class="o">(</span><span class="err">2</span><span class="o">);</span></code></pre></figure>
<p>Hey, browser, please blur the element, then double the contrast of the blurred element. (blurred parts have their contrast affected)</p>
<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">filter</span><span class="o">:</span> <span class="nt">contrast</span><span class="o">(</span><span class="err">2</span><span class="o">)</span> <span class="nt">blur</span><span class="o">(</span><span class="err">10</span><span class="nt">px</span><span class="o">);</span></code></pre></figure>
<p>Hey browser, please double the contrast of my element, then blur it out. (high contrast image is blurred normally)</p>
<p>Here is the actual comparison:</p>
<iframe width="100%" height="300" src="//jsfiddle.net/mdibaiee/608yoqrx/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h2 id="inheritance">Inheritance</h2>
<p>Okay, you now know the order of filters matters, the filter property is not actually <em>inherited</em>, but when you apply a filter on a parent element, of course its children are affected too, but what if the children have their own css filters? Ah-ha! CSS properties are applied bottom-up, which means childrens filters are applied first.</p>
<iframe width="100%" height="300" src="//jsfiddle.net/mdibaiee/o40d7cs7/embedded/result,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h2 id="implementation">Implementation</h2>
<p>I said using the url function we have “the power of CSS and SVG filters in one place”, but the CSS filters are actually implemented using SVG filters! You know, the functions are actually referencing to an svg generated in the browser. Here is the list of <a href="http://www.w3.org/TR/filter-effects/#ShorthandEquivalents">CSS Filter equivalents</a>.</p>
<h1 id="go-wild">Go Wild</h1>
<p>You can use CSS Filter on <em>any</em> element, experiment different things; <code class="language-plaintext highlighter-rouge">&lt;video&gt;</code>, <code class="language-plaintext highlighter-rouge">&lt;canvas&gt;</code>, <code class="language-plaintext highlighter-rouge">&lt;iframe&gt;</code>, GIF images, etc.</p>
<p>My try (although I couldnt get the GIF and CSS animation to be in sync, know a solution? Leave a comment please):</p>
<iframe width="100%" height="300" src="//jsfiddle.net/mdibaiee/hjaL0ka3/embedded/result,css,js" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<hr />
<p>Thats it, you can subscribe to my <a href="http://localhost:4000/feed.xml">RSS</a> or follow me on <a href="https://twitter.com/">Twitter</a> to get more articles like this.</p>
<style>
#mahdi {
transition: filter 1s ease;
-webkit-transition: filter 1s ease;
}
#mahdi:hover {
filter: blur(3px);
-webkit-filter: blur(3px);
}
</style>
</article>
<div class="share-page">
Share in
<a href="https://twitter.com/intent/tweet?text=CSS Filters are awesome!&url=http://localhost:4000/css-filters/&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter">Twitter</a>
<a href="https://facebook.com/sharer.php?u=http://localhost:4000/css-filters/" rel="nofollow" target="_blank" title="Share on Facebook">Facebook</a>
<a href="https://plus.google.com/share?url=http://localhost:4000/css-filters/" rel="nofollow" target="_blank" title="Share on Google+">Google+</a>
</div>
<div id="commento"></div>
<script defer
src="//commento.mahdi.blog/js/commento.js">
</script>
<script src="/js/heading-links.js"></script>
</div>
</div>
</div>
</body>
</html>