본문 바로가기
> 포트폴리오/wiggle wiggle

[SCSS] 검색창 만들기 ( search )

by 자몽주스 2024. 7. 1.
728x90
반응형


Fieldset 태그의 사용

 

fieldset 태그는 폼(form) 요소 내에서 관련된 요소들을 그룹화할 때 사용된다.

보통 legend 태그와 함께 사용되어 그룹의 제목을 제공하는 데 활용됩니다.

fieldset 태그는 접근성을 높이고, 폼 요소의 시각적 그룹화를 제공하는 데 유용하다.


HTML - aside
 <aside id="aside">
        <div class="aside-content">
          <div class="aside-top">
            <div class="aside-search">
              <fieldset>
                <legend>상품검색창</legend>
                <div class="input-container">
                  <input name="search" placeholder="검색하기" />
                  <img src="img/돋보기.svg" class="search-icon" />
                </div>
              </fieldset>
            </div>
            <div class="aside-cart">
              <a href="#"><img src="img/장바구니.svg" /></a>
            </div>
            <div class="aside-close">
              <a href="#"><img src="img/닫기.svg" /></a>
            </div>
          </div>
          <div class="aside-middle">
            <ul>
              <li>JOIN</li>
              <li>LOGIN</li>
              <li>CART</li>
              <li>MY PAGE</li>
            </ul>
          </div>
          <span class="dote-line"></span>
          <div class="aside-bottom">
            <ul>
              <li>ALL</li>
              <li>NEW</li>
              <li>BEST</li>
              <li>EVENT</li>
              <li>OUTLET</li>
              <li>ABOUT US</li>
              <li>OFFLINE</li>
            </ul>
          </div>
        </div>
      </aside>
aside-top 부분
 <div class="aside-top">
            <div class="aside-search">
              <fieldset>
                <legend>상품검색창</legend>
                <div class="input-container">
                  <input name="search" placeholder="검색하기" />
                  <img src="img/돋보기.svg" class="search-icon" />
                </div>
              </fieldset>
            </div>
            <div class="aside-cart">
              <a href="#"><img src="img/장바구니.svg" /></a>
            </div>
            <div class="aside-close">
              <a href="#"><img src="img/닫기.svg" /></a>
            </div>
          </div>

CSS 확인하기
#aside {
  position: fixed;
  top: 0;
  right: 0;
  width: 488px;
  height: 100vh;
  background: $main_color;
  z-index: 999;
  overflow-y: auto; // 질문 정리하기
  display: none; // js로 건들기
  padding: 78px 54px;
  font-size: 18px;
  li {
    font-weight: bold;
    margin-bottom: 16px;
    color: $sub_color;
    &:last-child {
      margin-bottom: 0;
    }
    &:hover {
      color: white; // 밑줄 생기게 꾸며주기
    }
  }

  .aside-top {
    margin: auto; //가운데 정렬
    width: 100%;
    margin-bottom: 44px;
    display: flex;
    align-items: center;
    justify-content: center;

    .aside-search {
      legend {
        display: none;
      }

      fieldset {
        border: none; /* 기본 fieldset 테두리 제거 */
        padding: 0; /* 기본 패딩 제거 */
        margin: 0; /* 기본 마진 제거 */
      }

      .input-container {
        position: relative;
        width: 100%;
      }

      .input-container .search-icon {
        position: absolute;
        right: 10px; /* 필요한 경우 조정 */
        top: 50%;
        transform: translateY(-50%);
        width: 20px; /* 필요한 경우 조정 */
        height: 20px; /* 필요한 경우 조정 */
        pointer-events: none; /* 아이콘이 입력 이벤트를 차단하지 않도록 설정 - 이거 뭔지 잘 모르겠으므로 질문하기.*/
      }

      input {
        padding: 10px;
        background-color: $main_color;
        width: 260px;
        height: 38px;
        border: 5px solid $sub_color;
        border-style: dashed;
        border-radius: 50px;
        letter-spacing: 2px;
        color: $sub_color;
        font-weight: bold;
        outline: none; /* 포커스 시 기본 테두리 제거 */
        box-shadow: none; /* 포커스 시 그림자 제거 */
        &:-webkit-autofill,
        &:-webkit-autofill:hover,
        &:-webkit-autofill:focus,
        &:-webkit-autofill:active {
          -webkit-box-shadow: 0 0 0 30px $main_color inset;
          -webkit-text-fill-color: $sub_color;
          border: 5px dashed $sub_color;
        }
        // input 요소의 자동완성 스타일을 덮어쓰는 CSS - 질문
      }
    }
    .aside-cart {
      display: flex;
      align-items: center;
      margin-left: 21px; // 간격 추가
    }
    .aside-close {
      margin-left: 21px; // 간격 추가
      img {
        width: 39px;
        height: 39px;
      }
    }
  }

  .dote-line {
    width: 100%; //.aside-content 너비 만큼 라인 채워주기.
    //.dote-line이 부모 요소인 .aside-content의 너비를 가득 채우도록 했음.
    height: 5px;
    display: inline-block; //span태그는 inline.
    margin: 27.5px 0; /* 총 높이를 59px로 맞추기 위해 조정 */
    border-bottom: 5px dashed $sub_color;
  }
}

 

