본문으로 건너뛰기

가로 스크롤 원인 찾기

HTML·CSS 목차화면 폭에 맞추기레슨 85 / 93

목차

가로 스크롤은 페이지 내용이 창보다 넓을 때 생깁니다. 웹 페이지는 320px부터 1280px까지 어느 폭에서도 가로 스크롤이 없어야 하고, 생기면 창 밖으로 튀어나온 상자를 찾아 그 원인을 고칩니다. 넘친 것을 감추는 것으로 끝내지 않습니다.

휴대전화에서 페이지가 옆으로 밀리면 글 줄을 읽을 때마다 좌우로 굴려야 하고, 손가락이 조금만 비껴도 화면이 흔들립니다. 넓은 화면에서 만든 페이지는 좁은 폭에서 이런 일이 자주 생기는데, 원인은 몇 가지로 모입니다. 이 레슨은 넘침을 재는 두 값, 튀어나온 상자를 찾는 차례, 원인 넷과 고치는 법을 봅니다.

그림 준비 중

1페이지의 너비가 창의 너비보다 넓으면 넘친다

동아리 공지 칸에 너비 600px을 적고 폭 320px 창에서 그립니다.

<div class="notice">공지</div>
.notice {
  width: 600px;
}
결과 화면일부러 틀린 코드
잰 값개발자 도구에서 본 값
  • 페이지의 너비608px
  • 창의 너비320px
  • .notice의 너비600px

'창의 너비'는 페이지가 보이는 칸의 폭이고, '페이지의 너비'는 내용이 차지한 가장 넓은 폭입니다. 블록은 너비를 적으면 부모 내용 칸과 상관없이 그 너비를 지킵니다(브라우저 규칙 6). 그래서 .notice가 body 바깥 여백 8px 뒤에서 600px을 차지해 페이지가 608px이 되었고, 창보다 넓은 288px만큼 가로 스크롤이 생겼습니다. 결과 화면 머리의 '일부러 틀린 코드'가 이 넘침입니다.

width를 max-width로 바꾸면 600px은 상한이 되고, 창이 좁으면 부모 내용 칸만큼 줄어듭니다(너비와 box-sizing).

<div class="notice">공지</div>
.notice {
  max-width: 600px;
}
결과 화면폭 320px
잰 값개발자 도구에서 본 값
  • 페이지의 너비320px
  • .notice의 너비304px

페이지의 너비가 창의 너비 320px과 같아져 가로 스크롤이 없습니다.

2튀어나온 상자 찾기 — 찾는 차례 다섯째

상자 네 겹에서 찾는 차례에 더한 다섯째 줄(상자 · 배치)에 한 가지를 더합니다 — 가로 스크롤이 생기면 창 밖으로 튀어나온 상자를 찾습니다. 컴퓨터에서 이렇게 찾습니다.

  1. 개발자 도구 기기 모드에서 폭을 320으로 정합니다(meta viewport 3절). 창만 좁히면 뷰포트 줄을 빠뜨린 것을 놓칩니다.
  2. 페이지를 아래까지 굴리며 오른쪽으로 튀어나온 곳을 찾고, 그 자리에서 마우스 오른쪽 단추 → Inspect(한국어 화면에서는 '검사')를 누릅니다.
  3. Elements 패널에서 그 요소와 부모를 차례로 고르며, 페이지 위에 칠해지는 상자 자리가 창 끝을 넘는지 봅니다. Computed 창의 상자 그림에서 너비를 봅니다.
  4. 처음으로 창 끝을 넘는 상자가 원인입니다. 그 상자의 너비 선언 · 내용을 아래 표에서 찾아 고칩니다.

미디어 쿼리가 있는 페이지는 320 · 1280과 함께 경계 폭과 그 1px 아래(640 · 639)에서도 봅니다. 조건 블록이 드는 폭과 안 드는 폭의 배치가 다르기 때문입니다.

3원인 넷과 고치는 법

원인보이는 곳고치는 법
고정 너비width: 600px 같은 선언max-width로 상한만 둔다(1절)
큰 그림img의 width="800"max-width: 100% · height: auto(유연한 그림)
긴 영문 덩어리빈칸 없는 주소 · 해시태그overflow-wrap: anywhere
% 열과 간격50% 50% 두 열 + gap1fr 열(열 만들기)

% 열은 두 열이 부모 내용 칸을 다 쓴 뒤 간격이 더해져 넘칩니다 — 폭 320에서 grid-template-columns: 50% 50%⁠에 gap: 16px이면 페이지의 너비가 328px입니다. 1fr은 간격을 빼고 남는 자리를 나눕니다.

