html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!--jQuery라이브러리 사용을 위한 링크-->
<!--팝업창-->
<div class="popup">
<div class="popup__head">
<button class="popup__btn-close">X</button>
</div>
</div>
<!--container-->
<div class="con">
<button class="btn-popupshow">팝업 1</button>
Lorem.../* <- * 50 생략 *
</div>
css
.con{
width:1000px;
margin:0 auto;
}
/*container의 너비를 설정하고 가운데정렬해준다.*/
.popup{
width:300px;
height:300px;
border:10px solid black;
background-color:white;
/*너비, 높이, 배경색, 보더 설정*/
position:fixed;
/*스크롤을 내려도 팝업창의 위치는 그대로 가운데여야하기 때문에 position값을
absolute대신에 fixed를 사용한다.fixed -> 고정*/
top:50%;
left:50%;
transform:translate(-50%,-50%);
/*중앙 정렬*/
box-shadow:10px 10px 30px rgba(0,0,0,0.7);
display:none;
/*버튼을 누르기 전 기본상태는 안보여야 하므로 display:none;으로 해준다.*/
}
.popup__btn-close{
display:block;
margin:5px;
margin-left:auto;
/*팝업창 속 X버튼 css*/
}
/*.popup클래스와 .active클래스를 동시에 가지고 있는 태그에게만 적용되는 속성*/
.popup.active{
display:block;
}
/*display속성을 block으로 만드는 .active클래스 속성.*/
JS
console.clear();
//버튼을 누르면 작동하는 함수
function popup_open_close() {
let has = $('.popup').hasClass('active');
/*변수 has를 선언하고 값을 명제로 주는데,
.popup클래스를 가지고 있는 태그가 .active태그를 가지고 있으면 참,
가지고 있지 않으면 거짓이다.*/
console.log(has);
/*변수 has값 확인을 위해 console창에 출력해준다.*/
if(has){
$('.popup').removeClass('active');
/*만약 has가 참이라면(.popup클래스를 가지고 있는 태그가 .active태그를 가지고 있으면)
.popup, .active클래스를 동시에 가지고 있는 태그에게서 .active태그를 제거해준다.*/
}
else{
$('.popup').addClass('active');
/*만약 has가 거짓이라면(.popup클래스를 가지고 있는 태그가 .active태그를 가지고 있지 않으면)
.popup클래스를 가지고 있는 태그에게.active태그를 추가해준다.*/
}
}
코드를 입력하세요
$('.popup__btn-close').click(popup_open_close);
//.popup__btn-close(팝업창 속 X버튼)를 클릭하면 popup_open_close를 실행한다.
$('.btn-popupshow').click(popup_open_close);
//.btn-popupshow(팝업 버튼)를 클릭하면 popup_open_close를 실행한다.
이번에는 배경색도 흐릿하게 바뀌고 X버튼에 hover시 돌아간다. 그리고 팝업이 위에서부터 생기면서 내려오는 것을 구현해보자.
html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!--jQuery사용을 위한 코드-->
<!--팝업-->
<div class="popup">
<div class="popup__content">
<!--부모 .popup클래스는 배경색을 흐리게 만드느데 사용하고 popup__content를 만들어
새로 팝업창을 만든다.-->
<!--팝업 헤더-->
<div class="popup__head">
<div class="popup__btn-close"></div>
</div>
<!--팝업 내용-->
<div class="popup__body">
<div class="con">
Lorem ...
</div>
</div>
</div>
</div>
<section class="section-1">
<div class="con">
<!--팝업 생성 버튼-->
<button class="btn-popup-1">팝업 1</button>
Lorem ipsum...
</div>
</section>
css
/*노말라이즈*/
body, ul, li {
margin:0;
padding:0;
list-style:none;
}
a {
color:inherit;
text-decoration:none;
}
/*컨텐츠 너비만들고 가운데로 옮겨 양 옆 여백만들기*/
.con {
margin-left:auto;
margin-right:auto;
}
.con {
max-width:1200px;
}
.popup {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
background-color:rgba(0,0,0,0.5);
/*웹을 가득 채우고 배경색을 흐린 검정색으로 만든다.*/
align-items:center;
justify-content:center;
display:flex;
/*display를 flex로 만들어 팝업창(.popup__content)를 정가운데로 옮긴다.*/
opacity:0;
visibility:hidden;
/*불투명도를 0으로 만들어 평소에 보이지 않게 만들고 visivility로 숨긴다. .active클래스가 추가되면 나타나게 한다.*/
transition: opacity .3s, visibility .3s;
/*opacity와 visibility에 재생시간을 부여한다.*/
}
.popup.active {
opacity:1;
visibility:visible;
/*팝업을 다시 나타나게 하는 클래스를 만든다.*/
}
.popup__content {
min-width:200px;
min-height:200px;
/*최소 너비, 높이 지정*/
background-color:white;
border:2px solid black;
transform:translateY(-100%);
/*평소에는 팝업창이 위에 있게 만들고 .active클래스 추가로 가운데 오게 만든다.*/
transition: transform .3s;
/*transform에 재생시간을 부여한다.*/
}
/*.popup과 .active클래스를 모두 가지고 있는 태그의 후손이면서
.popup__content를 가지고 있는 태그에게 적용하는 속성*/
/*원래는 .popup이 .active클래스를 가지고 있지 않으므로 이 속성이 활성화
되지 않지만 JS를 이용해 .popup이 .active클래스를 갖는 순간 활성화된다.*/
/*단순히 .active클래스를 라이브러리처럼 사용하는 것이 아니라 관련된 클래스를 만들어
클래스를 추가하는 것만으로 여러 css속성이 추가되도록 구현한 것!!*/
.popup.active .popup__content {
transform:translateY(0);
/*다시 원래 자리로 오게하는 클래스를 만든다.*/
}
.popup__head {
padding:10px;
}
.popup__btn-close {
width:30px;
height:30px;
/*X표를 만들기위해 네모 틀을 만든다.*/
margin-left:auto;
/*.popup__head의 오른쪽에 붙인다.*/
position:relative;
/*before, after태그를 absolute로 하고 이 태그를 유령의 집으로 만든다.*/
cursor:pointer;
transition:transform 0.3s;
/*transform(rotate)에 재생시간을 부여한다. 돌아가는 애니매이션 구현*/
}
.popup__btn-close:hover {
transform:rotate(185deg);
/*hover시 185도 돌아간다.*/
}
.popup__btn-close::before,
.popup__btn-close::after {
content:"";
background-color:black;
position:absolute;
top:40%;
left:0;
width:100%;
height:20%;
transform:rotate(45deg);
/*before, after태그를 막대기처럼 만들어 하나는 45도 하나는 -45도 기울여
X표처럼 만든다.*/
transition:box-shadow 0.3s;
/*box-shadow에 재생시간을 부여한다.*/
}
.popup__btn-close::after {
transform:rotate(-45deg);
}
.popup__btn-close:hover::before,
.popup__btn-close:hover::after {
box-shadow:0 0 3px black;
/*hover시 그림자가 생기도록 한다.*/
}
.popup__body {
padding:0 10px;
/*팝업 내용에 양엽 padding값 부여*/
}
JS
console.clear();
$('.btn-popup-1').click(function() {
$('.popup').addClass('active');
});
/*팝업 1 버튼(.btn-popup-1)을 클릭시 팝업(.popup)에게 .active클래스를 부여한다.*/
$('.popup__btn-close').click(function() {
$('.popup').removeClass('active');
});
/*X버튼(.popup__btn-close)을 클릭시 팝업(.popup)에게 .active클래스를 제거한다.*/
이 속성은 transform속성 중에서 요소를 회전 시킬 수 있는 속성이다.
selector{ transform: rotate(각도) }
보통 radian과 degree를 사용하는데 radian은 rad, degree는 deg으로 사용한다.
180도 = 180deg = 3.142..rad
우리가 위 코드에서 팝업창의 평소상태를 보이지 않게 만들 때 전에 배웠던 display: none;을 생각할 것이다. 하지만 클릭했을 때 transition을 이용해야 하는데 아쉽게도 display: none;은 애니메이션 효과가 나타나지 않는다.
그럼 opacity속성을 사용해야 할까? 반은 정답이다. 하지만 가장 큰 문제가 있다.
opacity를 사용하면 투명하게만 보이기 때문에 말 그대로 보이지만 않을 뿐 그 레이어는 그대로 있다. 그래서 .con안에 있는 팝업 1 버튼을 누를 수 없다는 것이다.
그래서 우리는 opacity와 함께 visibillity속성을 사용한다. visibillity속성은 태그의 가시성을 결정하고
hidden값을 사용하면 요소를 숨겼을때 hidden으로 숨긴 요소의 아래에 있는 요소의 제어를 방해하지 않는다.transition은 수치로 나타낼 수 없는 속성에는 적용되지 않는다. visibillity는 숨기고 나타낼 뿐 수치는 없다.