2021.12.27 CSS의 활용 #3

leeseungjun·2021년 12월 27일
0

오늘은 마우스 클릭에 반응에 나타났다 사라지는 사이드 메뉴를 구현하는 방법을 알아보자.

1. Selectors

우선 본격적으로 시작하기전에 새로운 selector들의 개념과 사용법을 알아두고 들어가자.

1.1 속성 선택자 (Attributte Selectors)

속성 선택자는 지정하는 속성을 가진 element만을 선택적으로 styling해주는 방식이다.

element[attribute="value"] {
  styling
}

의 format으로 쓸 수 있다.

예를 들어

input[id="sidemenu"] {
  background: red;
}

와 같이 써주면 idvaluesidemenu

가지는 input element를 선택해 배경색을 red로 주겠다는 의미이다.

1.2 Pseudo-Class Selector (:)

pseudo-class selector는 element가 특정한 상태에 있을 때를 styling 해주는 selector를 의미한다.

input[id="check"]: checked {   /* input type="checkbox"라고 가정 */
  background: blue;
}

위와 같이 쓰면 id가 check인 input element가 checked상태일 때만

배경색을 파랗게 바꿔주겠다는 것을 의미한다.

1.3 Adjacent Sibling Combinator (+)

Adjacent Sibling Combinator(인접 형제 선택자)

두 개의 element를 선택, 전자 바로 다음에 오는 후자 element를 styling해준다.

input[id="check"] + label {
  background: black;
}

이렇게 써주면 id의 value로 "check"를 가지는 input element

바로 다음에 오는 label element의 배경색을 black으로 바꿔준다.


이상 모든 selector들은 다른 selector들과 함께 사용할 수 있다.

2. Sidemenu 구현

2.1 checkbox 만들기

기본적인 메커니즘은 checkbox를 하나 만들고, pseudo-class selector를 활용해

그 checkbox가 check 된 상태인지 아닌지에 따라

다른 element의 styling을 바꾸는 방식으로 사이드 메뉴를 화면에

표현했다가 치웠다가 하는 것이다.

우선 checkbox를 만들어준다.

<input type="checkbox" id="sidemenu">

이를 CSS에서 styling 해준다.

input[id="sidemenu"] {
  display: none;
 }

여기서 display의 value none는 화면에 렌더링되지는 않지만 계속 브라우저 상에서

존재하고, 동작하게 element를 styling 해준다는 것을 의미한다.


다음으로 label element를 하단에 추가해 checkbox의 클릭 인식 범위를 조정해준다.
<label for="sidemenu">
</label>

label element의 크기를 css에서 다음과 같이 조정한다.

input[id="sidemenu"] + label {
  display: blocked;
  width: 60px;
  height: 40px;
  cursor: pointer;
  background: yellowgreen;
}

여기까지 하고 브라우저에서 불러오면 checkbox는 보이지 않지만 그 위치에 커서를

두면 커서의 모양이 바뀌는 것을 확인할 수 있다.

2.2 label 꾸미기

label의 모양을 만들고 이를 변형하는 것을 구현하면 보다 그럴싸한 sidemenu 구현이

가능해진다.

우선 <label> 안에 <span>를 3개 추가해준다.

span element들을 다음과 같이 styling 해준다.

 input[id="sidemenu"] + label > span {
   display: block;
   width: 100%;
   height: 5px;
   border-radius: 30px;
   background: black;
 }

여기까지 하고 브라우저를 보면 다음과 같이 나타난다.

이제 각각의 span을 따로 styling해 위치를 바꿔줘야 한다.

각각의 span들에 class를 넣어 속성을 부여할 수도 있지만 여기서는 nth-child라는 키워드를 사용해본다.

css에 다음과 같이 추가하자.

input[id="sidemenu"] + label > span:nth-child(1) {
   top: 0px;
}
input[id="sidemenu"] + label > span:nth-child(2) {
  top:50%;
}
input[id="sidemenu"] + label > span:nth-child(3) {
  bottom: 0px;
}

