반응형 웹사이트 구현


1일차

반응형 웹사이트를 구현할때는 가장 작은 모바일부터 구현한 후 큰 브라우저 순으로 구현하는게 좋다.
현업에서는 이미 데스크탑 기준 웹사이트를 구현한 후 모바일 모델을 구현하는 경우도 많다.

반응형 웹사이트는 고정형과 다르게 여러 가지 디바이스 환경에 맞춰야하기 때문에 고려해야 할 것이 더 많다.
먼저, 모바일, 패드, 데스크탑 모두 각각 만들어 관리할 수 있다. 이 방법은 유지 보수 면에서 편할 수 있지만, 같은 코드를 반복해서 적어줘야 하는 단점이 있다.
다음으로는 모바일, 패드, 데스크탑에서 겹치는 코드를 한번에 묶어서 적어준뒤 각각의 차이점만 따로 만들어주는 방법도 있다. 하나의 마크업으로 여러 개의 디바이스를 지원하는 원소스멀티유즈(OSMU)방법이다. 이 방법은 구현할때 뭐가 공통인지 한번 더 생각해야 되기 때문에 더 까다롭다.

이번 웹사이트는 모바일과 데스크탑의 공통 코드를 common.css로 묶고 차이점을 large.css, small.css로 나누어 관리하도록 하겠다.
기본 레이아웃 구조는 고정형과 크게 다를게 없지만 고전 레이아웃 기술을 사용한 고정형과 다르게 최신 레이아웃 기법인 flex와 grid를 적극 활용하였다.

전체적인 레이아웃은 굉장히 단순하다. container > header + nav + main + footer로 나누어져 있다.
레이아웃은 단순하나, 데스크탑과 모바일 환경에서 보이는 양식이 달라 고려해줄 것이 많다. (데스크탑에선 보이지 않는 것이 모바일에선 보인다.)
+++
(모바일에서는 네비게이션이 햄버거 버튼을 누르면 펼쳐지는 형식이다. 이는, off canvas 형식으로 구현할 예정이다.)

데스크탑과 모바일을 따로 따로 작업할 필요없이 link 부분에 미디어 조건을 추가해주면 된다.

 <link rel="stylesheet" href="./css/small.css" media="screen and (min-width: 320px) and (max-width: 999px)"/>
  <link rel="stylesheet" href="./css/large.css" media="screen and (min-width: 1000px)"/>

미디어 조건이 320px<= x <=999px이면, small.css를, 미디어 조건이 1000px 이상이라면 large.css를 랜더링하게 해준다.

마크업 작업은 데스크탑과 모바일의 내용을 모두 적어주면 된다. 한쪽에만 필요한 내용은 안보이도록 작업해주면 된다.

먼저, 전체 레이아웃을 배치해보자.
데스크탑과 모바일 모두 flex를 활용하였다.
간단하게 방법만 설명하자면,
<전체 레이아웃>


  display: flex;
  flex-flow: row wrap;
  align-items: center;

왜 column direction을 사용하지 않았냐면, column은 다음 열로 이동하기 위해서는 높이를 설정해줘야 한다.
그런데, 웹을 만들때 컨텐츠가 추가됨에 따라 높이가 변하도록 하는 것이 더 유연하게 관리할 수 있다.
대부분의 경우 row를 이용하게 된다.

이제, header를 만들어보자.
header안에는 뭐가 있는지 살펴보자.

  1. 로고
  2. 링크 목록
  3. 햄버거 버튼(모바일에서만)
  4. 검색 창

우선, 로고를 웹페이지의 h1이라고 생각하고 1번부터 4번순으로 마크업해보자.

헤더 안의 레이아웃은 grid를 이용해보도록 하겠다.
모바일의 경우, 3행 1열의 그리드 / 데스크탑의 경우, 2행 2열의 그리드가 나온다.

grid-template: auto / 100%(or 1fr);

grid-template-rows를 auto로 처리하면 행의 높이는 컨텐츠 높이만큼 가져가게 된다. 또, 암시적 행의 높이도 컨텐츠 높이이다.
++마크업 순서상 링크목록이 나중에 선언됐으므로 order:-1로 선언해 순서를 위로 올려주었다.

grid-template: repeat(2, 50px) / repeat(2, 1fr);

