오늘은 간단하게 반응하는 화살표 아이콘을 만들어 보자. 오늘 만들 아이콘은 transform-origin 속성과 transform 속성의 rotate 값을 이용하여 회전하는 아이콘을 만들어 볼 것이다. 해당 아이콘이 사용된 모습이 보고 싶다면, 하단의 링크를 참고해 보기 바란다.
우선 완성된 이미지를 살펴보자
위의 이미지에 보이듯이 평상시에는 '≡' 모양을 유지하다가 hover 기능에 의해 마우스를 인식하게 되면 아이콘의 각 막대가 회전하며 '↓' 모양으로 변화하는 것을 볼 수 있다.
아래의 링크에서는 측면에서 나타나는 사이드바 메뉴의 모션 맞추어 반응하는 아이콘이 사용되었다.
[HTML/CSS] 사이드바 메뉴 만들기 : 나타나는 2차 메뉴 만들기 feat. transform: translate
기본 마크업부터 살펴보자
<section>
<div></div>
<div></div>
<div></div>
</section>
변화하기 이전 아이콘의 막대 3개를 책임질 엘리먼트 3개와 이를 통제해 줄 부모 엘리먼트 1개만 있으면 아이콘을 만들기 위한 HTML 준비는 끝이다. 우선은 막대 3개를 만들어 보자. 이때 우리는 position 속성의 값이 absolute일 때, 서로 영향을 주지 않는다는 특징을 이용하여 아이콘의 형태를 자유롭게 조작하기 위해 position 속성을 이용하여 막대를 만들 것이다.
/* 박스 안에 막대 가두기 */
section {
position: relative;
width: 300px;
height: 300px;
border: 30px solid red;
}
section > div {
position: absolute;
width: 100%;
height: 20%;
background-color: black;
}
section > div:nth-of-type(2) {
top: 40%;
}
section > div:nth-of-type(3) {
top: 80%;
}
위의 속성들을 적용해 보자
반응하기 이전의 아이콘 형태가 만들어졌다. 여기서 우리는 두 번째 막대와 세 번째 막대를 이용하여 transform-origin 속성의 이해와 transform 속성의 rotate 값에 대해 알아보자.
/* transform-origin: X% Y% */
section:hover > div:nth-of-type(2) {
transform-origin: left bottom; /* transform-origin: 0% 100% */
transform: rotate(45deg);
}
section:hover > div:nth-of-type(3) {
transform-origin: right bottom; /* transform-origin: 100% 100% */
transform: rotate(-45deg);
}
위의 코드에서 transform-origin 속성에는 2개의 값을 준다. 여기에 % 의 형태로 변수를 지정하게 된다면 순서대로 X축과 Y축의 값을 지정하게 된다. X축의 경우 0%에 가까울수록 left 값에 근접하게 되고, Y축의 경우 0%에 가까울수록 top 값에 근접하게 되며 각각의 축의 50%는 center로 표현할 수 있다.
위의 속성들을 적용해 보자
우리가 지정한 값에 따라 두 번째 막대는 좌측 하단을 기준으로, 세 번째 막대는 우측 하단을 기준으로 무사히 회전된 모습을 볼 수 있다. 이때, 두 번째 막대는 rotate 값으로 양수를 주며 시계방향으로 45도 회전하였으며, 세 번째 막대는 rotate 값으로 음수가 주어져 반시계 방향으로 회전된 것을 확인할 수 있었다. 추가로 rotate에서 각도는 Degree의 약자인 deg를 사용하게 된다.
여기서 화살표의 아이콘 모양을 위해 세 번째 막대의 위치와 각각의 길이를 추가로 조절해 보자.
section:hover > div:nth-of-type(2) {
transform-origin: left bottom; /* transform-origin: 0% 100% */
transform: rotate(45deg);
width: 70.5%
}
section:hover > div:nth-of-type(3) {
transform-origin: right bottom; /* transform-origin: 100% 100% */
transform: rotate(-45deg);
top: 40%;
width: 70.5%;
}
위의 속성들을 적용해 보자
단순히 막대의 길이와 높낮이를 조절했을 뿐인데, 이미지에 보이듯이 세 번째 막대의 위치가 좌측으로 이동되는 이슈가 생긴 것을 볼 수 있다. 이는 absolute 값을 지닌 개체에 별도로 위칫값을 지정하지 않는다면 기본적으로 좌측 상단으로 이동하는 특징을 갖고 있기 때문이다. 이에 우리는 세 번째 막대에 위칫값을 지정할 필요가 있다.
section > div:nth-of-type(3) {
top: 80%;
right: 0; /* 우측 벽면으로 이동 */
}
위의 속성들을 적용해 보자
마지막으로 첫 번째 막대를 화살표의 기둥으로 만들어 주어야 한다. 우리는 자연스러운 변신을 위하여 첫 번째 막대는 회전하지 않고, 너비가 먼저 줄어든 다음 높이를 늘리는 방식으로 모션을 구현해 보자. 그러기 위해서 첫 번째 막대의 너비를 수동적으로 적용해 보겠다.
/* 첫 번째 막대의 길이를 수동적으로 전환 */
section > div:nth-of-type(1) {
width: auto;
left: 0;
right: 0;
}
/* left와 right의 변화에 따라 길이 조절 */
section:hover > div:nth-of-type(1) {
left: 40%;
right: 40%;
}
위의 속성들을 적용해 보자
다음으로 첫 번째 막대의 길이를 늘이기만 하면 화살표 아이콘이 만들어진다. 하지만 여기서 너비를 줄이는 동작과 높이를 늘리는 동작이 함께 작용하면 부자연스러운 모션이 연출되게 된다. 이를 transition 속성을 이용하여 모션에 딜레이를 주는 것으로 동작에 순서를 부여하게 된다면 우리가 목표로 하는 아이콘을 완성할 수 있게 된다.
section > div:nth-of-type(1) {
width: auto;
left: 0;
right: 0;
/* 커서를 인식하지 않을 때는 높이를 먼저 조절 후 너비 조절 */
transition: all 1s, left .5s .5s, right .5s .5s, height .5s 0s;
}
section:hover > div:nth-of-type(1) {
left: 40%;
right: 40%;
height: 100%;
/* 커서를 인식할 때는 너비를 먼저 조절 후 높이 조절 */
transition: all 1s, left .5s 0s, right .5s 0s, height .5s .5s;
}
위의 속성들을 적용해 보자
쨔쟌-! 여러 속성과 그에 맞는 값을 이용하여 변화하는 아이콘을 만들어 보았다. 이번 포스팅에서 다루어 본 속성들을 응용하여 더욱 다양한 종류와 방식의 아이콘을 만들어 보며 해당 속성들을 다루는 것에 익숙해지며 공부해야겠다는 결심을 다지며 이번 포스팅은 아래의 코드를 남기며 마치도록 하겠다.
◆ 함께 보면 좋은 글
위 단계들의 종합 CSS 코드를 남기며 이번 포스팅을 마친다.
section {
position: relative;
width: 300px;
height: 300px;
}
:root {
--rotate-icon: 0.5s;
}
section > div {
position: absolute;
width: 100%;
height: 20%;
background-color: black;
transition: all var(--rotate-icon);
}
section > div:nth-of-type(1) {
top: 0;
width: auto;
left: 0;
right: 0;
transition: all var(--rotate-icon), left calc(var(--rotate-icon) / 2) calc(var(--rotate-icon) / 2), right calc(var(--rotate-icon) / 2) calc(var(--rotate-icon) / 2), height calc(var(--rotate-icon) / 2) 0s;
}
section > div:nth-of-type(2) {
top: 40%;
transform-origin:bottom left;
}
section > div:nth-of-type(3) {
top: 80%;
left: auto;
right: 0;
transform-origin:bottom right;
}
section:hover > div:nth-of-type(2) {
transform:rotate(45deg);
width: 70.5%;
}
section:hover > div:nth-of-type(3) {
top: 40%;
transform:rotate(-45deg);
width: 70.5%;
}
section:hover > div:nth-of-type(1) {
left: 40%;
right: 40%;
height: 100%;
transition: all var(--rotate-icon), left calc(var(--rotate-icon) / 2) 0s, right calc(var(--rotate-icon) / 2) 0s, height calc(var(--rotate-icon) / 2) calc(var(--rotate-icon) / 2);
}
'웹 프로그래밍 > 프론트엔드' 카테고리의 다른 글
[HTML/CSS] 사이드바 메뉴 만들기 : 늘어나는 2차 메뉴 만들기 feat. overflow: hidden (0) | 2023.05.22 |
---|---|
[HTML/CSS] Position (absolute와 relative) & z-index를 활용해 보자 (0) | 2023.05.19 |
[HTML/CSS] 사이드바 메뉴 만들기 : 나타나는 2차 메뉴 만들기 feat. transform: translate (0) | 2023.05.16 |
[HTML/CSS] 드롭다운 메뉴 바 만들기 : 2차 메뉴 만들기 feat. position (0) | 2023.05.15 |
[HTML/CSS] 1차 메뉴 바 만들기 : inline-grid를 이용하자 (0) | 2023.05.14 |
댓글