프론트엔드에서 제일 어렵다는...! 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%;
}
}
모바일~태블릿
에서는 일정한 좌우 margin을 제외하고 100% 차지하게 되고, 데스크탑
에서는 최대너비가 존재해 화면이 커질수록 좌우 margin만 늘어납니다.모바일~태블릿
화면에서 사이즈가 동일하고 데스크탑
화면에서 가로세로 비율을 유지하며 커지거나요소들의 너비 > container 너비 → 밑으로 내려가게 되면서 한 줄에 Element의 개수 줄어듬
배너나 메인부분의 배경이미지 (혹은 배경색) 의 너비는 좌우공백이 존재하지 않고, 화면 전체를 차지합니다.
화면 너비가 줄어들면서
저작권통향 판례를 통해 HTML코드또한 저작권 보호대상이라, 어떤 사이트를 참고했는지는 밝히지 않고 코드도 일부 수정했습니다.
<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>
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;
}
}
li
요소에 너비지정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
단위를 써서 폰트사이즈를 지정하지는 않았습니다.
화면사이즈에 따라 원래 비율을 유지하며 배경이미지를 지정할 때 두 가지의 방법을 찾았습니다.
최대너비를 지정하면서 너비 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;
}
원래 이미지 사이즈보다 클때는 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에 정리하려 합니다.