aside-top 부분
.aside-top {
    margin: auto; //가운데 정렬
    width: 100%;
    margin-bottom: 44px;
    display: flex;
    align-items: center;
    justify-content: center;

    .aside-search {
      legend {
        display: none;
      }

      fieldset {
        border: none; /* 기본 fieldset 테두리 제거 */
        padding: 0; /* 기본 패딩 제거 */
        margin: 0; /* 기본 마진 제거 */
      }

      .input-container {
        position: relative;
        width: 100%;
      }

      .input-container .search-icon {
        position: absolute;
        right: 10px; /* 필요한 경우 조정 */
        top: 50%;
        transform: translateY(-50%);
        width: 20px; /* 필요한 경우 조정 */
        height: 20px; /* 필요한 경우 조정 */
        pointer-events: none; /* 아이콘이 입력 이벤트를 차단하지 않도록 설정 - 이거 뭔지 잘 모르겠으므로 질문하기.*/
      }

      input {
        padding: 10px;
        background-color: $main_color;
        width: 260px;
        height: 38px;
        border: 5px solid $sub_color;
        border-style: dashed;
        border-radius: 50px;
        letter-spacing: 2px;
        color: $sub_color;
        font-weight: bold;
        outline: none; /* 포커스 시 기본 테두리 제거 */
        box-shadow: none; /* 포커스 시 그림자 제거 */
        &:-webkit-autofill,
        &:-webkit-autofill:hover,
        &:-webkit-autofill:focus,
        &:-webkit-autofill:active {
          -webkit-box-shadow: 0 0 0 30px $main_color inset !important;
          -webkit-text-fill-color: $sub_color !important;
          border: 5px dashed $sub_color !important;
        }
        // input 요소의 자동완성 스타일을 덮어쓰는 CSS - 질문
      }
    }
    .aside-cart {
      display: flex;
      align-items: center;
      margin-left: 21px; // 간격 추가
    }
    .aside-close {
      margin-left: 21px; // 간격 추가
      img {
        width: 39px;
        height: 39px;
      }
    }
  }

HTML
 <div class="aside-search">
              <fieldset>
                <legend>상품검색창</legend>
                <div class="input-container">
                  <input name="search" placeholder="검색하기" />
                  <img src="img/돋보기.svg" class="search-icon" />
                </div>
              </fieldset>
            </div>

fieldset 을 사용해서 검색창을 그룹화 함.

fieldset 과 세트인 legend 를 사용해주고,

 

div 태그를 사용해서

input 태그와 돋보기 이미지를 넣어줬다.


CSS
.aside-search { // .aside-search 클래스에 대한 스타일 정의
  legend {
    display: none; // legend 요소를 숨깁니다.
  }

  fieldset {
    border: none; // fieldset 요소의 기본 테두리를 제거합니다.
   }

  .input-container {
    position: relative; // 내부 요소의 위치를 기준으로 배치합니다.
    width: 100%; // 부모 요소의 너비를 100%로 설정합니다.
  }

  .input-container .search-icon {
    position: absolute; // 검색 아이콘의 위치를 절대 위치로 설정합니다.
    right: 10px; // 오른쪽에서 10px 떨어지도록 설정합니다.
    top: 50%; // 위쪽에서 50% 떨어지도록 설정합니다.
    transform: translateY(-50%); // 아이콘을 세로 중앙으로 맞춥니다.
    width: 20px; // 너비를 20px로 설정합니다.
    height: 20px; // 높이를 20px로 설정합니다.
    pointer-events: none; // 아이콘에 마우스 이벤트가 발생하지 않도록 설정합니다.
  }

  input {
    padding: 10px; // 내부 여백을 10px로 설정합니다.
    background-color: $main_color; // 배경 색상을 $main_color 변수로 설정합니다.
    width: 260px; // 너비를 260px로 설정합니다.
    height: 38px; // 높이를 38px로 설정합니다.
    border: 5px solid $sub_color; // 테두리를 5px 두께의 $sub_color 색상으로 설정합니다.
    border-style: dashed; // 테두리 스타일을 대쉬(dashed)로 설정합니다.
    border-radius: 50px; // 테두리를 둥글게 만들어 줍니다.
    letter-spacing: 2px; // 글자 간격을 2px로 설정합니다.
    color: $sub_color; // 글자 색상을 $sub_color로 설정합니다.
    font-weight: bold; // 글자 굵기를 굵게 설정합니다.
    outline: none; // 포커스 시 기본 테두리를 제거합니다.
    box-shadow: none; // 포커스 시 그림자를 제거합니다.

    // 자동완성 텍스트에 대한 스타일 정의
    &:-webkit-autofill,
    &:-webkit-autofill:hover,
    &:-webkit-autofill:focus,
    &:-webkit-autofill:active {
      -webkit-box-shadow: 0 0 0 30px $main_color inset !important; // 자동완성 배경 색상을 $main_color로 설정합니다.
      -webkit-text-fill-color: $sub_color !important; // 자동완성 텍스트 색상을 $sub_color로 설정합니다.
      border: 5px dashed $sub_color !important; // 테두리를 5px 두께의 대쉬 스타일로 설정합니다.
    }
  }
}