긴 영문 덩어리는 상자가 아니라 글자가 넘칩니다. 한국어 문장은 글자 사이에서 줄을 바꿀 수 있지만, 빈칸 없는 영문은 한 덩어리로 남아 상자 밖으로 나옵니다.

<h1>
  #HomemadeKimchiFriedRice
</h1>
결과 화면일부러 틀린 코드

h1의 상자는 304px 그대로인데, 해시태그 글자가 상자를 넘어 페이지를 넓혔습니다. 얼마나 넘치는지는 글꼴마다 다릅니다.

<h1>
  #HomemadeKimchiFriedRice
</h1>
h1 {
  overflow-wrap: anywhere;
}
결과 화면폭 320px
잰 값개발자 도구에서 본 값
  • 페이지의 너비320px

overflow-wrap: anywhere⁠는 넣을 줄에 덩어리가 다 들지 않을 때만 그 안에서 줄을 바꿉니다 — 12단원 gap과 flex: 1에서 본 그 선언입니다. 물려받는 속성이라 main에 한 번 주면 안의 글 모두에 닿습니다.

예제

320과 1280에서 점검하기

레시피 페이지 본문에 상한 · 반응형 그림 · 긴 글자 꺾기를 모두 둔 모양입니다. 두 끝 폭에서 그립니다.

<main>
  <h1>
    #HomemadeKimchiFriedRice
  </h1>
  <img
    src="images/kimchi.svg"
    width="800"
    height="600"
    alt="김치볶음밥"
  />
</main>
main {
  max-width: 960px;
  margin: 0 auto;
  overflow-wrap: anywhere;
}

img {
  max-width: 100%;
  height: auto;
}
결과 화면폭 320px
잰 값개발자 도구에서 본 값
  • 페이지의 너비320px
  • 창의 너비320px
  • img의 너비304px
<main>
  <h1>
    #HomemadeKimchiFriedRice
  </h1>
  <img
    src="images/kimchi.svg"
    width="800"
    height="600"
    alt="김치볶음밥"
  />
</main>
main {
  max-width: 960px;
  margin: 0 auto;
  overflow-wrap: anywhere;
}

img {
  max-width: 100%;
  height: auto;
}
결과 화면폭 1280px
잰 값개발자 도구에서 본 값
  • 페이지의 너비1280px
  • main의 너비960px
  • img의 너비800px
  • 320px에서는 main이 창을 채우고, 그림은 main 폭 304px까지 줄고, 해시태그는 줄을 바꿉니다. 페이지의 너비가 창의 너비와 같습니다.
  • 1280px에서는 main이 상한 960px에서 멈춰 가운데에 오고, 그림은 원래 너비 800px입니다.
  • 할 일 화면도 같은 두 줄로 좁은 폭을 맡습니다 — .app의 max-width: 520px과 할 일 글 .text의 overflow-wrap: anywhere⁠입니다.

자주 틀리는 곳

틀린 생각: 가로 스크롤은 body에 overflow-x: hidden을 주면 해결된다.

<div class="notice">공지</div>
body {
  overflow-x: hidden;
}

.notice {
  width: 600px;
}
결과 화면일부러 틀린 코드
잰 값개발자 도구에서 본 값
  • 페이지의 너비608px
  • 창의 너비320px

가로 스크롤 막대는 사라지지만 페이지의 너비는 여전히 608px입니다. 넘친 288px은 창 밖에서 잘려, 그 자리의 글과 단추를 볼 수도 누를 수도 없습니다.

맞는 규칙: 감추지 말고 튀어나온 상자를 찾아 원인에서 고칩니다(2 · 3절).

틀린 생각: 컴퓨터 브라우저 창을 320px로 좁혀 봤으니 휴대전화에서도 같다.

컴퓨터 브라우저는 뷰포트 줄을 보지 않아, 줄을 빠뜨린 페이지도 창 폭으로 배치합니다. 휴대전화는 그 페이지를 980px로 배치해 줄여 보입니다(meta viewport).

맞는 규칙: 넘침 점검은 기기 모드에서 폭을 정하고 합니다.

틀린 생각: 긴 영문은 word-break: break-all⁠로 끊는다.

<p class="a">
  Kimchi fried rice with cheese
  and egg
</p>
.a {
  width: 100px;
  word-break: break-all;
}
결과 화면
<p class="b">
  Kimchi fried rice with cheese
  and egg
