본문 바로가기
css

애덤 아가일의 병든 마우스 아웃 CSS 호버 효과

by code-box 2022. 1. 10.
반응형

코드펜 피드를 뒤지며 눈사탕을 찾고 있었는데 아담 아가일이 만든 깔끔한 CSS 호버 효과를 발견하기 전에 첫 페이지를 지나칠 필요가 없었다.

경외심에 데모를 쳐다보느라 10분이나 걸렸나 봐 뭔가 앱 같은 느낌이 들어. 배경색이 왼쪽에서 미끄러져 들어와 오른쪽을 통해 빠져나간다는 점에서 문맥상 얼마나 정확한지 알 수 있을 것 같습니다. 마우스인, 마우스아웃의 상호작용에서 예상할 수 있는 바로 그런 행동입니다.

어찌됐든 새 펜을 태워서 다시 만드는 일을 하러 갔다. 그리고 이것은 매우 복잡한 것이 아니라 적절한 상쇄와 짝을 이루는 전환과 변환을 영리하게 사용하는 것입니다. 우아하다! 사실 마우스 아웃 부분이 어떻게 작동하는지 깨닫기까지 얼마나 걸렸는지 좀 당황스럽네요.

이게 내가 태클한 방법이야 사마귀 같은 거 말이야

"그것은 배경의 전환을 사용하는 것이라고 장담합니다.

 
That was my first thought. Define the background-color, set the `background-size` and `background-position`, then transition the `background-position`. That’s how I’ve seen that “growing” background color thing done in the past. I’ve done that myself on some projects, like this:
 
If I could do the same thing, only from left-to-right, then all that’s left is the mouse-out, right? Nope. The problem is there’s nothing that can really make the `background-position` transition from left-to-right to left-to-right. I could make it do one or the other, but not both.

대신에 변신을 하는 것일 수도 있다.

My next attempt was jump into transforms. The `transform` property provides a bunch of functions that can `transition` together for slightly more complex movement. For example, the `background` can “grow” or “shrink” by changing the element’s `scale()`. Or, in this case, just along the x-axis with `scaleX()`.
 
But like I mentioned, there isn’t a way to isolate the element’s `background` to do that. Going from `scaleX(0)` to `scaleX(1)` scales the entire element, so that basically squishes the link — content and all — down to nothing, then stretches it back out to its natural size which is a totally different effect. Plus, it means starting with `scaleX(0)` which hides the whole dang thing by default making it unusable.
But a pseudo-element could work! It doesn’t matter if that gets squished or hidden because it isn’t part of the actual content. Gotta put the `background` on that instead and position it directly under the link.
a {
    /* Keeps the pseudo-element contained to the element */
    position: relative;
}

a::before {
    background: #ff9800;
    content: "";
    inset: 0; /* Logical equivalent to physical offsets */
    position: absolute;
    transform: scaleX(0); /* Hide by default */
    z-index: -1; /* Ensures the link is stacked on top */
}
a {
    /* Keeps the pseudo-element contained to the element */
    position: relative;
}

a::before {
    background: #ff9800;
    content: "";
    inset: 0; /* Logical equivalent to physical offsets */
    position: absolute;
    transform: scaleX(0); /* Hide by default */
    z-index: -1; /* Ensures the link is stacked on top */
}

이제 호버에서 바뀌려면 ::before가 필요해요.

 
I knew I could make `::before` scale from `0` to `1` by chaining it to the link element’s `:hover` state.
a:hover::before {
    transform: scaleX(1)
}
a:hover::before {
    transform: scaleX(1)
}

좋아, 뭔가 알아냈어

 
 
Sprinkle a little `transition` fairy dust on it and things start to come to life.
a::before {
    background: #ff9800;
    content: "";
    inset: 0;
    position: absolute;
    transform: scaleX(0);
    transition: transform .5s ease-in-out;
    z-index: -1;
} 
a::before {
    background: #ff9800;
    content: "";
    inset: 0;
    position: absolute;
    transform: scaleX(0);
    transition: transform .5s ease-in-out;
    z-index: -1;
} 
 

"음, 과도기는 양방향으로 움직인다."

 

다시 말하지만, 여기가 내가 갇힌 곳이야. 왠지 모르게 머릿속이 자꾸 맴돌아요. 평소처럼, 나는 CSS-Tricks 연감에 가서 어떤 재산을 깜빡했는지 알아보려고 했다.

Ah, yes. That would be `transform-origin`. That allows me to set where the `transform` starts, which is not totally dissimilar from setting the `background-position` like I tried earlier. The `transform` could start from the left instead of its default `50% 50%` position.
a::before {
    background: #ff9800;
    content: "";
    inset: 0;
    position: absolute;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .5s ease-in-out;
    z-index: -1;
} 
a::before {
    background: #ff9800;
    content: "";
    inset: 0;
    position: absolute;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .5s ease-in-out;
    z-index: -1;
} 

네, 이렇게요

 
 
I was already transitioning `::before` to `scaleX(1)` on link hover. If I reversed the `transform-origin` from `left` to `right` at the same time, then mayyyybe the highlight goes out the opposite of how it came in when the mouse exits?
a:hover::before {
    transform: scaleX(1);
    transform-origin: right;
} 
a:hover::before {
    transform: scaleX(1);
    transform-origin: right;
} 
 
 
Whoops, backwards! Let’s swap the `left` and `right` values. 
 

멋있네 감동 고마워요, 아담!

댓글