이전

.aside-search {
  legend {
    display: none; /* legend 요소를 화면에 보이지 않게 함 */
  }

  fieldset {
    border: none; /* 기본 fieldset 테두리를 제거함 */
    padding: 0; /* 기본 패딩을 제거함 */
    margin: 0; /* 기본 마진을 제거함 */
  }

  .input-container {
    position: relative; /* 검색 아이콘을 input 내부에 배치하기 위해 위치를 상대적으로 설정 */
    width: 100%; /* 컨테이너의 너비를 100%로 설정 */
  }

  .input-container .search-icon {
    position: absolute; /* 검색 아이콘의 위치를 절대적으로 설정하여 input 내부에 배치 */
    right: 10px; /* 검색 아이콘을 input 오른쪽에서 10px 떨어지게 설정 */
    top: 50%; /* 검색 아이콘을 input의 세로 중앙에 배치 */
    transform: translateY(-50%); /* 검색 아이콘을 정확히 중앙에 맞추기 위해 수직 변환 */
    width: 20px; /* 검색 아이콘의 너비를 20px로 설정 */
    height: 20px; /* 검색 아이콘의 높이를 20px로 설정 */
    pointer-events: none; /* 검색 아이콘이 클릭 등 입력 이벤트를 차단하지 않도록 설정 */
  }

  input {
    padding: 10px; /* input 내부 텍스트의 여백을 10px로 설정 */
    background-color: $main_color; /* input의 배경색을 $main_color 변수로 설정 */
    width: 260px; /* input의 너비를 260px로 설정 */
    height: 38px; /* input의 높이를 38px로 설정 */
    border: 5px solid $sub_color; /* input의 테두리를 $sub_color 변수로 설정하고 두께를 5px로 설정 */
    border-style: dashed; /* input의 테두리 스타일을 점선으로 설정 */
    border-radius: 50px; /* input의 모서리를 50px로 둥글게 설정 */
    letter-spacing: 2px; /* 글자 간격을 2px로 설정 */
    color: $sub_color; /* 텍스트 색상을 $sub_color 변수로 설정 */
    font-weight: bold; /* 텍스트를 굵게 설정 */
    outline: none; /* 포커스 시 기본 테두리를 제거함 */
    box-shadow: none; /* 포커스 시 그림자를 제거함 */
    
    /* input 요소의 자동완성 스타일을 덮어쓰는 CSS */
    &:-webkit-autofill,
    &:-webkit-autofill:hover,
    &:-webkit-autofill:focus,
    &:-webkit-autofill:active {
      -webkit-box-shadow: 0 0 0 30px $main_color inset; /* 자동완성된 배경색을 $main_color로 설정 */
      -webkit-text-fill-color: $sub_color; /* 자동완성된 텍스트 색상을 $sub_color로 설정 */
      border: 5px dashed $sub_color; /* 자동완성된 상태에서도 테두리를 5px 점선 $sub_color로 유지 */
    }
  }
}

수정된 css


position 속성의 사용 목적
.input-container {
  position: relative; // 내부 요소의 기준점을 이 요소로 설정합니다.
  width: 100%; // 부모 요소의 너비를 100%로 설정합니다.
}

