티스토리 뷰



이지스 퍼블리싱에서 출간된 <반응형 웹디자인>

첫째마당의 2장 [px을 %로 바꾸기 - 가변 그리드]를 공부하다가

책에서는 별다른 언급이 없지만

나같은 초심자가 쉽게 실수할 수 있는 부분에 대해 공유하려고 한다.




둘을 합쳐 너비가 100%인데,

옆으로 나란히 배치가 안되고 아래로 넘치네?




책에서 제시한 예제의 가변 그리드 구조

두 div를 합쳤을 때 너비가 100%로 꽉 차는 형태이다.



책의 45page 부터 시작되는 예제에서 위와 같은 구조의 가변그리드를 만드는데,

보면 알 수 있듯 container 라는 클래스의 div 안에 두 div가 가로로 꽉찬 구조이다.

그런데 예제 코드를 직접 입력해서 실행해보니 책의 예시와는 다르게

아래 그림과 같이 자꾸 두 번째 div가 밑으로 내려가는 것이었다.





책에서 제시한대로 코드를 입력하고 실행했는데

자꾸 두 번째 <div>가 아래로 밀려나는 문제가 발생.




문제는 띄어쓰기, 엔터




오타가 있거나 잘못 입력된 부분일거라고 의심했던 부분은


선택자 오류 / display : inline-block 오류 / border의 두께 /

숫자를 잘못 입력 / 텍스트 편집기 오류 / CSS 초기화 오류 



등등이 있었으나 아무리 CSS를 책과 똑같이 해도 해결이 안되는 것이었다.

그러다가 책과 다른 부분이 딱 하나가 있는 것을 발견했는데,

 html에서 div를 입력한 부분에서 엔터를 쳤냐 안쳤냐 / 띄어쓰기를 했냐 하는 것이었다.



책에서는 div를 

<div></div><div></div> 

로 붙여 썼고


나는 div를

 <div></div> 

 <div></div> 

라고 썼다.


'설마....'하고 엔터를 삭제하고 붙여 써보니 거짓말처럼 해결되었던 것이다.







inline-block, inline 요소는

공백을 무시하지 않는다.



html 코드에서 안심하고 요소 사이에 엔터나 띄어쓰기를 남발해왔기에 매우 당황스러웠다.

이유가 궁금하여 Stackoverflow에서 검색해본 후 이유를 알 수 있었다.






div는 원래 block element이다. 

하지만 가변형 그리드를 만드는 과정에서 div를

display: inline-block으로 설정해뒀던 것이 이 문제의 화근이었다.



block 요소와는 다르게

inline(또는 inline-block)이 된 요소는 공백이 있으면 그 공백이 표현된다.



붉은색 체크부분 처럼 코드 사이에 여백이 있으면

띄어 쓰기로 인식되어 실행 화면에서도 공백이 생긴다.




그래서 <div></div>와 <div></div> 사이에 있는 공간을

한 칸의 여백 등으로 인식하는 것이다.

따라서 이 경우 두 div 사이의 틈은 1 byte의 스페이스가 있는 셈이 된다.

그래서 첫 번째 div의 가로 + 두 번째 div의 가로 = 100%여도

공백만큼의 가로 너비가 생겨서 두 번째 div가 밀려나는 것이다.








inline (또는 inline-block) 요소에서

공백을 띄어쓰기로 인식하는 문제를 해결하는 방법




Stackoverflow에서 이 문제를 해결하는 네 가지 방법을 찾을 수 있.





> 방법 1. 마크업에서 공백을 없앤다.

CSS에 수정을 가하지 않고 해결할 수 있는 방법은 문제의 원천인 공백을 없애는 것이다.

공백을 없애면서도 엔터를 친 것 처럼 가독성있게 코드를 작성하는 방법은 4가지 정도가 있다.




1) 엔터나 띄어쓰기 없이 쓰기.

<div>text</div><div>text</div><div>text</div><div>text</div><div>text</div>


2) 주석을 사용해서 공백을 없앤다.

<div>text</div><!--
--><div>text</div><!--
--><div>text</div><!--
--><div>text</div><!--
--><div>text</div>


3) 닫는 괄호를 다음 줄로 넘겨 태그를 닫는다.

<div>text</div
><div>text</div
><div>text</div
><div>text</div
><div>text</div>


4) 닫는 태그 전체를 다음 줄로 넘겨 태그를 닫는다.

<div>text
</div><div>text
</div><div>text
</div><div>text
</div><div>text
</div>






> 방법 2. 부모 div의 폰트 크기를 0으로 만든다.

div 사이에 있는 여백이 띄어쓰기 된 공간임을 생각했을 때, 

그 공간의 너비는 폰트 크기에 의해 결정이 된다는 사실을 짐작할 수 있다.

따라서 부모 div의 폰트 크기를 0으로 만들면, 띄어쓰기 공간의 너비도 0이 되는 원리다.


#parent {
    font-size: 0;
}

#parent > div {
    font-size: 16px;
}



이와 같이 CSS에서 부모 div의 폰트 크기를 0으로 해준 후,

자식 div의 폰트 크기를 재설정 해주면 된다.


하지만 이 방법은 자식 div의 폰트 크기가 em단위로 설정이 되어있을 경우 불가능하다.

em 단위는 부모로부터 속성을 상속받기 때문에

폰트 크기가 0인 div를 부모로 하는 자식 div의 폰트 크기를

em 단위를 사용해서 설정하면 0에 무엇을 곱하든 0이 되기 때문에 어떻게 해도 0이 된다.








> 방법 3. 부모 div의 display 속성을 flex로 변경한다. (가장 추천하는 방법)


다음과 같이부모 div의 display 속성을 flex로 변경하는 방법을 사용하면

div 요소 사이의 공백을 쉽게 없앨 수 있다.

.parent {
    display: flex;
}
.parent > div {
    display: inline-block;
    padding: 1em;
    border: 2px solid #f00;
}



단, flexible box를 지원하는 브라우저에서만 가능한 방법이다.  

Can I use 사이트에서 flex를 지원하는 브라우저 사양을 알 수 있다.

안정적인 사용을 위해 각 vender prefix를 붙여 선언해주면 좋다.




CanIuse 사이트에서 flexible box를 지원하는 브라우저를 확인할 수 있다.






이 외에도 div의 마진에 음수 값을 지정하는 방법도 있지만,

위의 방법들을 적용했을 때 문제를 해결할 수 있다면, div의 마진에 음수값을 지정하는 방법은 권장하지 않고 있다.






참고 문서



1. Stack overflow QnA

Why is there an unexplainable gap between these inline-block div elements?

2. Can I Use _ flexbox (링크)



댓글