항해99 TIL [12/2]

이지연·2021년 12월 9일
0

항해99 TIL

목록 보기
27/33
post-thumbnail

오랜 시간 동안 준비해온 실전 프로젝트 발표일이 드디어 내일로 다가왔다. 하지만 내가 속한 프론트엔드의 경우는 이미 만들어진 반응형 웹을 기반으로 한 모바일로의 추가 작업(뷰)이라는 또 다른 숙제가 남았고 따라서 이를 위해 모바일 우선 반응형 웹 디자인에 대해 좀 더 공부해 보는 시간을 가져보기로 했다.

모바일 우선 반응형 웹 디자인 (1)

설계

출처: 유튜브-드림코딩 by 엘리

화면 구성
header, nav, main, footer 등 모바일 화면을 구성하는 각 요소들의 배치를 고려함.

브레이크 포인트를 정함.

위는 범용 예시들이며, 절대적인 기준이 아니므로 지원하고자 하는 기기와 실제 동작을 참고하여 조정해야 함.

미디어 쿼리

정의
사용자 미디어의 종류와 상태에 대해 질의를 던져 기기의 종류나 화면 크기에 맞춰 개별적인 css 코드가 적용될 수 있도록 하는 CSS3의 기능.

문법
@media only|not 매체유형 and (표현식) { CSS스타일코드; }

예시

출처: Nextree

브라우저 호환성

IE9부터 지원. 브라우저 호환성 좋음.

출처: Can I use

뷰포트

정의
화면 위 가상의 표시 영역

출처: 번데기 개발자님 티스토리 블로그

  • 뷰포트 시초는 애플인데, 아이폰 3GS 시절 320 x 480개의 픽셀로 데스크톱 기준으로 개발된 웹 사이트를 렌더링 할 때 한 화면에 담기지 못하는 문제점이 있었고 이에 애플은 가상의 뷰포트 개념을 도입해 320px인 디스플레이를 980px의 뷰포트에 렌더링을 함. ☞ 이후 별다른 뷰포트 설정이 없으면 대부분의 모바일 브라우저의 뷰포트는 980px이 기본값이 됨.

  • 뷰포트를 제대로 알려면 픽셀을 알아야 하는데 픽셀은 기기의 물리적 크기와 다르며 개수로 세는 것.

    • ex) 해상도 확인
      1. LG그램 15인치: 1920x1080 (가로 1920개, 세로 1080개 픽셀)
      2. 갤럭시 S10: 1440x3040 (가로 1440개, 세로 3040개 픽셀)

    • 갤럭시는 그램에 비해 물리적인 크기가 작을 뿐, 픽셀 개수는 적지 않으며
      물리적인 화면 크기는 훨씬 작은데 데스크톱과 비슷한 개수의 픽셀로 렌더링 시, 작아보일 수 밖에 없음. 실제로는 뷰포트 설정이 없으면 980px로 렌더링 되겠지만, 이 또한 스마트폰의 화면에서는 큰 편임.

      ☞ 작은 스마트폰 화면에 웹 페이지를 모두 표시하려고 하니 전체 페이지의 배율이 작게 축소되어 보이는 것.

해결 방법

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        // mobile first markup
    </body>
</html>

width: 뷰포트의 가로 크기를 결정.
device-width로 설정하면 최적화된 UI를 적용하기 위해 기기마다 독립적으로 설정된 픽셀값을 뷰포트의 width로 설정하고, 그것에 웹 페이지를 맞춤.

initial-scale: 페이지가 처음 로드될 때 줌 레벨을 조정.

그 외

  • minimum-scale : viewport의 최소 배율값, 기본값은 0.25.
  • maximum-scale : viewport의 최대 배율값, 기본값은 1.6.
  • user-scalable : 사용자의 확대/축소 기능을 설정, 기본값은 yes.

모바일 우선

  • 우선 모바일을 기준으로 마크업을 함.
  • 이후 작성된 코드 아래에 미디어 쿼리를 사용해 각 브레이크 포인트별로 코드를 더 함.
.block__element--modifier {
	// Mobile
    @media screen and (min-width: 768px) and (max-width: 1023px) {
    	// Tablet
    }
    @media screen and (min-width: 1024px) {
    	// PC
    }
}

css 단위

px

소개
css의 가장 기본 단위로, 1px는 화소 1개의 크기를 의미하며 절대값임.

