input과 checked를 활용한 확장선택자

홍범선·2023년 9월 27일
0

프론트엔드

목록 보기
3/16

✏️ Html, CSS에서 마우스를 올리는 동작(Hover)는 있지만 클릭하는 동작은 없음... 클릭이라는 이벤트를 만들어주는 것이(checked) 가상클래스이다.

checked는 input태그와 같이 쓰인다.

📝 인접 선택자 or 형제 선택자

여기서 왜 p태그 하나만 빨간색으로 되었을까?🤔
=> 인접 선택자는 바로 밑에 있는 것만 선택하기 때문이다. ul태그 인접한 p태그는 하나만 있으므로 해당 태그만 빨간색으로 칠해진 것이다. 중요한 것은 인접선택자는 아래방향에서만 찾는다. 양 옆으로 찾지 않는다.

결과는 아무것도 색칠되지 않는다.

여기서 왜 p태그 전부 파란색으로 되었을까?🤔
=> 형제 선택자는 ul태그와 형제인 태그들 중 같은 계층인 p태그인 것을 전부 파란색으로 칠한 것이다. 반면에 div태그 안 p태그는 다른 계층이므로 색칠되지 않는다.

📝 인접 선택자 & 형제 선택자 함께 쓰기

ul의 형제 태그 중 div태그 하위 요소 중 p태그의 인접태그 div를 찾는다.
굳이 이렇게 까지 하지 않는다. 클래스를 사용하면 된다.

📝 햄버거 버튼 만들기

html파트


input박스는 checked 이벤트만 받지 화면에 보이지 않는다.
label과 input을 같은 이름으로 매칭해주면 화면에 보이지 않지만 기능은 label에서 하게 된다.
span태그는 햄버거 버튼을 화면에 출력해준다.
sidebar는 왼쪽에 있다가 누르면 화면에 나타나는 네비메뉴바이다.

input과 label은 항상 짝꿍이 되어야한다.

input은 보이지 않지만 클릭하면 발생하는 이벤트를 label이 동작하도록 할 것이다.

CSS파트

1. input 안보이게 하기(속성 선택자)

여기서 대괄호는 뭐지?🤔
만약 input전체를 display:none을 하게 되면 모든 input이 안보이게 될 것이다. 이 때 속성 선택자를 사용해서 특정한 input만 display:none이 되도록 하는 것이다.
id=tigger인 input을 안보이게 한다.

2. label(크기값 가지도록 하기)

label은 inline속성이다. 그래서 아무리 width,height를 조정해도 보이지 않는다. 해결하는 방법은 display: block 또는 inline-block을 해주면 된다.

3. span(크기값 가지도록 하기)

span도 마찬가지로 inline속성이다. 따라서 display: block 을 하여 크기값을 가지도록 한다.

왜 width는 없어도 될까?🤔
display block을 하는 순간 내부적으로 width는 100%를 가지도록 한다. 그래서 컨텐트들이 아래로 쌓이는 이유이다.

4. 부모 자식 요소 설정하기

label태그는 부모요소이기 때문에 relative를 주었고 label태그에 하위태그인 span은 label태그기준으로 절대좌표를 사용할 것이기 떄문에 absolute를 사용한다. left: 0을 주었기 때문에 모든 span태그가 left:0인 좌표에 모여있을 것이다.
즉 span마다 top을 다르게 주면 될 것이다.

5. span태그 마다 위치 설정해주기

label span태그에 **width:100% 없어도 된다 했는데 왜 width:100%를 사용했나?🤔
=> absolute 때문이다. absolute를 사용하는 순간 inline-block이 되기 때문에 width:100%를 사용해야한다.**

span태그는 여러개 있다. 이때 nth-child를 사용하면 인덱스에 맞는 span태그를 가져올 수 있다.

6. 결과 확인하기

햄버거 버튼이 나오는 것을 볼 수 있다. 이제 햄버거 버튼을 누르면 x로 바뀌고 네비바가 나오도록 해보자

