[HTML/CSS/JS] 팝업 구현3(+ 속성 선택자, flex, 그레이브 문법, 테일윈드)

happyyeom·2024년 10월 29일

속성 선택자

css선택자 문법의 일종으로 속성 선택자라는 것이 있다. 이 문법은 HTML요소의 특정 속성이나 값에 따라 요소를 선택하는데 사용된다.
기본 구문:

  • [attribute]: 해당 속성이 존재하는 모든 요소를 선택합니다.
  • [attribute="value"]: 특정 속성이 지정한 값과 정확히 일치하는 요소를 선택합니다.
  • [attribute*="value"]: 해당 속성 값에 지정한 문자열이 포함된 요소를 선택합니다.
  • [attribute^="value"]: 해당 속성 값이 지정한 문자열로 시작하는 요소를 선택합니다.
  • [attribute$="value"]: 해당 속성 값이 지정한 문자열로 끝나는 요소를 선택합니다.

ex)

/* class 속성에 "button"이라는 문자열이 포함된 모든 요소 선택 */
[class*="button"] {}
/* class 속성이 "prefix-"로 시작하는 요소 선택 */
[class^="prefix-"] {}
/* class 속성이 "-active"로 끝나는 요소 선택 */
[class$="-active"] {}
/* class 속성이 "popup-"을 포함하고 "-active"로 끝나는 모든 section 요소 선택 */
section[class*="popup-"][class$="-active"] {}

이 속성을 이용해서 우리가 기존에 구현했던 팝업 코드에서 별도의 css속성을 추가하지 않더라도 요소를 추가함으로써 팝업이 늘어나도록 구조를 변경해보자.

원래 기존 css코드에서

.popup-1-actived,
.popup-1-actived > body {
  overflow:hidden;
}

.popup-2-actived,
.popup-2-actived > body {
  overflow:hidden;
}

이 코드를 수정해주어야 한다.
여기서 숫자를 제외한 popup--actived는 중복되기에 이 코드를

[class*="popup-"][class*="-actived"],
[class*="popup-"][class*="-actived"] > body{
  overflow:hidden;
}

이렇게 수정한다.
JS

function Popup__init(no) {
  $('.btn-popup-' + no).click(function() {
    Popup__show(no);
  });
  
  $('.popup-' + no + ' .popup__btn-close, .popup-' + no).click(function() {
    Popup__hide(no);
  });
  
  $('.popup-' + no + ' .popup__content').click(function() {
    return false;
  });
}

function Popup__show(no) {
  $('.popup-' + no).addClass('active');
  $('html').addClass('popup-' + no + '-actived');
}

function Popup__hide(no) {
  $('.popup-' + no).removeClass('active');
  $('html').removeClass('popup-' + no + '-actived');
}

매개변수에 숫자가 들어가서 실행되면

 $('html').~~~('popup-' + no + '-actived');

이 함수는 html태그에 popup-(매개변수)-actived를 추가하고 popup--actived클래스를 가지고 있는 태그들([class*="popup-"][class*="-actived"], [class*="popup-"][class*="-actived"] > body)에게 속성을 적용한다.

팝업창을 flex를 이용해 재구현

팝업 헤더의 높이를 css에 적지 않도록 flex를 이용해 다시 구현해보자.

.popup__content {
  min-width:200px;
  min-height:200px;
  background-color:white;
  border:2px solid black;
  transform:translateY(-100%);
  transition: transform .3s;
}

--->

.popup__content {
  min-width:200px;
  max-height:100%;
  background-color:white;
  border:2px solid black;
  box-sizing:border-box;
  transform:translateY(-100%);
  transition: transform .3s;
  display:flex;
  flex-direction:column;
}

전체 팝업창의 높이를 지정하지 않았다가 100%로 지정해주고 display속성을 flex, 방향을 세로 방향으로 지정해준다. 또한 전체넓이에 border를 포함하도록 해준다.

.popup__body {
  padding:0 10px;
  max-height:calc(100vh - 55px);
  overflow-y:auto;
}

--->

.popup__body {
  padding:0 10px;
  flex-grow:1;
  overflow-y:auto;
}

원래 팝업의 body부분의 너비를 유연하게 만들기위해 max-height:calc(100vh - 55px);이 코드를 사용했지만 이제 팝업 header의 너비를 건들지 않고도 flex-glow를 이용해 유연하게 늘어나도록 만들었다.

그레이브 문법을 이용해 JS 함수 수정

그레이브 문법이란 백틱(x-shift~)을 이용한 방식으로 ${}를 사용해 문자열에 변수를 삽입할 수 있고

const a = 5;
const b = 10;
console.log(`The sum is ${a + b}`); // "The sum is 15"

이렇게 내부에 표현식을 넣어 계산된 결과를 문자열로 삽입할 수 있다.
위 내용을 바탕으로 우리가 구현했던 함수를 수정해보자.

function Popup__show(no) {
  $('.popup-' + no).addClass('active');
  $('html').addClass('popup-' + no + '-actived');
}

function Popup__hide(no) {
  $('.popup-' + no).removeClass('active');
  $('html').removeClass('popup-' + no + '-actived');
}

function Popup__init(no) {
  $('.btn-popup-' + no).click(function() {
    Popup__show(no);
  });
  
  $('.popup-' + no + ', .popup-' + no + ' .popup__btn-close').click(function() {
    Popup__hide(no);
  });
  
  $('.popup-' + no + ' .popup__content').click(function() {
    return false;
  });
}

Popup__init(1);
Popup__init(2);

---->