사용법
사용자의 브라우저 설정에도 불구하고 늘 절대적인 값을 유지했으면 하는 경우
ex) border

주의사항
웹 접근성(Accessibility)을 위해 위와 같이 꼭 필요할 때만 사용하는 것이 좋음.

%

소개
언제나 다른 수치를 참조하며 참조값은 같은 요소에 적용된 다른 속성이거나 혹은 조상 요소의 같은 속성이거나, 컨테이닝 블록의 오프셋 속성(left, right, top, bottom)이나 박스모델 속성(width, height, margin, padding)과 같은 서식 상황(formatting context)에서의 측정값이거나, 혹은 다른 어떤 것임.

참조: w3.org

사용법
레이아웃 지정에 유용함.

// html
<article class="blog__post">
    <div class="blog__post--image">
    </div>
    <div class="blog__post--content">
    </div>
</article>

// css
.blog__post {
	width: 100%;
}

.blog__post .blog__post--image {
	width: 50%;
}

.blog__post .blog__post--content {
	width: 50%;
}

flexbox와 함께 사용하면 유용함.

// html
<div class="container">
    <div class="item">1</div>
    <div class="item">22</div>
    <div class="item">three</div>
</div>

//css
.container {
    display: flex;
    justify-content: center;
    background-color: red;
}

.container .item {
    width: 20%;
    border: 1px solid black;
    background-color: skyblue;
}

sandbox에서 위 코드를 실험한 결과 container에 display: flex와 justify-content: center를 선언하면 디폴트로 item들의 width는 내부 요소의 width에 맞춰져 주축 row를 기준으로 중앙 정렬 되고, 창의 폭을 줄이기 시작하면 여백이 먼저 감소하다가 여백이 모두 줄어들었을 때에도 item들의 width는 내부 요소의 width 아래로 떨어지지 않음.

이 때, item에 width: 20%를 선언하면 item들이 container의 width를 20%씩 총 60%를 갖게 되고 나머지 40%는 양 쪽에 20%씩 나눠져서 그 비율이 내부 요소의 크기와 관계없이 유지됨. 즉, 위와 같이 창의 폭을 줄일 때, item의 width가 내부 요소의 width보다 줄어들더라도 해당 비율을 고수하며 이는 height도 마찬가지임.

  • 마진, 패딩에 사용하면 유용함.

주의사항
% 단위가 무조건 부모 요소를 참조한다고 생각하기 쉽지만, 이는 사실이 아니며 특히 박스 모델 속성(width, height, padding, margin)과 오프셋 속성(left, right, top, bottom)에 %를 적용할 때 -> % 수치는 단순히 '부모 요소'가 아닌 '컨테이닝 블록'을 기준으로 계산됨. 대부분의 경우 어떤 요소의 컨테이닝 블록은 가장 가까운 블록 레벨 조상의 콘텐츠 영역이나, 항상 그렇지는 않음.

  • height, top, bottom은 컨테이닝 블록의 height를, width, padding, margin, left, right은 width를 사용해 백분율을 계산함.

    참고: 컨테이닝 블록의 모든 것-MDN

  • 특정 요소의 height에 100%를 선언할 때 margin을 고려하지 못하면 컨테이닝 블록 밖으로 탈출하는 현상이 생김.

// html
<div class="slider__track">
    <div class="slider__track--slide">
    </div>
</div>

// css
.slider__track {
    display: flex;
    justify-content: center;
    height: 150px;
    background-color: red;
}

.slider__track--slide {
    width: 20%;
    height: 100%;
    margin: 20px 0;
    background-color: skyblue;
}

해결 방법

  1. slide 요소의 마진을 제거함.
  2. slide 요소의 height에서 마진값을 뺌.
.slider__track--slide {
    height: calc(100% - (20px + 20px));
}
  • 컨테이닝 블록의 중앙에 내부 요소를 배치하기 위해 position과 top, left를 %와 함께 사용할 때, 아래와 같이 내부 요소의 중심이 아닌 모서리가 중앙에 맞춰짐.

// html
<header class="header">
    <div class="header__logo">
    </div>
</header>

// css
.header {
    position: relative;
}

.header .header__logo {
    position: absolute;
    top: 50%;
    left: 50%;
}

✔ 해결 방법

.header .header__logo {
    position: absolute;
    top: 50%;
    left: 50%;
    // 아래 코드를 추가함
    transform: translate(-50%, -50%);
}
profile
개발하는 디자이너입니다.

0개의 댓글