responsiveBlogImage

woolee의 기록보관소·2022년 11월 5일
0

FE 기능구현 연습

목록 보기
11/33

HTML

.side-bar의 span 요소로 메뉴 버튼 생성하기
.image-grid 안에 이미지 넣기

<div class="side-bar">
    <div class="menu-toggle">
      <span></span>
      <span></span>
      <span></span>
    </div>
    <h2>BLOG</h2>

    <div class="socials">
      <ul>
        <li>
          <a href="#">FACEBOOK</a>
        </li>
        <li>
          <a href="#">INSTAGRAM</a>
        </li>
        <li>
          <a href="#">TWITTER</a>
        </li>
      </ul>
    </div>
  </div>

  <div class="image-grid">
    <div class="overlay"></div>
    <div class="image one vertical"></div>
    <div class="image two"></div>
    <div class="image three"></div>
    <div class="image four"></div>
    <div class="image five vertical"></div>
    <div class="image six horizontal"></div>
  </div>

CSS

letter-spacing : 글자 간격을 설정하기 => 음수면 좁히고, 양수면 늘리고

.side-bar의 위치를 고정하고, 높이를 100vh로 전체 차지하도록, width:10%;로 잡아서 왼쪽에 사이드바가 위치하도록.

.menu-toggle는 absolute로 부모 위치 상속받고, 부모 기준 left:50%;, trnasform:translateX(-50%);로 중간에 위치하게 하기.
flex-direction:column;으로 세로로 줄세우기

transform-origin은 회전 중심 값 설정해주는 것.
0(%),0(%)이면 박스 왼쪽 상단 모서리에 위치하고
100(%),100(%)이면 오른쪽 하단 모서리에 위치

.image-grid는 이미지가 들어갈 자리이므로 position:relative; 잡아주기.
사이드바가 10% 차지하므로 left:10%;로 시작하고, width:90% 잡아두기.

flex와 grid의 차이?
flex는 1차원 레이아웃, gird는 2차원 레이아웃을 다룬다.
repeat(반복횟수, 반복값)
gap은 행과 열 사이의 간격을 잡아주는 속성

이미지 그리드는 기본값은 repeat()을 통해 3x3으로 잡아주고

.overlay를 통해 기본적으로 도화지를 잡아주고

.image를 통해 이미지 cover로 넣어주기
grayscale은 회색조로
opacity:0;으로 잡아줬다가 js로 active가 붙으면 opacity:1;로 보여주는 인터랙션 구현

grid-row => 행 시작 / 끝 위치
예를 들어 1 / 3 이면 1에서 3까지를 의미
span이 붙으면 inline 속성으로 배치하겠다는 의미인듯.?
grid-column => 열 시작 / 끝 위치
auto면 1

@media max-width:700px
=> 가로2줄, 세로4줄, 가로2줄인 이미지를 1줄로,
@media max-width:500px
=> 가로 1줄, 세로6줄, 세로2줄인 이미지까지 1줄로,

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  letter-spacing: 2px;
}

html, 
body {
  width: 100vw;
  background-color: black;
}

a {
  color: white;
  text-decoration: none;
  font-size: 0.8rem;
}

.side-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 10%;
  color: white;
  /* background-color: red; */
}

.menu-toggle {
  position: absolute;
  top: 25px;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 25px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  cursor: pointer;
}

.menu-toggle span {
  width: 100%;
  height: 3px;
  background-color: white;
}

.side-bar h2 {
  position: absolute;
  top: 18%;
  left: 50%;
  font-size: 1.2rem;
  transform-origin: 0 0;
  transform: rotate(-90deg) translateY(-50%);
}

.socials {
  position: absolute;
  bottom: 0;
  width: 350px;
  left: 50%;
  transform-origin: 0 0;
  transform: rotate(-90deg) translateY(-50%);
}

.socials ul {
  display: flex;
  justify-content: space-around;
  list-style: none;
}

.image-grid {
  position: relative;
  left: 10%;
  width: 90%;
  height: 100vh;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 0.2rem;
}

.overlay {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(5, 102, 206, 0.112);
  pointer-events: none;
}

.image {
  opacity: 0;
  position: relative;
  background-size: cover;
  background-position: center;
  filter: grayscale(100%);
}

.image.active {
  opacity: 1;
  transition: 0.5s;
}

.vertical {
  grid-row: span 2;
}

.horizontal {
  grid-column: span 2;
}

.one {
  background-image: url(./images/one.jpg);
}
.two {
  background-image: url(./images/two.jpg);
}
.three {
  background-image: url(./images/three.jpg);
}
.four {
  background-image: url(./images/four.jpg);
}
.five {
  background-image: url(./images/five.jpg);
}
.six {
  background-image: url(./images/six.jpg);
}

@media only screen and (max-width: 700px) {
  .image-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(4, 1fr);
  }
  .horizontal {
    grid-column: auto / span 1;
  }
}

@media only screen and (max-width: 500px) {
  .side-bar {
    width: 15%;
    color: white;
    z-index: 10;
    background-color: black;
  }
  .image-grid {
    grid-template-columns: repeat(1, 1fr);
    grid-template-rows: repeat(6, 1fr);
  }
  .vertical {
    grid-row: auto / span 1;
  }
}

JS

페이지가 로드되면 이미지를 순서대로 로드하는데, 이미지 로드 속도를 idx로 잡아줘서 이미지 순서대로 좌르륵 열리는 인터랙션 구현

let images = Array.from(document.querySelectorAll('.image'));

window.addEventListener('DOMContentLoaded', (e) => {
  images.forEach((image, idx) => {
    setTimeout(() => {
      image.classList.add('active');
    }, idx * 100)
  })
})

참고

Creating A Responsive Blog Image Layout With CSS Grid
Flex 대신 Grid를 사용해 레이아웃 만들기

profile
https://medium.com/@wooleejaan

0개의 댓글