function Popup__show(no) {
  $(`.popup-${no}`).addClass('active');
  $('html').addClass(`.popup-${no}-actived`);
}

function Popup__hide(no) {
  $(`.popup-${no}`).removeClass('active');
  $('html').removeClass(`.popup-${no}-actived`);
}

function Popup__init(no) {
  $(`.btn-popup-${no}`).click(function() {
    Popup__show(no);
  });
  
  $(`.popup-${no}, .popup-${no} .popup__btn-close`).click(function() {
    Popup__hide(no);
  });
  
  $(`.popup-${no} .popup__content`).click(function() {
    return false;
  });
}

Popup__init(1);
Popup__init(2);

테일윈드를 이용해 재구현

이번에는 처음부터 끝까지 테일윈드를 이용해 재구현해보자.

html

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<script src="https://cdn.tailwindcss.com"></script>

<div class="popup-1 popup fixed inset-0 flex items-center justify-center">
  <!--
  fixed -> position: fixed;
  inset-0 -> top: 0px;, right: 0px;, bottom: 0px;, left: 0px;
  flex -> display: flex;
  items-center -> align-items: center;
  justify-center -> justify-items: center;
  -->
  <div class="popup__content bg-white border-black border-2 max-h-full flex flex-col">
    <!--
    bg-white -> background-color: white;
    border-black -> border-color: black;
    border-2 -> border-width: 2px;
    max-h-full -> max-height: 100%;
    flex -> display: flex;
    flex-col -> flex-direction: column;
    -->
    <div class="popup__head p-2">
      <!--
      p-2 -> padding: 0.5rem;
      -->
      <div class="popup__btn-close relative w-12 h-12 ml-auto cursor-pointer">
      	<!--
      	relative -> position: relative;
      	w-12 -> width: 3rem;
        h-12 -> height: 3rem;
        ml-auto -> margin-left: auto;
        cursor-pointer -> cursor: pointer;
      	-->
      </div>
    </div>
    <div class="popup__body p-2 flex-grow overflow-y-auto">
      <!--
      p-2 -> padding: 0.5rem;
      flex-grow -> flex-grow: 1;
      overflow-y-auto -> overflow-y: auto;
      -->
      <div class="container">
        <!--
        container -> 웹의 너비에 따라 너비를 조절
        -->
        Lorem ipsum...
      </div>
    </div>
  </div>
</div>

<div class="popup-2 popup fixed inset-0 flex items-center justify-center">
  <!--
  fixed -> position: fixed;
  inset-0 -> top: 0px;, right: 0px;, bottom: 0px;, left: 0px;
  flex -> display: flex;
  items-center -> align-items: center;
  justify-center -> justify-items: center;
  -->
  <div class="popup__content bg-white border-black border-2 max-h-full flex flex-col">
    <!--
    bg-white -> background-color: white;
    border-black -> border-color: black;
    border-2 -> border-width: 2px;
    max-h-full -> max-height: 100%;
    flex -> display: flex;
    flex-col -> flex-direction: column;
    -->
    <div class="popup__head p-2">
      <!--
      p-2 -> padding: 0.5rem;
      -->
      <div class="popup__btn-close relative w-12 h-12 ml-auto cursor-pointer">
        <!--
      	relative -> position: relative;
      	w-12 -> width: 3rem;
        h-12 -> height: 3rem;
        ml-auto -> margin-left: auto;
        cursor-pointer -> cursor: pointer;
      	-->
      </div>
    </div>
    <div class="popup__body p-2 flex-grow overflow-y-auto">
      <!--
      p-2 -> padding: 0.5rem;
      flex-grow -> flex-grow: 1;
      overflow-y-auto -> overflow-y: auto;
      -->
      <div class="container">
        <!--
        container -> 웹의 너비에 따라 너비를 조절
        -->
        Lorem ipsum...
      </div>
    </div>
  </div>
</div>

<section class="section-1">
  <div class="container mx-auto">
    <!--
    container -> 웹의 너비에 따라 너비를 조절
    mx-auto -> margin-left: auto;, margin-right: auto;
    -->
    <button class="btn-popup-1">팝업1</button>
    <button class="btn-popup-2">팝업2</button>
  </div>
  <div class="container mx-auto">
    <!--
    container -> 웹의 너비에 따라 너비를 조절
    mx-auto -> margin-left: auto;, margin-right: auto;
    -->
    Lorem ipsum...
  </div>
</section>

css

.popup {
  background-color:rgba(0,0,0,0.5);
  visibility:hidden;
  opacity:0;
  transition:visibility 0.3s, opacity 0.3s;
}

.popup.active {
  visibility:visible;
  opacity:1;
}

.popup__content {
  transform:translateY(-100%);
  transition:transform 0.2s;
}

.popup.active .popup__content {
  transform:translateY(0);
}

.popup__btn-close:hover {
  transform:rotate(10deg);
}

.popup__btn-close::before,
.popup__btn-close::after {
  content:"";
  position:absolute;
  top:40%;
  left:0;
  width:100%;
  height:20%;
  background-color:black;
  transform:rotate(-45deg);
  transition: box-shadow 0.2s;
}

.popup__btn-close::after {
  transform:rotate(45deg);
}

.popup__btn-close:hover::before,
.popup__btn-close:hover::after {
  box-shadow:0 0 10px rgba(0,0,0,0.5);
}

html[class*="popup-"][class*="-actived"],
html[class*="popup-"][class*="-actived"] > body {
  overflow:hidden;
}

JS 부분은 동일

profile
🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳

0개의 댓글