📝 햄버거 버튼 CSS로 클릭했을 때 x로 바꾸기



1. 햄버거 버튼을 보게 되면 막대기가 span태그로 상, 중, 하로 3개가 있는 것을 볼 수 있다.
2. label과 input을 연결시켰기 때문에 label을 클릭하면 안보이는 input태그에서 checked 가상클래스가 생성된다.(checked가 되어 있을 시 없어짐)
3. x로 변경되는 로직은 span태그의 상, 하를 45도 기울이고, 중에 있는 span태그를 안보이게 하면 된다.
4. input태그에는 checked라는 가상클래스가 존재하는 것을 알 수 있다. 그래서 속성이 trigger인 input태그가 checked되었다면 인접해 있는 label태그의 하위 span 태그들 중 1, 2, 3번째 CSS속성을 변경해준다.
5. 바로 변경되는 것보다 transition을 사용해서 0.3초에 걸쳐 완성되도록 하면 애니메이션 효과가 연출된다.

잘 된다❗️❗️

📝 햄버거 버튼 클릭시 사이드바 생기게 하기


left가 -250px이면 안보일텐데?🤔

1. 처음 네비바를 left를 -250px로 하여 존재하지만 안보이도록 한다.
2. 마찬가지로 input태그 중 id가 trigger인 태그가 checked되었다면 형제 태그들(같은 계층 태그들) 중 클래스 이름이 sidebar인 것을 left를 0으로 한다.

sidebar가 position이 fixed니까 햄버거 버튼을 가리는데??🤔

라벨의 z-index를 높혀 sidebar위로 오도록하면 된다.

📝 햄버거 버튼 클릭시 사이드바 생기는 것과 동시에 햄버거 버튼 위치 이동하기


햄버거 버튼이 보이지만 사이드바 옆에 존재하는 것이 UI적으로 좋은 것 같다.
1. label자체를 움직이기 위해서 label postion을 absolute를 준다.
2. 마찬가지로 input태그 중 id가 trigger인 태그가 checked되었다면 인접태그에서 label인 것을 left를 250px으로 한다.
3. transition을 사용해서 애니메이션 효과내기

잘 된다.

📝 전체코드

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    input[id=trigger]{
      display: none;
    }
    label[for=trigger]{

      width: 30px;
      height: 20px;
      display: block;
      position: absolute;
      top: 10px;
      left: 10px;
      transition: 0.3s;
      z-index: 1000;
    }
    label[for=trigger] span{
      display: block;
      height: 2px;
      background-color: #000;
      position: absolute;
      left: 0;
      width: 100%;
      transition: 0.3s;
      
    }
    label[for=trigger] span:nth-child(1){
      top:0;
    }
    label[for=trigger] span:nth-child(2){
      top:50%;
    }
    label[for=trigger] span:nth-child(3){
      top:100%;
    }
    input[id=trigger]:checked + label span:nth-child(1){
      top: 50%;
      transform: rotate(45deg);
    }
    input[id=trigger]:checked + label span:nth-child(2){
      opacity: 0;
    }
    input[id=trigger]:checked + label span:nth-child(3){
      top: 50%;
      transform: rotate(-45deg);
    }
    .sidebar{
      width: 250px;
      height: 100vh;
      background-color: pink;
      position: fixed;
      top: 0;
      left: -250px;
      transition: 0.3s;
    }
    input[id=trigger]:checked ~ .sidebar{
      left:0;
    }
    input[id=trigger]:checked + label{
      left: 250px;
    }
  </style>
</head>
<body>
  <div class="container">
    <input type="checkbox" id="trigger">
    <label for="trigger">
      <span></span>
      <span></span>
      <span></span>
    </label>
    <div class="sidebar"></div>
  </div>
</body>
</html>
profile
알고리즘 정리 블로그입니다.

0개의 댓글

관련 채용 정보