이번 포스팅에서는 반응형 웹에 대해 정리하겠습니다.
과거의 웹사이트들은 데스크탑 컴퓨터를 통해서 이용하는 경우가 대부분이었습니다. 웹사이트를 제작하는 개발자들은 데스크탑에 최적화된 화면만 구성하면 이용자들이 웹사이트를 이용하는데에는 불편함이 없었습니다.
이후 전자기기의 발전으로 인해 데스크탑 뿐만 아니라 태블릿, 스마트폰 등의 전자기기에서 웹에 접속할 수 있게 되었지만, 전자기기들의 화면의 크기가 다양한 탓에 여러가지 버전의 웹페이지를 만들어야 하는 경우가 발생하게 됩니다. 이러한 불편함을 해결하기 위해 반응형 웹페이지가 탄생합니다.
반응형 웹은 위의 예시처럼 하나의 URL을 기반으로 화면이 바뀝니다. 반응형 웹 디자인은 유연한 레이아웃에 대응하여 항상 최적의 화면을 제공함으로써 다양한 스크린 사이즈를 지닌 디바이스에 적응할 수 있습니다.
그러나 위의 예시처럼 특정 장치에 최적화된 페이지로 연결되는 별도의 URL이 있다면 반응형 웹이라고 부르지 않습니다. 특정 장치에 연결이 되는 별도의 URL은 모바일의 경우 대개 m.domainname.com 같은 식으로, 도메인 앞에 모바일을 의미하는 “m”을 붙임으로써 구분합니다. 특정 장치에 연결이 되는 별도의 URL과 화면이 구비된 웹 사이트의 경우, 데스크탑 버전의 웹 사이트를 띄운 브라우저를 줄였을 때 반응하지 않는다는 특징이 있습니다.
이러한 반응형 웹에는 장점과 단점이 동시에 공존하고 있습니다.
하나의 콘텐츠에 오직 하나의 HTML 소스만 있기 때문에 하나의 소스를 수정하면 모든 스크린 사이즈에 맞춰 컨텐츠가 최적화되기 때문에 유지보수가 효율적 입니다. 웹페이지 내용을 수정해야 할 때도 하나의 페이지에서만 적용해도 동일하게 반영되고, 하나의 소스 코드로 관리가 가능하기 때문에 초기 개발 비용 및 유지 관리 비용의 절감 효과를 가져올 수 있습니다. 또한 사용자 입장에서도 기기에 구애받지 않고 항상 최적의 화면을 경험할 수 있게 됩니다.
검색엔진 최적화(SEO)에 유리해 검색 결과에서 상위권에 나타나게 할 수 있습니다. 반응형 웹은 하나의 URL을 기반으로 화면이 바뀌므로 PC용 URL과 모바일용 URL이 동일합니다. 따라서 검색 포털 등 광고를 통한 사용자 접속을 효율적으로 관리할 수 있습니다.
그러나 이런 모바일 환경에서도 적응하게끔 만들어진 반응형 웹은 모바일을 전용으로 하는 사이트에 비해 무겁습니다. 반응형 웹 디자인은 읽어들여야 할 소스가 많아 불필요하게 많은 데이터를 소비하기 때문에 이는 사이트 속도와 직결이 됩니다. 로딩의 속도나 이미지 리사이징의 문제로 성능이 떨어질 수 있으며, 실제로 사용하지 않은 자원을 전송 받거나 실제 사용되는 이미지보다 더 큰 이미지를 사용할 수 있습니다.
웹 브라우저의 호환성의 문제가 있을 수 있습니다. 현재 존재하는 웹 브라우저는 스펙 및 사양이 제각기 다르기 때문에 하나의 웹 브라우저에서는 잘 반응하던 HTML 소스가 다른 웹 브라우저에서는 디자인이 깨지는 경우가 발생할 수 있습니다. 또한 CSS3의 특성상 인터넷 익스플로러(IE) 8 버전 이하에서는 사용이 불가능 해집니다. 이런 문제 때문에 디자인의 자유도가 떨어지며, 100% 맞춤 디자인이 어렵다는 점이 발생합니다.
반응형 웹은 장점이 매우 많으나 단점 또한 존재하는 기술입니다. 따라서 훌륭한 프론트엔드 엔지니어가 되기 위해서는 항상 사이트 속도를 향상시키기 위해 이미지를 최적화 해야 하며, 효율적인 네비게이션 제공 방법 외에도 다양한 사항들을 고려해야만 합니다.
미드어 쿼리를 이용하면 특정 조건에 따른 스타일 지정이 가능합니다.
@media 미디어 타입 (조건(너비 및 높이)) {
(CSS 입력하는 부분)
}
--예제
@media screen (max-width: 400px) {
body {
color: red;
}
}
미디어 타입을 별도로 지정할 수 있습니다.
반응형 디자인을 만들기 위해 가장 많이 사용하는 기능은 뷰포트 너비이며, min-width와 max-width, width 등의 미디어 기능을 활용해 뷰포트가 특정 너비 이상 또는 이하인 경우 CSS를 적용할 수 있습니다. 또한, orientation을 이용하면 가로 모드인지 세로 모드인지 검사하여 CSS를 적용할 수 있습니다.
@media 미디어 타입 (조건(너비 및 높이)) {
(CSS 입력하는 부분)
}
// <------------------------------------------->
@media screen (max-width: 400px) {
body {
color: red;
}
}
@media (orientation: landscape) {
body {
color: rebeccapurple;
}
}
논리곱, 논리합 등을 이용하여 보다 더 복잡한 조건에서 미디어 쿼리를 사용할 수 있습니다.
논리 곱을 통해 미디어 기능을 합칠 수 있습니다.
@media screen and (min-width: 400px) and (orientation: landscape) {
body {
color: blue;
}
}
논리 합을 통해 두 조건 중 하나의 조건만 충족해도 CSS를 적용시킬 수 있습니다.
@media screen and (min-width: 600px), screen and (orientation: landscape) {
body {
color: blue;
}
}
미디어 쿼리의 의미를 반대로 적용시킵니다.
@media not all and (orientation: landscape) {
body {
color: blue;
}
}
styled-components에서 미디어 쿼리를 이용해서 화면에 표시하는 요소의 개수를 지정할 수 있습니다. grid를 사용해서 레이아웃을 지정했습니다. 미디어 쿼리를 사용할 때 주의할 점으로는 작성하는 순서가 CSS 스타일에 영향을 주기 때문에 순서를 잘 고려 해야합니다.
import styled from "styled-components";
import "../App.css";
import { data } from "../data/data";
const BREAK_POINT_MOBILE = 580;
const BREAK_POINT_TABLET = 870;
const BREAK_POINT_PC = 1150;
const VideoContainer = styled.div` // 기본값으로 한 줄에 4개의 Video 컴포넌트를 배치
width: 100vw;
height: 80vh;
display: grid;
padding: 50px;
grid-template-columns: repeat(4, 1fr);
row-gap: 30px;
place-items: center;
// width가 1150px 이하인 경우, 한 줄에 3개의 Video 컴포넌트를 배치
@media screen and (max-width: ${BREAK_POINT_PC}px) {
grid-template-columns: repeat(3, 1fr);
}
// width가 870px 이하인 경우, 한 줄에 2개의 Video 컴포넌트를 배치
@media screen and (max-width: ${BREAK_POINT_TABLET}px) {
grid-template-columns: repeat(2, 1fr);
}
// width가 580px 이하인 경우, 한 줄에 1개의 Video 컴포넌트를 배치
@media screen and (max-width: ${BREAK_POINT_MOBILE}px) {
grid-template-columns: repeat(1, 1fr);
}
`;
const Video = styled.img`
width: 85%;
height: 100%;
min-height: 200px;
min-width: 200px;
background-color: red;
border-radius: 10px;
`;
const Main = () => {
return (
<>
<VideoContainer>
{data.map((data) => {
return <Video key={data.id} src={data.img}></Video>;
})}
</VideoContainer>
</>
);
};
export default Main;