이렇게 해도 차이가 없는데, 각 span을 parent element(label)를 기준으로 배치하려면

label과 span에 position 속성을 부여해야 한다. 다음을 각 element에 대해 추가한다.

input[id="sidemenu"] + label {
  postition: relative;
}
input[id="sidemenu"] + label > span {
  position: absolute;
}

이 후, 브라우저에서 보면 다음과 같다.

두번째 span이 약간 아래로 밀린 이유는, element의 배치를 정할 때,

기준이 항상 왼쪽 상단부터 시작하기 때문이다. 이를 보정하기 위해 다음을 추가한다.

input[id="sidemenu"] + label > span:nth-child(2) {
  tranform: translateY(-50%)  /* 자신의 크기의 -50%만큼 element 위치를 이동 */  
}

2.3 모양 변형하기

이제 클릭에 따라 성질을 바꾸는 것을 css로 구현해보자.

앞에서 checkbox의 display 성질 값을 none으로 주면 화면상에 렌더링 되지는 않지만

여전히 동작하고 있다는 것을 다시 한 번 생각해보면 된다.

여기서 pseudo-class selector가 활용된다.

input[id="sidemenu"]:checked + label > span:nth-child(1) {
  top:50%;
  transform: translateY(-50%) rotate(45deg); /* 위치 조정, 객체 회전 */
}
input[id="sidemenu"]:checked + label > span:nth-child(2) {
  opactiy: 0;
}
input[id="sidemenu"]:checked + label > span:nth-child(3) {
  top:50%;
  transform: translateY(50%) rotate(-45deg);
}

여기까지 왔으면 label의 background값은 지워도 된다.

stripe 3개에서 x자로 span의 배치를 바꿀 때, 이 변화를 눈에 보일 정도로

서서히 보여주고 싶다면 transition 속성을 추가하면 된다. span의 성질에 다음과 같이

추가하자.

input[id="sidemenu"] + label > span {
  transition: all 0.35s;   /*  오른쪽의 숫자가 변형 시간을 의미한다.  */
}

2.4 sidemenu bar

이제 전에 했던 것과 마찬가지로 <div>을 만들고 그 안에 list들을 넣음으로써

메뉴를 구현해 볼 것이다. 다른 점이 있다면 화면에 렌더링이 되는지의 여부를 사용자가

클릭으로 바꿀 수 있다는 것이다.

label 하단에 다음과 같이 division을 추가한다.

<div id="header">
  <ul>
    <li><a href="#">menu1</a></li>
    <li><a href="#">menu1</a></li>
    <li><a href="#">menu1</a></li>
    <li><a href="#">menu1</a></li>
    <li><a href="#">menu1</a></li>
  </ul>
</div>

대응하는 css에서는 다음과 같이 써주면 된다.

#sidemenu + label + #header {
  position:fixed;  /* 스크롤을 내려도 항상 같은 자리에 유지할 수 있게 하는 명령어  */
  width: 300px;
  height: 100%;
  background: rgb(136, 136, 136);
  top: 0px;
  padding: 60px 25px 25px 25px;
  box-sizing:border-box;
  left:-300px;   /* element의 크기만큼 화면 바깥으로 이동했으므로 보이지 않게 된다. */ 
  transition: all 0.35s;
 }
#sidemenu:checked + label + #header {
left: 0px;  /* sidemenu가 체크된 상태라면 위치를 이동, 화면에 나타나게 만든다.  */

이렇게 하고 span을 클릭하면 사이드 메뉴가 튀어나오게 되는데,
다시 클릭을 할 수 없게 된다. 이를 수정하기 위해 z-index를 추가해주면 된다.

label[id="sidemenu"] + label > span {
  z-index:2;
}

이렇게 하면 열고 닫을 수 있는 기능을 포함한 사이드 메뉴가 완성된다.

0개의 댓글