[JavaScript30] ๐Ÿ“ท 05. FLEX PANEL GALLERY

40125 ๋‹จ์–ด JavaScriptjavascript30JavaScript

๐Ÿ“ท 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๋Š” ์š”์†Œ์˜ ํฌ๊ธฐ๊ฐ€ ๋ถˆ๋ถ„๋ช…ํ•˜๊ฑฐ๋‚˜ ๋™์ ์ธ ๊ฒฝ์šฐ์—๋„, ๊ฐ ์š”์†Œ๋ฅผ ์ •๋ ฌ ํ•  ์ˆ˜ ์žˆ๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•จ.

์†์„ฑ์˜๋ฏธ
displayFlex Container๋ฅผ ์ •์˜
flex-flowflex-direction์™€ flex-wrap์˜ ๋‹จ์ถ• ์†์„ฑ
flex-directionFlex Items์˜ ์ฃผ ์ถ•(main-axis)์„ ์„ค์ •
flex-wrapFlex Items์˜ ์—ฌ๋Ÿฌ ์ค„ ๋ฌถ์Œ(์ค„ ๋ฐ”๊ฟˆ) ์„ค์ •
justify-content์ฃผ ์ถ•(main-axis)์˜ ์ •๋ ฌ ๋ฐฉ๋ฒ•์„ ์„ค์ •
align-content๊ต์ฐจ ์ถ•(cross-axis)์˜ ์ •๋ ฌ ๋ฐฉ๋ฒ•์„ ์„ค์ •(2์ค„ ์ด์ƒ)
align-items๊ต์ฐจ ์ถ•(cross-axis)์—์„œ Items์˜ ์ •๋ ฌ ๋ฐฉ๋ฒ•์„ ์„ค์ •(1์ค„)

flex-direction

๊ฐ’์˜๋ฏธ๊ธฐ๋ณธ๊ฐ’
rowItmes๋ฅผ ์ˆ˜ํ‰์ถ•(์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ)์œผ๋กœ ํ‘œ์‹œrow
row-reverseItems๋ฅผ row์˜ ๋ฐ˜๋Œ€ ์ถ•์œผ๋กœ ํ‘œ์‹œ
columnItems๋ฅผ ์ˆ˜์ง์ถ•(์œ„์—์„œ ์•„๋ž˜๋กœ)์œผ๋กœ ํ‘œ์‹œ
column-reverseItems๋ฅผ column์˜ ๋ฐ˜๋Œ€ ์ถ•์œผ๋กœ ํ‘œ์‹œ

justify-content

์˜๋ฏธ๊ธฐ๋ณธ๊ฐ’
flex-startItems๋ฅผ ์‹œ์ž‘์ (flex-start)์œผ๋กœ ์ •๋ ฌflex-start
flex-endItems๋ฅผ ๋์ (flex-end)์œผ๋กœ ์ •๋ ฌ
centerItems๋ฅผ ๊ฐ€์šด๋ฐ ์ •๋ ฌ
space-between์‹œ์ž‘ Item์€ ์‹œ์ž‘์ ์—, ๋งˆ์ง€๋ง‰ Item์€ ๋์ ์— ์ •๋ ฌ๋˜๊ณ  ๋‚˜๋จธ์ง€ Items๋Š” ์‚ฌ์ด์— ๊ณ ๋ฅด๊ฒŒ ์ •๋ ฌ๋จ
space-aroundItems๋ฅผ ๊ท ๋“ฑํ•œ ์—ฌ๋ฐฑ์„ ํฌํ•จํ•˜์—ฌ ์ •๋ ฌ

flex

Item์˜ ๋„ˆ๋น„(์ฆ๊ฐ€, ๊ฐ์†Œ, ๊ธฐ๋ณธ)์„ ์„ค์ •ํ•˜๋Š” ๋‹จ์ถ• ์†์„ฑ.

๊ฐ’์˜๋ฏธ๊ธฐ๋ณธ๊ฐ’
flex-growItem์˜ ์ฆ๊ฐ€ ๋„ˆ๋น„ ๋น„์œจ์„ ์„ค์ •0
flex-shrinkItem์˜ ๊ฐ์†Œ ๋„ˆ๋น„ ๋น„์œจ์„ ์„ค์ •1
flex-basisItem์˜ (๊ณต๊ฐ„ ๋ฐฐ๋ถ„ ์ „) ๊ธฐ๋ณธ ๋„ˆ๋น„ ์„ค์ •auto
flex: ์ฆ๊ฐ€๋„ˆ๋น„ ๊ฐ์†Œ๋„ˆ๋น„ ๊ธฐ๋ณธ๋„ˆ๋น„
.item{
	flex: 1 1 20px; /* ์ฆ๊ฐ€๋„ˆ๋น„ ๊ฐ์†Œ๋„ˆ๋น„ ๊ธฐ๋ณธ๋„ˆ๋น„
	flex: 1 1; /* ์ฆ๊ฐ€๋„ˆ๋น„ ๊ฐ์†Œ๋„ˆ๋น„ */
	flex: 1 20px; /* ์ฆ๊ฐ€๋„ˆ๋น„ ๊ธฐ๋ณธ๋„ˆ๋น„ (๋‹จ์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด flex-basis๊ฐ€ ์ ์šฉ๋จ.) */
}

flex:1 => flex-grow: 1๊ณผ ๋™์ผ.

์ฐธ๊ณ  :

๐ŸŒ ๊ณผ์ •

๐Ÿ‘‰ 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์„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ํ•˜๋ฉด ๋จ.

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