@media (max-width: 600px)
을 사용하면 된다. 이는 현재 viewport width가 600px 이하인지 물어본다. → 현재 viewport가 600px 이하라면 해당 CSS 코드가 적용된다. 600px보다 크다면 적용되지 않는다.@media (max-width: 600px)
와 @media (max-width: 1200px)
가 동시에 적용되면? → 600px 이하, 1200px 이하 두 조건 모두 참을 만족하므로 적용된다. → 충돌이 있을 때 마지막 것이 적용된다.@media (max-width: 1200px) {
.section-hero {
background-color: orangered;
}
}
@media (max-width: 600px) {
.section-hero {
border: 20px dashed blue;
background-color: blue;
}
}
@media (max-width: 600px)
이 마지막에 있으므로, 600px 이하일 때 충돌하는 background-color
는 파란색이 된다(Mobile First의 경우 너비를 점점 줄여나가며 min-width를 설정한다.)
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
width=device-width
, initial-scale=1.0
: 페이지가 화면의 너비와 일치하도록 한다. 모바일 장치에서 화면에 맞추기 위해 페이지를 축소하지 않는다는 뜻.@meida(max-width: )
안에 넣어야 숫자의 기준은?반올림한 em 단위
/* @media()에서 괄호 안에 rem이나 em의 단위를 넣어도 이는 기존 html{}에 설정해준
font-size의 영향을 받지 않아, 그대로 1rem = 1em = 16px이다.
(브라우저 설정해준 font-size가 16px임)
/* rem: root font size
em: current font size */
/************************************/
/* BELOW 1344px (Smaller desktops) */
/**********************************/
/* 1344px 인 이유?
1350px을 목표로 했다.
1350px을 em 단위로 변경하려 계산하면, 1350px / 16px = 84.375 em 이다.
반올림하면 84em이므로 @media() 괄호 안에 84em을 써주고 84em * 16px = 1344px 이다.
따라서 1344px 이다.*/
@media (max-width: 84em) {
...
}
200~300px의 간격
→ 너무 많은 미디어 쿼리를 만들지 않고 최소 200px 이상의 간격으로 미디어 쿼리를 만드는 게 좋다.
/************************************/
/* BELOW 1344px (Smaller desktops) */
/**********************************/
****
@media (max-width: 84em) {
.hero {
/* 기존 130rem */
max-width: 120rem;
/* 기존 130rem이므로 container와 width를 맞추기 위해 */
/* 위처럼 설정하면 hero 부분의 너비가 1300px에서 1200px로 변하는 걸 볼 수 있다. */
/* 여기서 새로 생기는 문제는, heading-primary 가 3줄에서 4줄이 된다는 것이다. */
}
.heading-primary {
/* 기존 5.2rem */
font-size: 4.4rem;
/* 4줄로 늘어났던 제목이 원래의 3줄로 바뀐다. */
}
/* 아래로 내려보면 .gallery 부분도 width를 줄일 수록 이상해진다. */
/* grid 3열을 2열로 줄여서 해결해보자. */
/* 참고: 모든 스크린 사이즈를 완벽하게 만들 수는 없다. 조금 이상해도 OK*/
/* 작은 노트북 중 가장 흔한 것이 1200px이니까 그 정도에서 확인하고 괜찮으면 OK */
.gallery {
grid-template-columns: repeat(2, 1fr);
}
}
/************************************/
/* BELOW 1200px (Landscape Tablets)*/
/**********************************/
/* 1200px / 16px = 75em */
@media (max-width: 75em) {
/* 우리는 반응형으로 웹을 설계했기 때문에
모든 것을 줄이고 싶을 때 글꼴 크기를 줄이면 된다. */
/* 62.5%가 브라우저가 보통 16px이므로 10px을 의미했다면,
우리는 이제 9px을 쓰고 싶을 때 아래와 같이 하면 된다.
9px / 16 = 0.5625*/
html {
font-size: 56.25%;
}
/* container가 120rem으로 1200px이었는데,
이제는 120rem * 9px = 1080 px로 변경됐다. */
/* 너비가 좁아지는데 grid gap은 그대로라 gap이 점점 커져 보일 것임. 이를 줄여준다. */
.grid {
column-gap: 4.8rem;
row-gap: 6.4rem;
}
.heading-secondary {
font-size: 3.6rem;
}
.heading-teritiary {
font-size: 2.4rem;
}
/* header가 원래 폭이 넓었는데, 화면이 줄어들수록 container보다 폭이 좁아진다.
container와 폭을 맞춰줄 것이다. */
.header {
padding: 0 3.2rem;
}
.main-nav-list {
gap: 3.2rem;
}
.hero {
gap: 4.8rem;
}
/* 개발자 도구에서 ipad, landscape 설정해서 중간 점검 해보기 */
.testimonials-container {
padding: 4.8rem 3.2rem;
}
}
/**************************/
/* BELOW 940px (Tablets) */
/************************/
/* 940px / 16 = 58.75 */
@media (max-width: 59em) {
/* 8px / 16 = 0.5*/
html {
font-size: 50%;
}
/* 다음 미디어쿼리가 될 영역까지 너비를 줄여보고,
200~300px이 안됐는데 디자인이 무너진다면 개별 요소를 직접 수정한다. */
/* 2개의 열을 1개의 열로 수정하기 - 세로 모바일 화면 생각! */
.hero {
grid-template-columns: 1fr;
padding: 0 3.2rem;
gap: 6.4rem;
}
/* hero를 바꾸니 이미지가 너무 커져서 수정 */
/* 기존: 100% */
.hero-img {
width: 60%;
}
/* 중앙 정렬 */
.hero-text-box,
.hero-img-box {
text-align: center;
}
.delivered-meals {
/* 해당 블록은 flexbox이다. 따라서 justify-content 사용해서 중앙 정렬 */
justify-content: center;
margin-top: 3.2rem;
/* visual hierarchy 때문에 delivered-meals는 hero-text-box에 더 붙이고,
hero-img-box는 위 둘과 좀 더 간격을 주었다. */
}
/* 로고들이 너무 크고 간격도 좁아 보여서 조정한다. */
.logos img {
height: 2.4rem;
}
.step-number {
font-size: 7.4rem;
}
/* meal-content 카드 제목이 자꾸 2줄이 되어 조정한다. */
.meal-content {
padding: 2.4rem 3.2rem 3.2rem 2.4rem;
}
/* gallery 부분도 hero처럼 1 column으로 만들기 */
.section-testimonials {
grid-template-columns: 1fr;
}
/* 이미지 부분이 너무 커지니까 수정해보기 2x6의 행렬로 만들어보자. */
.gallery {
grid-template-columns: repeat(6, 1fr);
}
/* 마지막 폼 부분에 사진이 많이 좁아짐.
이를 조정하기 위해 form 부분을 한줄로 만들기 */
.cta {
/* 기존: 2fr 1fr. 사진의 비율이 33%였음. 이를 40%로 키워보기 */
grid-template-columns: 3fr 2fr;
}
/* form 한줄로 만들기 */
.cta-form {
grid-template-columns: 1fr;
}
.btn--form {
/* 입력 칸과 버튼 간의 간격이 좁아보여서 넓혀준다. */
margin-top: 1.2rem;
}
}
index.html
<body>
<header class="header nav-open">
...
<button class="btn-mobile-nav">
<!-- 메뉴 아이콘 -->
<ion-icon class="icon-mobile-nav" name="menu-outline"></ion-icon>
<!-- 메뉴 닫기 아이콘 -->
<ion-icon class="icon-mobile-nav" name="close-outline"></ion-icon>
</button>
</header>
</body>
style.css
/* MOBILE */
.btn-mobile-nav {
border: none;
background: none;
/* background-color: none이 아님에 주의! */
cursor: pointer;
/* 데스크탑일 때 보여지면 안되는 버튼이므로 display: none 설정 */
display: none;
}
.icon-mobile-nav {
height: 4.8rem;
width: 4.8rem;
color: #333;
}
/*
<!-- 메뉴 아이콘 -->
<ion-icon class="icon-mobile-nav" name="menu-outline"></ion-icon>
<!-- 메뉴 닫기 아이콘 -->
<ion-icon class="icon-mobile-nav" name="close-outline"></ion-icon>
*/
/* name 속성으로 아이콘 구분짓기 */
/* .icon-mobile-nav[name="menu-outline"] {
} */
.icon-mobile-nav[name="close-outline"] {
display: none;
}
queries.css
.main-nav {
background-color: rgba(255, 255, 255, 0.97);
position: absolute; /*parent에 relatvie를 주어야 함에 주의*/
top: 0;
left: 0;
width: 100%;
height: 100vh;
transform: translateX(100%);
/* translateX(100%) 했을 때 오른쪽에 그만큼 공간이 생긴다.
이를 해결하기 위해 body에 overflow-x: hidden을 설정한다.*/
/* header에 realtive를 설정해주어야 한다. */
display: flex;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in;
/* Hide navigation */
/* display: none; 하면 단점 - Allows NO transitions at all */
/* display: none; */
/* 1) Hide it visually */
opacity: 0;
/* 2) Make it unaccessible to mouse and keyboard. display:none이 아닌 opacity:0을 사용하기 때문에 */
pointer-events: none;
/* Hide it from screen readers */
visibility: hidden;
}
/* nav-open: 내비게이션 바가 열렸을 때 */
.nav-open .main-nav {
opacity: 1;
pointer-events: auto;
visibility: visible;
transform: translateX(0%);
}
.nav-open .icon-mobile-nav[name="close-outline"] {
display: block;
}
.nav-open .icon-mobile-nav[name="menu-outline"] {
display: none;
}
.main-nav-list {
/* .main-nav-list는 이미 플렉스 박스라 display: flex; 선언해줄 필요 X */
flex-direction: column;
gap: 4.8rem;
}
.main-nav-link:link,
.main-nav-link:visited {
font-size: 3rem;
}
/**********************************/
/* BELOW 704px (Smaller Tablets) */
/********************************/
/* 700/16 = 43.75em */
/* 44*16 = 704px*/
@media (max-width: 44em) {
/* 3,4개의 그리드 열을 전부 2개의 그리드 열로 바꿔준다. */
.grid--3-cols,
.grid--4-cols {
grid-template-columns: repeat(2, 1fr);
}
/* 3개 그리드 열에 있던 3개의 요소가 2개 그리드 열로 바뀌면서
위에 2개, 아래 1개가 되어서 아래 1개를 중앙 정렬하고 싶을 때 */
.diets {
grid-column: 1 / -1;
justify-self: center;
}
.heading-secondary {
margin-bottom: 4.8rem;
}
.pricing-plan {
width: 100%;
}
/* footer */
.grid--footer {
grid-template-columns: repeat(6, 1fr);
}
.nav-col {
grid-row: 1;
grid-column: span 2;
}
.logo-col,
.address-col {
grid-column: span 3;
}
}
/************************/
/* BELOW 544px (Phone) */
/**********************/
/* 550px/16px = 34.375em */
/* 34em*16px = 544px*/
@media (max-width: 34em) {
/* 이제 충분한 공간이 없기 때문에 모든 그리드를 하나의 열에 모을 것이다. */
.grid {
row-gap: 4.8rem;
}
.grid--2-cols,
.grid--3-cols,
.grid--4-cols {
grid-template-columns: 1fr;
}
.section-hero {
padding: 2.4rem 0 6.4rem 0;
}
.btn,
.btn:link,
.btn:visited {
padding: 2.4rem 1.6rem;
}
.hero-img {
width: 80%;
}
.logos img {
height: 1.2rem;
}
.step-img-box:nth-child(2) {
grid-row: 1;
}
.step-img-box:nth-child(6) {
grid-row: 5;
}
.step-img-box {
/* grid gap을 개별적으로 조정할 수 없을 때 쓰는 trick */
/* 이미지가 해당하는 아래의 글과 더 가깝도록 이미지를 아래로 조정할 때 */
/* translateY를 사용한다. */
transform: translateY(2.4rem);
}
.testimonials {
grid-template-columns: 1fr;
}
.gallery {
grid-template-columns: repeat(4, 1fr);
gap: 1.2rem;
}
.cta {
grid-template-columns: 1fr;
}
.cta-text-box {
padding: 3.2rem;
}
/* cta-img-box는 원래 아무것도 없는 요소이고, 다른 것에 의지해 background-image가 보였다.
다른 것에 의지하지 않을 때는 수동으로 해당 요소에 높이를 부여해야 한다. */
.cta-img-box {
grid-row: 1; /* form보다 위에 위치시키기 */
height: 32rem;
}
}