부스트코스 2단 메뉴 마크업 중 어려웠던 점

심지훈·2021년 6월 5일
0

부스트코스

위와 같이 2단 메뉴를 마크업 하던 중 어려웠던 점을 정리해봤다.

  1. 어떻게 서브메뉴가 메인메뉴 하단에 자리잡게 하는가?

위는 메인메뉴와 서브메뉴의 마크업인데, 메인 메뉴의 a태그 아래에 서브메뉴가 위치하기 된다.

.submenu{
    position: absolute;
    left: 0;
    width: 100%;
    min-width: 700px;
    border-top: 1px solid #eee;
    border-bottom: 1px solid #eee;
}

position:absolute가 어떻게 서브메뉴를 아래로 내리는지 이해 할 수 없었다.

우선 모든 스타일을 제거한 상태는 위와같고, position:absolute를 한 상태는 아래와 같다.

어떻게 메인메뉴는 제자리를 찾아가고 서브메뉴는 아래로 내려올까?

https://www.daleseo.com/css-position-absolute/

이분의 블로그를 보고 바로 알 수 있었다.
position:absolute로 선언시에는 요소는 화면에서 자신만의 고유위치를 가지게 됨으로서 부모요소로부터 '독립'하게 된다. 더 정확히는 부모요소(상위요소)중 position: relative를 가진 가장 가까운 요소를 기준으로 절대적인 위치를 가지게 된다. 여기서는 relative한 포지션을 갖는 가장 가까운 요소는 html이므로 html 루트를 기준으로 절대적인 위치를 갖게 된다.

position:absolute만 적용해주면 따로 left,right,bottom,top 기준점을 명시해 주지 않았으므로 기존 웹툰메뉴 위치를 기준으로 부모요소에서 벗어나 독자적인 위치를 가지게 된다.

그 후 left: 0을 스타일링을 해주면 가장 상위 요소를 기준으로 left:0인 위치로 이동했고 블록 영역을 전체 다 사용하고 가운데 정렬 할것이기 때문에

.submenu {
    ...
    width:100%;
    text-align: center;

를 해주면 된다. text-align: center를 보면 상위요소에서 상속되므로 굳이 명시적으로 스타일링을 해줄 필요는 없다.

  1. 아래와 같이 글자아래 막대를 만드는 것

우선 이것도 position: absolute 속성을 이용해서 만드는 것인데 가상요소 선택자 ::after를 이용해서 만든다.

먼저 시각적으로 잘 보이게 하기 위해서 border 속성을 좀 진하게 표시했다. 위는 ::afterborder를 제외한 아무런 스타일링을 입히지 않은 모습이다. ::after는 요소 뒤에 위치한 가상의 영역을 가르키는 것을 볼 수 있다.

position: absolute로 스타일링을 주면 기존의 ::after의 위치에서 벗어나 position: relative한 부모요소를 기준으로 독자적인 위치를 갖게되고 현재는 서브메뉴의 li태그가 position: relative로 스타일링이 되어 있다.

상위 부모요소 li태그가 position: relative일때 position:absolute::afterleft:0으로 했을때 위와 같이 이동하게 된다.

li태그에 position: relative속성을 없애면 위와같이 가장 상위, html 요소를 기준으로 left:0 속성이 적용된다.

차례대로 left:0; right:0; bottom: -15px;을 주면 위와 같이 위치하게 되는데 저거는 display: blocka태그 기준으로 막대가 만들어지게 된것이다. 이것을 글자크기만큼만 막대가 그어지도록 해보자.

강의에서 width속성을 이용해 막대의 길이를 조정 할 수도 있다고 했지만 그렇게하면 글자의 수가 바뀜에 따라서 width도 바뀌어야 하기 때문에 유지보수 측면에서 어렵다고 했다.

글자를 span태그로 감싼뒤 span태그를 기준으로 똑같은 스타일링을 주면 글자 밑에만 도형이 생긴다.

.submenu_item  span{
    position: relative;
}

.submenu_item.active span::after,
.submenu_item:hover span::after{
    position: absolute;
    content: "";
    right: 0;
    bottom: -15px;
    left: 0;
    border: 3px solid #000;
}
profile
유연한 개발자

0개의 댓글