[Javascript 30] 5. Flexbox + JS Image Gallery

💗 [Javascript 30] 5. Flexbox + JS Image Gallery

✔ 참고 블로그 : CSS flexbox 쉽게 이해하기
✔ 참고 공식 문서 : DOMTokenList.toggle Document
✔ 참고 공식 문서 : Poiemaweb Flex-box

✔ 레이아웃 짜기.

❗❗ 레이아웃 처럼 만들기 위해서 진행해야하는 과정 ❗❗
1. 3개의 구역으로 나누어서 배경화면을 넣어준다.
2. 1개의 배경화면 구역에 text 3개를 1/3 위치에 넣어준다.

❗ 1,2번 과정을 수행하기 위해서는 flex-box가 필요하다. ❗
새로운 layout 요소이다. 요소의 사이즈가 불명확하거나 동적으로 변화할 때에도 유연한 레이아웃을 실현할 수 있다. 복잡한 레이아웃이라도 적은 코드로 보다 간단하게 표현할 수 있다.

✔ HTML 코드 작성하기.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FlexBox + JS Image Gallery</title>
    <link rel="stylesheet" href="flexbox js img gallery.css" />
  </head>
  <body>
    <div class="flex-container">
      <div class="flex-item item1">
        <div class="item-text">Blue</div>
        <div class="item-text">Cloud</div>
        <div class="item-text">White</div>
      </div>
      <div class="flex-item item2">
        <div class="item-text">Beautiful</div>
        <div class="item-text">Hot Air Ballon</div>
        <div class="item-text">Between Sky And Soil</div>
      </div>
      <div class="flex-item item3">
        <div class="item-text">Flower</div>
        <div class="item-text">Tulip</div>
        <div class="item-text">Fresh</div>
      </div>
    </div>
    <script src="flexbox js img gallery.js" defer></script>
  </body>
</html>

✔ CSS로 스타일 지정하기.

일단 모든 텍스트를 보여주고, 모두 원하는 위치에 놓아주고 원하는 색상으로 만들어주기.

그런 다음에 transform의 translateY를 적용하여 글씨를 평소에는 안 보이도록 만들어준다. 파일 .js에서 클릭시에 보이도록 만들어줄 예정이다.
더 정확하게 말한다면, 클릭하면 가운데 글씨가 커지면서 배경도 덩달아 커지면서 위, 아래에 위치한 text들이 나와야 한다.

@import "reset.css";
@import url("https://fonts.googleapis.com/css2?family=Inspiration&display=swap");

html {
  font-family: "Inspiration", cursive;
  font-weight: bolder;
  font-size: 70px;
  text-align: center;
}

.flex-container {
  display: flex;
  flex-direction: row;
}

.flex-item {
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 100vh;
  align-items: center;
  height: 100vh;
}

.item1 {
  background: url(cloud.jpg);
  background-size: cover;
  flex-direction: column;
}

.item2 {
  background: url("hot air balloon.jpg");
  background-size: cover;
  flex-direction: column;
}

.item3 {
  background: url("tulip.jpg");
  background-size: cover;
  flex-direction: column;
}

.item-text {
  flex: 1;
  padding-top: 25%; /* text-align이 안 먹혀서 padding을 이용해주었다. */
  color: #f6f7fb;
}

.item-text:last-child {
  color: #ed5466;
  transform: translateY(-100vh);
}

.item-text:first-child {
  color: #66ed54;
  transform: translateY(-100vh);
}

.item2 > .item-text:nth-child(2) {
  color: black;
}

💙 flex-box 주의해야할 점
1. div 태그는 block 요소이기 때문에, 수직 방향으로 정렬된다.
2. 수직 방향을 수평 방향으로 정렬하고 싶다면, 그 위에 있는 부모 태그에 display: flex 처리를 해준 뒤에, 수평 방향인 flex-direction: row를 처리해주면 된다.
3. 그 다음에 해당 태그에도 동일하게 처리해주면 된다. ➕ 항상 인과 관계를 생각해줘야 한다. 어디에 적용을 해야 될지를 고민해줘야 한다.
(인과 관계 예시) text를 column 방향으로 정렬하기 위해서는, 그 위에 있는 부모 태그 자체를 column 방향으로 정렬을 해준 뒤에 text를 확인해보자. 그러면, column 방향으로 잘 정렬되어있을 것이다.

✔ 참고 공식 문서 : Flex와 상수 : flex-box의 크기를 조절해준다.

✔ JAVASCRIPT 코드 작성하기.

💙 JavaScript 코드 작성하는 과정
1. 클릭 시에 가운데에 있는 text가 커지면서, 그 영역도 같이 커져야한다.
2. (이 부분이 이해하기 조금 까다로움) 전환이 완료되면, 위에 있는 단어와 아래에 있는 단어를 가져와야한다.

