📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[CSS] 가상 요소 ::before / ::after로 밑줄 넣기

문제

CSS만을 이용해서 위와 같은 결과물을 만들려고 한다. 이 결과물을 만드는 데 2가지 과정이 필요하다.

1) 목록에 밑줄을 만들어야 한다.

2) hover 값을 줘야 한다. (transform 사용)

 

이 게시물은 1번에 해당하는 과정을 설명하는 글로, 2번 과정은 따로 transform 속성 정리글에서 다루겠다.

먼저, 밑줄을 만드는 경우의 수는 많다. 해당 글씨가 들어간 태그에 border-bottom을 줘도 되고, li에 padding-bottom 값을 준 후 border-bottom을 줘도 된다. 메뉴에 어떤 태그를 썼냐에 따라 방법은 무수히 많다.

 

하지만, 위와 같이 주게 되면 부작용이 있다. border에도 1px처럼 크기가 있기 때문에, 위처럼 hover를 주는 경우 글씨가 갑자기 올라가는 경우가 생기게 된다. (글씨의 높이가 30px이라고 쳤을 때, border의 1px까지 더해지면 총 31px이 되기 때문에 위의 사진처럼 hover가 말끔하게 보이지 않고, 계단처럼 올라갔다 내려갔다하게 됨)

 

그렇다면 위처럼 깔끔하게 hover시 밑줄을 깔끔하게 주고 싶다면 어떻게 해야 할까?

 

해결

<nav>
  <ul>
    <li><a href="#">HOME</a></li>
    <li><a href="#">SHOP</a></li>
    <li><a href="#">PAGE</a></li>
  </ul>
</nav>

html은 대충 이렇다고 하자. li 안에 a로 글씨를 감쌌구나라는 정도만 알면 된다.

 

nav ul li a {
  position: relative; /* 필수 */
}

nav ul li a::after {
  content: "";
  width: 100%;
  position: absolute;
  bottom: -10px; /* 글씨와 밑줄 사이의 거리 */
  left: 0;
  border-top: 2px solid #fcaa1f; /* border-bottom을 줘도 된다 */
  /* transform: scaleX(0);
  transition: transform 0.2s; transform 효과는 따로 다룰 예정 */
}

위의 속성들을 하나도 빠짐없이 쓰면 밑줄이 생긴다. 여기서 포인트는 바로 position 값에 "absolute"를 썼다는 점이다. 또한, absolute를 썼기 때문에 위의 a 태그에는 relative 값을 주었다.

 

width 값에는 100%를 줌으로써 글씨 전체 가로 너비에 딱 떨어지게 해주었고, border-top 또는 border-bottom으로 밑줄을 만들었다. 그냥 border로 주게 되면 준 값보다 더 굵어지기 때문에, top이나 bottom으로 따로 줘야 한다. 그리고 bottom: 0을 줬는데, 만약 bottom 대신 top: 0을 주게 된다면 밑줄이 글씨 위로 올라가니, 만약 이런 결과를 원한다면 top으로 바꿔줘도 된다.

 

이외에 해줘야할 것은 따로 없다. 그만큼 가상 요소로 밑줄 정도 만드는 것은 매우 간단한 일이다.

밑줄 뿐만 아니라 가상 요소를 잘 이용하면 여러 가지 다양한 컨텐츠를 손쉽게 만들 수 있다.