.input-container .search-icon {
  position: absolute; // 이 요소를 가장 가까운 위치 지정 조상의 기준으로 배치합니다.
  right: 10px; // 오른쪽에서 10px 떨어지도록 설정합니다.
  top: 50%; // 위쪽에서 50% 떨어지도록 설정합니다.
  transform: translateY(-50%); // 아이콘을 세로 중앙으로 맞춥니다.
  width: 20px; // 너비를 20px로 설정합니다.
  height: 20px; // 높이를 20px로 설정합니다.
  pointer-events: none; // 아이콘에 마우스 이벤트가 발생하지 않도록 설정합니다.
}

position: relative

.input-containerposition: relative를 준 이유는 내부 요소들의 위치를 이 요소를 기준으로 설정하기 위해서입니다. relative는 요소의 원래 위치를 기준으로 상대적인 위치를 설정할 수 있게 해줍니다.

이 코드에서는 내부에 위치한 .search-icon 요소의 배치를 위한 기준점을 설정하는 역할을 합니다.

position: absolute

.search-icon position: absolute를 준 이유는

이 요소를 .input-container를 기준으로 원하는 위치에 정확히 배치하기 위해서입니다.

absolute는 가장 가까운 position이 relative, absolute, fixed, 또는 sticky로 설정된 조상을 기준으로 요소를 배치합니다. 여기서는 .input-container가 relative로 설정되어 있으므로, .search-icon은 .input-container를 기준으로 배치됩니다.


top: 50% transform: translateY(-50%)의 사용
= 요소를 수직 중앙에 정렬하기 위해서

top: 50%

top: 50%는 부모 요소의 상단에서부터 자신의 높이의 50% 위치로 요소를 이동시킵니다.

그러나 이렇게 하면 요소의 상단이 부모 요소의 중간에 오게 됩니다. 즉, 요소의 절반이 위로 튀어나오게 됩니다.

transform: translateY(-50%)

transform: translateY(-50%)는 요소를 자신의 높이의 50%만큼 위로 이동시킵니다.

이로 인해 요소가 정확히 부모 요소의 수직 중앙에 오게 됩니다.

결합된 효과

이 두 속성을 결합하면 요소의 수직 중앙 정렬이 정확하게 이루어집니다.

간단히 말해, top: 50%는 요소를 부모의 중간으로 보내고,

transform: translateY(-50%)는 요소의 절반을 위로 올려서 전체 요소가 중앙에 위치하도록 합니다.


top: 50% transform: translateY(-50%) 의 차이 

 

top: 50%

 

이 속성은 요소의 상단이 부모 요소의 높이의 50% 지점에 위치하도록 합니다.

그러나 이것만으로는 요소가 정확히 중앙에 배치되지 않습니다.

왜냐하면 top: 50%는 요소의 상단을 기준으로 위치를 잡기 때문입니다.

따라서 요소의 절반은 부모 요소의 50% 지점 아래에 있게 됩니다.

transform: translateY(-50%)

 

요소를 자신의 높이의 50%만큼 위로 이동시킵니다.

이는 요소의 세로 중심을 기준으로 이동을 시킵니다.


두 속성의 조합

 

이 둘을 함께 사용하면 요소를 부모 요소의 중앙에 정확히 배치할 수 있습니다.

 

  • top: 50%요소의 상단을 부모 요소의 높이의 50% 지점에 위치시킵니다.
  • transform: translateY(-50%)요소를 자신의 높이의 50%만큼 위로 이동시켜, 요소의 세로 중심이 부모 요소의 높이의 50% 지점에 오게 합니다.
예시

 

예를 들어, 부모 요소의 높이가 200px이고, 자식 요소의 높이가 40px라고 가정해봅시다.

  1. top: 50%자식 요소의 상단부모 요소의 50% 지점인 100px에 위치시킵니다. (부모 요소가 200px 이니까) 
  2. 그러나 이 상태에서는 자식 요소의 상단이 100px에 위치하므로, 자식 요소의 하단은 140px에 위치하게 됩니다.
  3. transform: translateY(-50%)자식 요소를 20px(자신의 높이 40px의 50%) 위로 이동시킵니다.
  4. 따라서 자식 요소의 상단은 80px, 하단은 120px에 위치하게 됩니다.
  5. 결과적으로 자식 요소는 부모 요소의 세로 중심에 배치됩니다.

 


그림으로 설명

예시 상황

  • 부모 요소의 높이: 200px
  • 자식 요소의 높이: 40px
top: 50% 적용 후: 자식 요소의 상단 부모 요소의 50% 지점인 100px에 위치시킵니다. (부모 요소가 200px 이니까) 

 

부모 요소 (높이 200px)
+---------------------+
|                     |
|        (100px)      | <- 자식 요소의 상단
|       +------+      |
|       | 자식 |      |
|       | 요소 |      |
|       +------+      |
|                     |
+---------------------+

