Sticky effect

Original author: Lucas Bebber
  • Transfer
Just recently, Chris wrote about “The Effect of Drip Transformation in CSS” . The effect is really cool and the technique itself is implemented in a smart way, but this approach through ordinary CSS filters has certain drawbacks: you cannot use opacity, add content inside drops, problems with background colors.

In recent days, I have experimented quite a lot with SVG filters and noticed that they can be used to solve the above problems in CSS implementations. Take a look at the sticky menu I made for a demo:

CodePen



SVG Filters 101

SVG filters are a very powerful thing. But this is a very extensive topic, so we will only talk about the most necessary for solving our problem.

Despite the name, we can apply these filters to DOM elements using CSS and this will work in most browsers .

Classic syntax for describing filters:

      ...          
      
      ...
    
    ...
  


Applying a filter to a DOM element:
.selector {
  filter: url('#name-of-your-filter-here');
  /* you can also load filters from external SVGs this way: */
  filter: url('filters.svg#name-of-your-other-filter-here');
}


You may need vendor prefixes for the filter property.

Element contains one or more of filter noticing (filter primitives), which perform functions blur, color transform, shading. A complete list of these primitives is here .

Take a look at a couple of examples:

CodePen




This simple filter performs a three-pixel blur on an element. It is important to pay attention to the in = attribute "SourceGraphic" . In in defines what exactly the filter will be applied to. The SourceGraphic value returns the original item. Thus, we indicate that blurring should occur for the original graphic. Everything is quite simple.

Let's look at an example a bit more complicated: drop shadow. It clearly shows how the filter chain works by noticing together:

CodePen




Take a look at the result and in attributes. In result , the name of the result is indicated using the filter, which subsequently gives us the opportunity to filter this result, in contrast to the original graphic object. That is, in this example, we blurred the element, darkened the specifically blurred object, and then changed the position for the blurred and darkened objects.

Pay attention to the mark. It contains two attributes to indicate the area of application: in the value SourceGraphic and in2 the value shadow.

Now that we understand the basic principles of SVG filters, let's figure out how to make a sticky effect.

Fix the already completed

The basic technique is described here . Let me remind you that the idea is to blur and contrast elements at the same time. And everything will work in a magical way.
CodePen


However, we still have:

  1. Problems in working with different colors.
  2. Blur is done for the whole element, including the content.
  3. Inability to use opacity.


All this does not allow to apply this trick in a real project.

With the help of SVG filters we can realize what was not possible with CSS: we can increase the contrast only for the alpha channel, without changing the color; and with SourceGraphic we can apply blur only for the element itself, without changing the content. Also, since we work with the alpha channel, it should not only be transparent, a transparent background is necessary, be careful with this.

Main code:



Briefly about what we did:

  1. First, we blurred 10 pixels and assign a name to this result.
  2. Then, for the resulting result, we applied a color matrix filter to increase the contrast of the alpha channel.
  3. And after that we inserted the original graphic object into this effect.


About Color Matrices

If you have not used the color matrix filter before, then you need to explain how it works. Imagine a table of four rows and five columns. It will look as follows.

   | R | G | B | A | +
---|-------------------
 R | 1 | 0 | 0 | 0 | 0
---|-------------------
 G | 0 | 1 | 0 | 0 | 0
---|-------------------
 B | 0 | 0 | 1 | 0 | 0
---|-------------------
 A | 0 | 0 | 0 | 1 | 0
---|-------------------


Each line is a channel (red, green, blue and alpha) and uses to set the channel value. The first four columns are also channels. The number in the cell is the channel multiplier in the column for the channel in the row. For example, 0.5 in row R and column G will add the current value Green * 0.5 to the red channel. The last column is no longer a channel and is used to add or subtract. The numbers indicated in it are multiplied by 255 and assigned to the corresponding channel.

It’s a long story to explain, but actually using the filter is extremely simple. In our case, we only change the alpha channel value and our matrix will look like this:

   | R | G | B | A | +
---|-------------------
 R | 1 | 0 | 0 | 0 | 0
---|-------------------
 G | 0 | 1 | 0 | 0 | 0
---|-------------------
 B | 0 | 0 | 1 | 0 | 0
---|-------------------
 A | 0 | 0 | 0 |18 |-7
---|-------------------


RGB channels remain unchanged. The alpha channel value is multiplied by 18, and then 7 * 255 is subtracted from it, effectively increasing the contrast of transparency alone. All values ​​can be customized to your needs.

To apply this matrix to the feColorMatrix filter, we must write all the values ​​in a specific order:

values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7"


Demo

As a result, the effect conceived by us works. Example:

CodePen


You can customize everything you need, add a shadow, change the color of each element, everything is at your disposal!

To summarize

  • The filter should apply to the container with the elements, and not to the elements themselves.
  • Due to the pulling effect, the container should be a slightly larger area than the contents. Otherwise, you may get similar defects at the edges:
    image
  • In order to apply this filter for example for rectangles, we must use a slightly more sophisticated method. Instead of drawing the original object over the sticky effect, we should apply the feComposite filter with the atop attribute in order to hide everything that goes beyond the bounds:

    CodePen

    You can use this approach not only to create a sticky effect, but also in simpler cases, for example, to round the corners of several rectangles.
  • This filter, although light in volume, can be very resource intensive if applied to large areas. So be careful.


Support

SVG filters have good support, but not all browsers support their application to DOM elements, in particular Safari. However, they do work, at least on Firefox and Chrome, even the Android version. But the filter noticeably spoils the picture if not supported. If you need to use it, then use it for SVG elements instead of DOM elements.

Also popular now: