20

background

I visited CodePen today and saw such a very interesting effect:

CodePen Demo -- Material Design Menu By Bennett Feely

This effect still has some points worth discussing and learning, let's take a look at it together.

How to achieve such a similar effect?

First of all, think about it, if you were to achieve the above effects, what would you do?

Here I briefly list some possible solutions:

  1. Shadow box-shadow
  2. Radial-gradient
  3. Scale transform: scale()

Quickly go through them one by one.

Use box-shadow to achieve

If you use box-shadow , the code is roughly as follows:

<div class="g-container">
    <div class="g-item"></div>
</div>
.g-container {
    position: relative;
    width: 400px;
    height: 300px;
    overflow: hidden;
}

.g-item {
    position: absolute;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: #fff;
    top: 20px;
    left: 20px;
    box-shadow: 0 0 0 0 #fff;
    transition: box-shadow .3s linear;
    
    &:hover {
        box-shadow: 0 0 0 420px #fff;
    }
}

The core lies in:

  1. A mask overflow: hideen set on the outer layer
  2. When the inner element hover, implement a change from box-shadow: 0 0 0 0 #fff to box-shadow: 0 0 0 420px #fff

The effect is as follows:

The overall animation is simulated, but there are two most fatal problems:

  1. When our mouse leaves the circle, the entire animation begins to reverse, and the white area begins to disappear. If we want to perform button operations, it cannot be completed.
  2. The elements hidden in the rectangle after the animation are expanded are not easy to place

Therefore, box-shadow looks good, but can only give up. The code of the above Demo - CodePen Demo - box-shadow zoom in animation

Use gradient radial-gradient to achieve

Below we use the radial gradient radial-gradient plus CSS @property to restore the above effect:

<div class="g-container"></div>
@property --size {
  syntax: '<length>';
  inherits: false;
  initial-value: 24px;
}

.g-container {
    position: relative;
    width: 400px;
    height: 300px;
    overflow: hidden;
    background: radial-gradient(circle at 44px 44px, #fff 0, #fff var(--size), transparent var(--size), transparent 0);
    transition: --size .3s linear;
    
    &:hover {
        --size: 450px;
    }
}

By controlling the animation effect of the radial gradient, when hovering, the original small circle background becomes a big circle background. The effect is as follows:

emmm, the effect is indeed restored, and the problem is also fatal:

  1. Because it is a background change, the mouse does not need to hover to the small circle, only need to enter the scope of the div, the animation will start, which is obviously wrong
  2. box-shadow , the DOM of the navigation element hidden under the white is not easy to place

The code of the above Demo - CodePen Demo - radial-gradient zoom in animation

emmm, there is another method, by zooming transform: scale() , there will be some problems, so I will not continue to expand here.

So here, if you want to achieve the above effects, the core lies in:

  1. The mouse must hover to the circle to start the animation, and the mouse can move freely within the expanded range, and the animation effect will not be retracted
  2. After the animation is expanded, the placement of the DOM inside should not be too troublesome. It is best to control the display and hiding of the content without the help of Javascript.

Use clip-path to achieve dynamic area clipping

So, here, we actually need a dynamic area crop .

In this article of - 161baabc1203d4 how to achieve overflow: hidden without using overflow: hidden? , introduces several ways of clipping elements in CSS, and among them, the most suitable for this effect is - clip-path .

With clip-path , the function of dynamic cropping can be realized very well, and the code is also very simple:

<div class="g-container"></div>
.g-container {
    position: relative;
    width: 400px;
    height: 300px;
    overflow: hidden;
    transition: clip-path .3s linear;
    clip-path: circle(20px at 44px 44px);
    background: #fff;
    
    &:hover {
        clip-path: circle(460px at 44px 44px);
    }
}

We only need to use clip-path . At the very beginning, cut a rectangular div with clip-path: circle(20px at 44px 44px) into a circle. When hovering, expand the radius of the cutting circle to the entire rectangle.

The effect is as follows:

In this way, we can perfectly achieve the effect of the title map, and the built-in DOM elements can be directly written into this div.

<div class="g-container">
    <ul>
        <li>11111</li>
        <li>22222</li>
        <li>33333</li>
        <li>44444</li>
    </ul>
</div>

The effect is as follows:

CodePen Demo -- clip-path zoom in animation

A very interesting technique, using clip-path to achieve dynamic area clipping, I hope you can master it.

At last

Okay, this concludes this article, I hope this article is helpful to you :)

Want to get the most interesting CSS information, don’t miss my account - 161baabc1205b3 iCSS front-end interesting 161baabc1205b7 😄

More wonderful CSS technical articles are summarized in my Github - iCSS , which will be updated continuously. Welcome to click a star to subscribe to the collection.

If you have any questions or suggestions, you can communicate more, original articles, limited writing style, and lack of knowledge. If there are any irregularities in the article, please let me know.


chokcoco
12.3k 声望18.5k 粉丝