자식 요소의 상단이 100px에 위치하므로, 자식 요소의 하단은 140px에 위치하게 됩니다.

자식 요소의 상단이 부모 요소의 높이의 50% 지점에 위치합니다.

따라서 자식 요소의 상단은 100px 지점에 위치합니다.

부모 요소 (높이 200px)
+---------------------+
|                     |
|        (100px)      | <- 자식 요소의 상단
|       +------+      |
|       | 자식 |      |
|       | 요소 |      |
|       +------+      | <- 자식 요소의 하단 (100px + 40px = 140px)
|        (140px)      |
|                     |
+---------------------+

자식 요소의 높이는 40px이므로, 자식 요소의 하단은 상단에서 40px 아래에 위치합니다.

따라서 자식 요소의 상단이 100px에 위치할 때, 하단은 140px에 위치합니다. 

2. transform: translateY(-50%) 적용 후: 자식 요소를 20px(자신의 높이 40px의 50%) 위로 이동시킵니다.
부모 요소 (높이 200px)
+---------------------+
|                     |
|                     |
|     +------+        |
|     | 자식 |        | <- 자식 요소의 상단 (80px)
|     | 요소 |        |
|     +------+        | <- 자식 요소의 하단 (120px)
|                     |
+---------------------+

자식 요소의 상단은 80px, 하단은 120px에 위치하게 됩니다.

결과적으로 자식 요소는 부모 요소의 세로 중심에 배치됩니다.

 

자식 요소를 자신의 높이의 50%만큼 위로 이동시킵니다.

자식 요소의 높이가 40px이므로 50%는 20px입니다.

자식 요소를 20px 위로 이동시키면, 상단이 80px에 위치하게 되고, 하단이 120px에 위치하게 됩니다.

( 총 높이 240 에서 1/2 하면 120px 이니 정확한 세로중심에 배치되는 것. )

최종 결과

 

top: 50%와 transform: translateY(-50%)를 함께 사용하면,

자식 요소는 부모 요소의 정확한 세로 중심에 배치됩니다.

이 방법은 자식 요소의 높이가 무엇이든, 부모 요소의 세로 중심에 항상 일관되게 배치되도록 합니다.

시각적 요약
  1. top: 50%:
    • 자식 요소의 상단이 부모 요소의 50% 지점에 위치합니다.
  2. transform: translateY(-50%):
    • 자식 요소를 자신의 높이의 50%만큼 위로 이동시켜, 정확히 부모 요소의 세로 중심에 배치합니다.

참고할만한 사이트

https://velog.io/@kmjstj3/%EA%B0%80%EC%9A%B4%EB%8D%B0-%EC%A0%95%EB%A0%AC-%EC%B5%9C%EA%B0%95%EC%9E%90-top50-left50-transformtranslate-50-50

 

가운데 정렬 최강자 top:50% left:50% transform:translate(-50%,-50%)🥰

오늘은 아주 유용하게 사용하는 가운데 정렬 css문법을 소개하려고 한다.top:50%;left:50%;transform:translate(-50%,-50%);위 코드처럼 transfrom의 translate를 사용하면 매우 편리하게 가운데 정렬을 할 수 있다.

velog.io


webkit 설명

 

:-webkit-autofill은 브라우저가 사용자의 입력 데이터를 자동으로 채워줄 때 적용되는 특수한 CSS 선택자

&:-webkit-autofill,
&:-webkit-autofill:hover,
&:-webkit-autofill:focus,
&:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 30px $main_color inset; /* 자동완성된 배경색을 $main_color로 설정 */
  -webkit-text-fill-color: $sub_color; /* 자동완성된 텍스트 색상을 $sub_color로 설정 */
  border: 5px dashed $sub_color; /* 자동완성된 상태에서도 테두리를 5px 점선 $sub_color로 유지 */
}

이 CSS의 역할

  1. :-webkit-autofill: 브라우저가 자동완성 데이터를 입력 필드에 채울 때 적용됩니다.
  2. :-webkit-autofill:hover: 자동완성된 입력 필드가 마우스 오버 상태일 때 적용됩니다.
  3. :-webkit-autofill:focus: 자동완성된 입력 필드가 포커스를 받을 때 적용됩니다.
  4. :-webkit-autofill:active: 자동완성된 입력 필드가 활성화되었을 때 적용됩니다.

:-webkit-autofill은 개발자모드 #shadow-root 에 보이지 않던데 어디서 알 수 있는 지?

준비중

728x90
반응형