여기서 행의 높이값을 50px로 지정해준 이유: 그리드 셀안에서는 컨텐츠가 자동으로 stretch 돼서 보인다.
링크 목록과 검색폼을 셀의 중앙에 가도록 설정해주고 싶어서 높이를 고정해주었다. 또, 이 부분의 컨텐츠가 더이상 늘어나지 않을 것이라 판단해 고정할 수 있었다.


2일차

<mobile 돋보기 아이콘 처리>
모바일에서는 “검색” 버튼 대신에 돋보기 아이콘이 보인다.
고정형 레이아웃에서 많이 연습한 IR기법을 사용하면 된다.

검색버튼의 가로세로 크기는 35px인데, 돋보기 아이콘의 크기는 60X55px이다.
IR기법중에서 어떤 방법을 사용할까?

  1. padding 기법
    검색 버튼의 백그라운드 이미지를 돋보기 아이콘으로 사용한다. 그리고, 아이콘의 크기를 검색버튼 크기로 줄인다.

주의할 점
이 경우, background-size: cover , contain, 100% 모두 가능하다.
100%는 검색 버튼 크기만큼 사용하겠다는 의미인데, cover와 contain은 뭘까?
-background-size: cover 부모 요소에 맞게 이미지를 최대한 크게 보여준다. 이미지의 일부가 잘릴 수 있다.
-background-size: contain 이미지를 최대한 크게 보여주되, 잘리는 부분 없이 동일한 비율을 유지한다.

돋보기 아이콘은 보이는데 여전히 글자도 보인다. padding-top 값을 검색버튼 크기만큼 준다. (버튼 밖으로 글자를 밀어내기 위해서)
그 후, overflow: hidden 처리를 해준다.

  1. text-indent 기법
    쓸 수 있는 박스 모델에 제한이 있다.
    다음 중 text-indent 기법을 사용할 수 없는 속성은 무엇일까?
  2. block
  3. inline-block
  4. table-cell
  5. inline
  6. table
    정답은? inline 이다.

text-indent기법은 button 영역에 가상 요소 클래스 ::after를 사용해서 이미지를 삽입해준다.
::before를 사용하지 않는 이유는, ::after를 사용하면 버튼의 가장 마지막 형제 요소로 삽입되기 때문에 제일 위로 배치될 수 있기 때문이다.
text-indent를 박스 크기만큼 이동하고(35px), white-space와 overflow:hidden을 이용해준다.

*background-size 속성은 background 단축 속성으로 넣어주면 구형 모델중에 인식하지 못하는 것이 있다. 현업에서는 background-size만 별도로 기재해주기도 한다.

배치를 완료하니, 검색 폼 영역의 검색 입력칸이 그리드 셀 안의 전체를 차지하지 못한다.
그리드셀 안에서는 요소가 stretch 되는게 기본값이지만 이경우는 그렇지 않는다. 왜일까?
앞전에 grid container와 grid item을 정했을 때를 다시 보면, form 자체가 그리드 아이템이기 때문이다.
배경 색상을 칠해보면 form 영역은 그리드 셀 전체를 차지하고 있는 것이 보인다.
검색 input 영역이 전체를 차지할 수 있도록 fieldset을 다시 grid container로 설정한다. 그런데, 문제가 발생한다.
파이어폭스에선 제대로 구동되지만 크롬에선 오류가 나타난다. fieldset을 grid container로 설정하면 크롬에서 오류가 발생한다. 이에 대한 해결 방법은 두가지가 있다.
첫 번째, fieldset의 display 속성을 contents로 바꿔준다.
*
display: contents란?
contents 속성은 이번에 새로 도입된 개념으로, 박스의 개념을 버리고 텍스트같은 컨텐츠로 성격을 바꾸어 버리게 합니다. 즉 넓이값과 높이값을 마음대로 지정할 수 없을뿐 아니라 border, 배경색도 가질 수 없습니다. margin, padding값도 부여할 수 없습니다. 또, IE11에서 지원하지 않습니다.

  • fieldset의 속성을 contents로 바꿔주고 form을 grid container로 설정해주면 input과 button이 grid item이 될 수 있다.
    이 방법은 IE 11의 지원이 불가하므로 fieldset안에 input과 button을 div로 묶어주고 이 div을 grid container로 설정해주는 방법이 있다.