const items = document.querySelectorAll(".flex-item");
// console.log(items);

function toggleOpen(event) {
  // console.log(event);
  // console.log(this);
  // console.log("hello"); 클릭 시 함수가 잘 돌아가고 있다.
  // console.log(this.classList.toggle("open")); 
  // true -> false -> true -> false .. 잘 뜨고 있다.
  // 근데 문제는 클릭하는 순간 true가 뜨기는 하지만, 작아진다!
  this.classList.toggle("open");
}

// items.forEach((item) => console.log(item)); // typeof item : object
items.forEach((item) => item.addEventListener("click", toggleOpen));

아 근데 문제는 내가 원하는 모양대로 나오고 있지 않다.
근데 어디가 잘못되었는지는 잘 모르겠다... 다시 html & css부터 뜯어봐야겠다...

✔ 최종 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FlexBox + JS Image Gallery</title>
    <link rel="stylesheet" href="flexbox js img gallery.css" />
  </head>
  <body>
    <div class="flex-container">
      <div class="flex-item item1">
        <div class="item-text">Blue</div>
        <div class="item-text">Cloud</div>
        <div class="item-text">White</div>
      </div>
      <div class="flex-item item2">
        <div class="item-text">Beautiful</div>
        <div class="item-text">Hot Air Ballon</div>
        <div class="item-text">Between Sky And Soil</div>
      </div>
      <div class="flex-item item3">
        <div class="item-text">Flower</div>
        <div class="item-text">Tulip</div>
        <div class="item-text">Fresh</div>
      </div>
    </div>
    <script src="flexbox js img gallery.js" defer></script>
  </body>
</html>
@import "reset.css";
@import url("https://fonts.googleapis.com/css2?family=Inspiration&display=swap");

html {
  font-family: "Inspiration", cursive;
  font-weight: bolder;
  font-size: 70px;
  text-align: center;
}

.flex-container {
  display: flex;
  flex-direction: row;
  flex: 1;
}

.flex-item {
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 100vh;
  align-items: center;
  height: 100vh;
  flex: 1; /* 꼭 적어주기. */
}

/* 눌렀을 때 (클릭하였을 때), 변화하는 스타일을 지정해주기. */

.flex-item.open {
  flex: 3;
  font-size: 90px;
}

.item1 {
  background: url("cloud.jpg");
  background-size: cover;
  flex-direction: column;
  flex: 1;
}

.item2 {
  background: url("hot air balloon.jpg");
  background-size: cover;
  flex-direction: column;
  flex: 1;
}

.item3 {
  background: url("tulip.jpg");
  background-size: cover;
  flex-direction: column;
  flex: 1;
}

.item-text {
  flex: 1;
  padding-top: 25%; /* text-align이 안 먹혀서 padding을 이용해주었다. */
  color: #f6f7fb;
}

.item-text {
  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);
}

/* 이 부분이 눌렀을 때 변화를 줄 수 있는 부분이다.  */

.item-text > *:first-child {
  transform: translateY(-100%); /* 스크린에서 벗어나게 만들어준다. */
}

.item-text > *:last-child {
  transform: translateY(100%); /* 스크린에서 벗어나게 만들어준다. */
}

.item-text.open-active > *:first-child {
  transform: translateY(0);
}

.item-text.open-active > *:last-child {
  transform: translateY(0);
}

.item-text:last-child {
  color: #ed5466;
}

.item-text:first-child {
  color: #66ed54;
}

.item2 > .item-text:nth-child(2) {
  color: black;
}
const items = document.querySelectorAll(".flex-item");
// console.log(items);

function toggleOpen(event) {
  // console.log(event);
  // console.log(this);
  // console.log("hello"); 클릭 시 함수가 잘 돌아가고 있다.
  // console.log(this.classList.toggle("open")); 
  // true -> false -> true -> false .. 잘 뜨고 있다.
  // 근데 문제는 클릭하는 순간 true가 뜨기는 하지만, 작아진다!
  this.classList.toggle("open");
}

// items.forEach((item) => console.log(item)); // typeof item : object
items.forEach((item) => item.addEventListener("click", toggleOpen));

😀 마무리...

❗❗ 문제점 ❗❗
1. flex-box를 중첩해서 사용하였더니, 제대로 되지 않은 것 같다.
2. transition과 transform을 이용해서 animation을 주려고 했는데 제대로 되지 않았다. ➕ cubic-bezier의 사용법
3. 원하는 결과값이 html과 css에서 나오지 않았다.

➕➕ 공부해야되는 부분

  • flex-box를 중복해서 사용하는 법 공부하기.
  • transition과 transform을 이용해서 애니메이션 효과 주기. ➕ cubic-bezier의 사용법

좋은 웹페이지 즐겨찾기