[JavaScript30] ๐ท 05. FLEX PANEL GALLERY
๐ท 05. FLEX PANEL GALLERY
flex-box๋ฅผ ์ด์ฉํ ๋ ์ด์์ ๋ฐ ํจ๊ณผ๋ฅผ ๊ณต๋ถ.
์ด๋ฏธ์ง๋ฅผ ํด๋ฆญํ๋ฉด ์ด๋ฏธ์ง์ ๊ธ์๊ฐ ์ปค์ง๊ณ , ์ฒซ๋ฒ์งธ์ ๋ง์ง๋ง ๊ธ์๊ฐ ๊ฐ๊ฐ ์์๋์์ ๋ฑ์ฅํจ.
์ด๊ธฐ์ฝ๋
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Flex Panels ๐ช</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
</head>
<body>
<style>
html{
box-sizing: border-box;
background:#ffc600;
font-family: 'helvetica neue';
font-size:20px;
font-weight: 200;
}
body{
margin:0;
}
*,*:befor, *:after{
box-sizing:inherit;
}.panels{
min-height:100vh;
overflow:hidden;
}.panel{
background:#6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color:#fff;
text-align:center;
align-items:center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
}
.panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
.panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
.panel > * {
margin: 0;
width: 100%;
transition: transform 0.5s;
}
.panel p {
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
font-size: 40px;
}
</style>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
<script>
</script>
</body>
</html>
์ด๊ธฐํ๋ฉด
๐ ์๋ก ์๊ฒ ๋ ๊ฒ
๐ display: flex;
๊ธฐ์กด ๋ฐฉ์
<div class="clearFix">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<style>
.box{ float:left; }
.clearFix::after{
display:block;
content:"";
clear:both;
}
</style>
flex ๋ฐฉ์
<div class="box-container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<style>
.box-container{
display:flex;
}
</style>
์ํ์ด ๋ ์์์ flex์ ์ฉ.
Flex๋ ์์์ ํฌ๊ธฐ๊ฐ ๋ถ๋ถ๋ช ํ๊ฑฐ๋ ๋์ ์ธ ๊ฒฝ์ฐ์๋, ๊ฐ ์์๋ฅผ ์ ๋ ฌ ํ ์ ์๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํจ.
์์ฑ | ์๋ฏธ |
---|---|
display | Flex Container๋ฅผ ์ ์ |
flex-flow | flex-direction ์ flex-wrap ์ ๋จ์ถ ์์ฑ |
flex-direction | Flex Items์ ์ฃผ ์ถ(main-axis)์ ์ค์ |
flex-wrap | Flex Items์ ์ฌ๋ฌ ์ค ๋ฌถ์(์ค ๋ฐ๊ฟ) ์ค์ |
justify-content | ์ฃผ ์ถ(main-axis)์ ์ ๋ ฌ ๋ฐฉ๋ฒ์ ์ค์ |
align-content | ๊ต์ฐจ ์ถ(cross-axis)์ ์ ๋ ฌ ๋ฐฉ๋ฒ์ ์ค์ (2์ค ์ด์) |
align-items | ๊ต์ฐจ ์ถ(cross-axis)์์ Items์ ์ ๋ ฌ ๋ฐฉ๋ฒ์ ์ค์ (1์ค) |
flex-direction
๊ฐ | ์๋ฏธ | ๊ธฐ๋ณธ๊ฐ |
---|---|---|
row | Itmes๋ฅผ ์ํ์ถ(์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก)์ผ๋ก ํ์ | row |
row-reverse | Items๋ฅผ row ์ ๋ฐ๋ ์ถ์ผ๋ก ํ์ | |
column | Items๋ฅผ ์์ง์ถ(์์์ ์๋๋ก)์ผ๋ก ํ์ | |
column-reverse | Items๋ฅผ column ์ ๋ฐ๋ ์ถ์ผ๋ก ํ์ |
justify-content
์๋ฏธ | ๊ธฐ๋ณธ๊ฐ | |
---|---|---|
flex-start | Items๋ฅผ ์์์ (flex-start)์ผ๋ก ์ ๋ ฌ | flex-start |
flex-end | Items๋ฅผ ๋์ (flex-end)์ผ๋ก ์ ๋ ฌ | |
center | Items๋ฅผ ๊ฐ์ด๋ฐ ์ ๋ ฌ | |
space-between | ์์ Item์ ์์์ ์, ๋ง์ง๋ง Item์ ๋์ ์ ์ ๋ ฌ๋๊ณ ๋๋จธ์ง Items๋ ์ฌ์ด์ ๊ณ ๋ฅด๊ฒ ์ ๋ ฌ๋จ | |
space-around | Items๋ฅผ ๊ท ๋ฑํ ์ฌ๋ฐฑ์ ํฌํจํ์ฌ ์ ๋ ฌ |
flex
Item์ ๋๋น(์ฆ๊ฐ, ๊ฐ์, ๊ธฐ๋ณธ)์ ์ค์ ํ๋ ๋จ์ถ ์์ฑ.
๊ฐ | ์๋ฏธ | ๊ธฐ๋ณธ๊ฐ |
---|---|---|
flex-grow | Item์ ์ฆ๊ฐ ๋๋น ๋น์จ์ ์ค์ | 0 |
flex-shrink | Item์ ๊ฐ์ ๋๋น ๋น์จ์ ์ค์ | 1 |
flex-basis | Item์ (๊ณต๊ฐ ๋ฐฐ๋ถ ์ ) ๊ธฐ๋ณธ ๋๋น ์ค์ | auto |
flex: ์ฆ๊ฐ๋๋น ๊ฐ์๋๋น ๊ธฐ๋ณธ๋๋น
.item{
flex: 1 1 20px; /* ์ฆ๊ฐ๋๋น ๊ฐ์๋๋น ๊ธฐ๋ณธ๋๋น
flex: 1 1; /* ์ฆ๊ฐ๋๋น ๊ฐ์๋๋น */
flex: 1 20px; /* ์ฆ๊ฐ๋๋น ๊ธฐ๋ณธ๋๋น (๋จ์๋ฅผ ์ฌ์ฉํ๋ฉด flex-basis๊ฐ ์ ์ฉ๋จ.) */
}
flex:1 => flex-grow: 1๊ณผ ๋์ผ.
์ฐธ๊ณ :
- https://heropy.blog/2018/11/24/css-flexible-box/
- https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
๐ ๊ณผ์
๐ 1. display:flex;
์ฝ๋๊ตฌ์กฐ๋ฅผ ๋ถ์ํ๊ณ , display:flex์ ์ฉ.
.panels{
min-height:100vh;
overflow:hidden;
}
์ ์ฉ ํ ํ๋ฉด
๐ 2. ๊ฐ ์์๋ค์ ํฌ๊ธฐ๋ฐ ๋ด์ฉ์ ์์น ์กฐ์
.panel{
~~~ ๊ธฐ๋ณธ์ฝ๋ ~~~
display:flex;
flex:1;
justify-content: center;
align-items:center;
flex-direction: column;
}
display: flex
: display์์ฑ์ flex๋ก ์ค์
flex: 1
: ๋ธ๋ผ์ฐ์ ํฌ๊ธฐ์ ๋ง์ถฐ ๋ชจ๋ ํจ๋ ํฌ๊ธฐ๊ฐ ๋์ผํ๊ฒ ์ค์ ๋จ.
justify-content: center
: ์ํ ์ ๋ ฌ
align-items: center;
: ์์ง ์ ๋ ฌ
flex-direction: column
: ์ ๋ ฌ ์ถ์ ์ธ๋ก๋ก ๋ฐ๊ฟ. ๊ธฐ๋ณธ๊ฐ์ row
ํจ๋ ์์ ๊ตฌ์ฑ์์๋ ์ ๋ ฌ
.panel > * {
~~~ ๊ธฐ๋ณธ์ฝ๋ ~~~
/* border:1px solid red; */
display:flex;
flex:1 0 auto;
justify-content: center;
align-items:center;
}
๐ 3. ํจ๊ณผ ์ ์ฉ
.panel > *:first-child {transform: translateY(-100%);}
.panel.open-active > *:first-child {transform: translateY(0);}
.panel > *:last-child {transform: translateY(100%);}
.panel.open-active > *:last-child {transform: translateY(0);}
panel์ ์ฒซ๋ฒ์งธ ์์์ ์์ง ์์น๋ฅผ ์๋ก -100%ํด์ ์ฎ๊ฒจ ์จ๊ธฐ๊ณ ,
๋ง์ง๋ง ์์๋ฅผ ์๋๋ก +100%ํด์ ์ฎ๊ฒจ ์จ๊ธฐ๊ฒ ์ค์ ํ
open-activceํด๋์ค๊ฐ ์๊ธฐ๊ฒ ๋๋ฉด ์ ์๋ฆฌ๋ก ๋์์ค๊ฒ ์ฝ๋๋ฅผ ์์ฑ.
๐ 4. ์๋ฐ์คํฌ๋ฆฝํธ ์์ฑ
<script>
const panels = document.querySelectorAll('.panel');
function toggleOpen(){
this.classList.toggle('open');
}
function toggleActive(e){
console.log(e.propertyName); // flex-grow, font-size
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active');
}
}
panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
</script>
const panels
์ .panel
์ ๋ชจ๋ ์์๋ฅผ ๋ค ๋ด๋๋ค.
panel๊ฐ๊ฐ๋ง๋ค click์ด๋ฒคํธ๋ก toggleOpen์ ๋์. ๋ณํ๊ฐ๋๋ ๋ toggleActive๋ฅผ ๋์์ํค๊ฒ ํจ.
๊ทธ๋ฌ๋ ์๋ ์ฌ์ง์ฒ๋ผ ๋จ์ํ ํ ๊ธ์ํค๊ธฐ๋๋ฌธ์ ๋๋ค ์ปค์ง๊ฒ ๋๋ค.
๐ 5. ์ถ๊ฐ ์์
function toggleOpen(){
panels.forEach(panel => panel.classList.remove('open'));
this.classList.toggle('open');
}
toggleOpen์์ toggle์ด ๋๊ธฐ์ , ๋ชจ๋ panel๋ค์ openclass๋ฅผ ์ง์ฐ๊ณ , open์ ์ถ๊ฐํ๊ฒ ํ๋ฉด ๋จ.
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([JavaScript30] ๐ท 05. FLEX PANEL GALLERY), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@cjh951114/JavaScript30-05.-FLEX-PANEL-GALLERY์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค