반응형 웹의 구조

박은정·2022년 5월 10일
1

TIL

목록 보기
49/70
post-thumbnail

프론트엔드에서 제일 어렵다는...! CSS에 호되게 당한 뒤로 반응형 웹이 뭔지 이전에 정리해보고, 이번에는 반응형 웹페이지의 구조에 대해 알아보겠습니다.

📚 화면 사이즈에 따른 웹페이지 구조

반응형 웹의 경우, 환경이나 크기에 따라 웹사이트의 구조가 바뀌기 때문에 웹 사이트의 구조를 파악하는 것이 중요합니다.

위의 이미지는 플랫 디자인 스타일로 디자인 되었고, 아래와 같은 특징을 가집니다.

  • PC나 태블릿: 영역들이 가로로 여러 줄 배치되게 구성되어있습니다.
  • 가장 작은 화면인 모바일 화면: 영역들이 세로로 한 줄씩 배치됩니다.

그리고 이러한 특징을 토대로 미디어쿼리를 통해 화면 너비별 레이아웃을 짜면, 아래와 같이 할 수 있습니다.

여기서는 min-width를 통해 모바일 → 태블릿 → PC 디바이스 순서대로 스타일을 부여했지만,
반대로 max-width를 통해 PC → 태블릿 → 모바일 디바이스 순서대로 스타일을 부여할 수 있습니다.

/* 모바일 CSS */
#wrap {
  display: flex;
  flex-flow: column nowrap; /* nowrap은 기본 속성이기 때문에 생략해도 상관없다 */
  width: 80%;
  margin: 0 auto;
  max-width: 1200px;
}

/* 태블릿 CSS */
@media all and (min-width: 768px) {
  #wrap {
    flex-flow: row wrap;
  }
}

/* PC CSS */
@media all and (min-width: 960px) {
  #wrap {
    position: relative;
    width: 90%;
  }
}

🎤 홈페이지의 실제 내용, contents

내용들을 감싸는 container

  • 제일 큰 사이즈에서는 일정 너비까지만 확장되고 양쪽 여백이 생깁니다.
  • 모바일~태블릿에서는 일정한 좌우 margin을 제외하고 100% 차지하게 되고, 데스크탑에서는 최대너비가 존재해 화면이 커질수록 좌우 margin만 늘어납니다.

각각의 컨텐츠에 해당하는 children

  • 모바일~태블릿 화면에서 사이즈가 동일하고 데스크탑 화면에서 가로세로 비율을 유지하며 커지거나
  • 모바일~데스크탑 화면에서 모두 동일한 사이즈인 대신 한 줄에 있는 children의 개수가 늘어납니다. 예를 들면, 화면 너비가 줄어들면서 한줄에 3개의 요소가 있지만 2개, 1개로 줄어듭니다.
요소들의 너비 > container 너비 → 밑으로 내려가게 되면서 한 줄에 Element의 개수 줄어듬
  • children의 사이즈가 변하던 한 줄에 children의 개수가 변하던 children간의 간격은 일정하게 유지됩니다.

🎤 contents를 감싸는, background

배너나 메인부분의 배경이미지 (혹은 배경색) 의 너비는 좌우공백이 존재하지 않고, 화면 전체를 차지합니다.

화면 너비가 줄어들면서

  • 배경이미지의 비율을 유지하며 전체 이미지를 보여주거나
  • 큰 사이즈의 배경이미지가 양쪽을 자르면서 보였습니다.

👨‍💻 코드 탐색

저작권통향 판례를 통해 HTML코드또한 저작권 보호대상이라, 어떤 사이트를 참고했는지는 밝히지 않고 코드도 일부 수정했습니다.

화면 사이즈에 따른 contents element 레이아웃

<div class='contents'>
  <header class='header'></header>
  <div class='sub-header'></div>
  <ul class='resource'>
    <li class='card big-card'>
      <a class='image-wrapper' href=`${image-link}`>
        <img src=`${image-url}` alt=''>
      </a>
      <div class='description'></div>
    </li>
    <!--이후로는 생략-->
    <li class='card big-card'></li>
    <li class='card big-card'></li>
    <li class='card big-card'></li>
    <li class='card big-card'></li>
    <li class='card big-card'></li>
  </ul>
</div>

flex container

  • 가로방향으로 flex 스타일지정
  • 수직라인(여기서는 세로방향)으로 가운데 정렬
  • flex container의 교차(여기서는 세로방향) 시작점에서부터 줄바꿈
  • 화면너비가 630px미만으로 줄어들면 너비는 300px에 가운데 정렬을 하고, 각 사이즈별로 너비를 지정

631px ~ 767px 화면너비에서 container의 너비를 750px로 하게 되면 남는 공간이 생기는데,
이때 justify-content: center 속성을 통해 화면의 가운데정렬을 합니다.

.resource {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start; /* wrap을 했을 때 줄 간의 간격*/
  align-items: center;
  width: 300px;
  margin: 0 auto;
}

ul {
  list-style: none;
}

@media only screen and (min-width: 960px) {
  .resource {
    width: 960px;
  }
}

@media only screen and (min-width: 767px) {
  .resource {
    width: 750px;
    justify-content: center;
  }
}

@media only screen and (min-width: 630px) {
  .resource {
    width: 640px;
    margin: 0 auto;
  }
}

flex children

  • li요소에 너비지정
  • children 간의 간격을 margin으로 설정

630px이상부터는 한 줄에 두개의 children을 놓기 때문에 좌우 및 아래 마진을 각각 10px로 줬고,
630px 미만으로는 한 줄에 하나의 children을 놓기 때문에 아래마진만 10px을 주었습니다.

@media only screen and (min-width: 630px) {
  .card {
    width: 300px;
    /* margin-top: 0, margin-left & margin-right: 10px, margin-bottom: 10px */
    margin: 0 10px 10px;
  }
}

.card {
  width: 300px;
  /* 위 & 좌우 & 아래 */
  margin: 0 0 10px;
}

li {
  list-style: none;
}

한편, 글자 크기는 데스크탑과 모바일화면에서의 사이즈가 다른 것처럼 특정 breakpoint에 따른 글자크기 지정은 있겠지만 rem이나 vw단위를 써서 폰트사이즈를 지정하지는 않았습니다.

배너의 배경이미지

화면사이즈에 따라 원래 비율을 유지하며 배경이미지를 지정할 때 두 가지의 방법을 찾았습니다.

방법1

최대너비를 지정하면서 너비 100%
높이는 비율에 맞춰서 자동으로 지정합니다.

<div class='banner'>
  <video class='banner-video' loop muted autoplay poster=`${banner-image}` aria-label='Video'>
    <source src=`${video-source}` type='video/mp4'>
  </video>
  <img class=banner-mobile src=`${banner-image}` alt='' width='600' height='400'>
</div>
/* 770up.scss */
@media only screen and (min-width: 770px) {
   .banner-image {
     display: block;
   }
}

/* _base.scss */
.banner-image {
  display: none;
}


image {
  min-width: 800px;
  width: 100%;
  height: auto;
  object-fit: inherit;
}

방법2

원래 이미지 사이즈보다 클때는 background-image 속성을 통해 설정하고
이미지 사이즈보다 같거나 작은 화면에서는 내부의 이미지요소를 너비 100%로 보여줍니다.

<div class='banner' style='position: absolute;'>
  <span class='banner-item' data-counter='1' title='title' data-click-label='1' data-click-action='action'>
    <img src=`${image-url}` alt='' data-src=`${iamge-url}` width='1280'>
  </span>
</div>
.banner-item {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  background-image: url(image-url);
  background-repeat: no-repeat;
  background-size: 100%;
  background-position: center center;
  width: 100%;
  height: 100%;
}

.banner-item img {
  width: 100%;
}

@media (min-width: 71em) {
  .banner-item img {
    display: none;
  }
}

-data 속성는 따로 알아보려합니다.

🔥 배운점

회사에서 반응형 웹페이지를 만들때 flex와 grid를 막 배운 참이라 grid를 활용해야겠다 생각을 했는데, 막상 다른 사이트의 코드를 보니 화면 사이즈에 따른 레이아웃을 바꿀때에는 flex wrap 속성을 활용해야겠다 생각을 했습니다.

배경이미지의 비율을 유지하면서 사이즈를 줄이고 싶을 경우,background-size: 100% 100% 스타일을 지정하면 제일 편리하지만 이미지가 찌그러지는 현상이 발생할 수 있었습니다.

디바이스의 너비 > 이미지 사이즈 : background-image 속성으로 배경이미지를 설정하고,
디바이스의 너비 <= 이미지 사이즈 : 내부의 img요소를 width: 100%로 보여줄 수 있습니다.

반응형 웹페이지 공부는 계속..!

🤔 앞으로는 ??

웹사이어티나이키같은 유명한 사이트들 반응형 어떻게 구동하는지 코드 뜯어보면서 velog에 정리하려 합니다.

👨‍🎓 출처

profile
새로운 것을 도전하고 노력한다

0개의 댓글