</p>
.b {
  width: 100px;
  overflow-wrap: anywhere;
}
결과 화면

break-all은 넘치지 않는 보통 낱말도 줄 끝에서 아무 글자 사이로 끊어, 위 문단은 낱말 가운데서 끊긴 줄이 생깁니다. anywhere는 낱말 사이에서 먼저 줄을 바꾸고, 한 줄에 다 들지 않는 덩어리만 그 안에서 끊습니다.

맞는 규칙: 영문 낱말은 지키고 긴 덩어리만 끊는 overflow-wrap: anywhere⁠를 씁니다.

확인 문제

1. 1절 첫 예제에서 .notice의 너비를 450px로 바꾸면, 폭 320px 창에서 페이지의 너비는 몇 px일까요?

  • ① 320px
  • ② 450px
  • ③ 458px
힌트

.notice가 페이지 맨 왼쪽에서 몇 px 떨어진 곳에서 시작하는지부터 보세요.

정답

③ — body 바깥 여백 8px 뒤에서 450px을 차지해 458px입니다.

<div class="notice">공지</div>
.notice {
  width: 450px;
}
결과 화면일부러 틀린 코드
잰 값개발자 도구에서 본 값
  • 페이지의 너비458px
  • 창의 너비320px
  • ①은 넘치면 창이 같이 넓어진다고 본 것입니다. 창의 너비는 320 그대로이고 페이지만 넓어집니다.
  • ②는 body의 바깥 여백을 빠뜨린 값입니다.

2. 레시피 노트 머리글에는 @media (min-width: 640px) 조건 블록이 하나 있습니다. 모바일 먼저의 하위 목표 3(경계 폭에서 확인)으로 가로 스크롤을 점검할 폭 목록의 ____ 자리를 채우세요.

320 · ____ · 640 · 1280
힌트

조건 블록이 드는 가장 좁은 폭과, 들지 않는 가장 넓은 폭을 둘 다 봅니다.

정답

639

  • 640은 min-width: 640px이 드는 가장 좁은 폭이고, 639는 들지 않는 가장 넓은 폭입니다. 두 폭의 배치가 다르니 둘 다 봅니다.
  • 641을 적었다면 640을 빼고 생각한 것입니다(경계를 빼는 생각).

3. 여행 일정 페이지의 이동 경로 칸이 폭 320px에서 가로 스크롤을 만듭니다. 고치는 법으로 알맞은 것을 고르세요.

<div class="route">
  둘째 날 경로
</div>
.route {
  width: 100%;
  padding: 16px;
}
결과 화면일부러 틀린 코드
  • ① .route에 box-sizing: border-box;⁠를 더한다.
  • ② body에 overflow-x: hidden;을 더한다.
  • ③ .route의 width를 320px로 바꾼다.
힌트

.route가 차지하는 너비를 상자 셈으로 적어 보고, 창의 너비 320과 견주어 보세요.

힌트 둘

width: 100%의 100%는 box-sizing 처음 값에서 내용 칸 너비입니다. body 내용 칸 304px에 안쪽 여백이 양쪽으로 붙으면 상자가 차지하는 너비가 몇 px인지 셈해 보세요.

정답

① — border-box면 100%(304px)가 안쪽 여백까지 든 차지하는 너비가 되어 창 안에 듭니다.

<div class="route">
  둘째 날 경로
</div>
.route {
  box-sizing: border-box;
  width: 100%;
  padding: 16px;
}
결과 화면폭 320px
잰 값개발자 도구에서 본 값
  • 페이지의 너비320px
  • .route의 너비304px
  • 고치기 전에는 내용 칸 304px에 안쪽 여백 16 × 2가 붙어 336px을 차지했습니다(width가 차지하는 너비라는 생각).
  • ②는 넘친 32px을 창 밖에 감출 뿐입니다.
  • ③은 body 바깥 여백 8px 뒤에서 320px을 쓰고 안쪽 여백까지 붙어 더 넘칩니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 예제 코드를 index.html과 style.css로 저장하고 link로 이어 엽니다(문서 뼈대의 body 안에 예제 HTML을 넣고, images/kimchi.svg를 같은 폴더에 둡니다). 기기 모드에서 폭을 320으로 정해 가로 스크롤이 없는지 봅니다. 이번에는 main의 overflow-wrap: anywhere 줄을 지우고 저장 · 새로고침한 뒤 2절 차례로 튀어나온 것을 찾아봅니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

HTML·CSS 목차로