<aside class="sidebar">
<a href="/twitter" class="button-link">follow us on Twitter</a>
<a href="/facebook" class="button-link">like us on Facebook</a>
</aside>
내용 | 코드 | 결과 |
---|---|---|
1. button-link 에 display:block 처리 하기 전 | ||
2. button-link 에 display:block 처리: container의 width를 채우고 한 줄 전체를 차지하게 됨 | ||
3. spacing 처리: margin-top:1.5em 을 추가 => button 각각에 margin-top이 적용됨. top 부분에는 이미 적용된 padding값에 margin-top이 중복 적용되어 원하는 결과가 아님 | ||
4. 인접 형제 결합자(adjacent sibling combinator, +)를 사용하여 앞에서 지정한 요소의 바로 다음에 위치하는 형제 요소만 선택해서 margin-top을 적용시킴 |
위 사례의 4번째 해결 방안에 만일 button
요소를 더 추가하게 되면 바로 문제가 발생하게 된다. 해당 요소를 선택하여 margin-top
을 다시 적용하면 된다고 생각하겠지만 이렇게 건당 처리하는 것보다 좀 더 일괄적으로 적용될 수 있는 솔루션이 필요하다!
내용 | 코드 | 결과 |
---|---|---|
5. button-link 밑에 하위요소로 sponsor-link를 추가하게 되는 순간 해당 요소에 margin-top이 다시 적용되지 않는 것을 볼 수 있음 |
* + *
: 뇌수술 받은 부엉이랑 닮았다고 하여 지어진 이름이란다🦉
*
는 일반적으로 모든 요소를 선택할 때 사용한다. 여기에 +
요소를 쓰고 또 한번 *
를 쓰게되면 버튼 뒤의 직접적인 하위 버튼 요소만을 타켓하는 것이 아니라 부모의 첫 번째 자식요소를 제외한 모든 뒤따라오는 요소를 타겟한다는 뜻이다.
내용 | 코드 | 결과 |
---|---|---|
6. <body> 내부 전체를 타겟할 수 있도록 다음과 같이 처리 |
다음 중 body * + *
이 적용된 부분을 살펴보겠다. 부모 요소의 첫 번째 자식요소를 제외한 그 이후 자식 요소들이 모두 targeted 되었다.
<body>
<header>
<h1>Franklin Running Club</h1>
</header>
<div class="container"> /* <-----적용! */
<main class="main">
<h2>Come join us!</h2>
<p> /* <-----적용! */
The Franklin Running club meets at 6:00pm every Thursday
at the town square. Runs are three to five miles, at your
own pace.
</p>
</main>
<aside class="sidebar"> /* <-----적용! */
<a href="/twitter" class="button-link">
follow us on Twitter
</a>
<a href="/facebook" class="button-link"> /* <-----적용! */
like us on Facebook
</a>
<a href="/sponsors" class="sponsor-link"> /* <-----적용! */
become a sponsor
</a>
</aside>
</div>
그 결과 원치 않는 문제가 생겼다. 이미 <div class="container">
에 top-margin:1.5em
이 적용되었는데 <aside>
에도 중복 적용되면서 sidebar의 top-margin이 결과적으로 3em이 되어버린 것이다.
또한 현재 <main class="main">
에 padding 적용이 안되어있으므로 padding도 추가해야한다.
내용 | 코드 | 결과 |
---|---|---|
7. <sidebar> 에 margin-top:0으로 처리하기 & <main class="main"> 에 padding값 주기 |
float
란
containing block안에서 특정 요소의 오른쪽이나 왼쪽에 위치시키는 것을 뜻한다.float
는 3가지 값을 받는다 :left
,right
,none
이다. 기본값은none
으로float
가 적용되지 않은 상태를 뜻한다.
요소를 옆에 위치시키거나 이미지 주변으로 텍스트가 흐르게 하기 위한 목적으로 사용되지만 제대로 사용하지 못할 경우 다른 요소를 overlapping 하거나 부모 요소에 혼란을 주는 등 레이아웃 문제가 발생할 수 있다. 최근에는flexbox
나grid
로 많이 대체되었다.
float
는 요소(주로 이미지)를 컨테이너의 한 쪽 방향(왼쪽 or 오른쪽)으로 오게 위로 끌어올리고 그 나머지 요소들이 그 주변으로 흐르게 만든다. 신문이나 매거진에서 익숙하게 본 그림이다.
위 그림과 같이 요소를 오른쪽이나 왼쪽으로 위치시킬 수 있다. float
가 적용된 요소는 원래 document flow에서는 더 이상 고려되지 않고 컨테이너의 한 쪽 자리에 위치하기 되며 나머지 document 요소들은 그 주변을 감싸며 흐르게 된다. 한 개 이상의 요소에 float
를 적용하게 되면 다음 그림과 같이 한 쪽 방향으로 쌓이게 된다.
<body>
<div class="container">
<header>
<h1>Franklin Running Club</h1>
</header>
<main class="main clearfix">
<h2>Running tips</h2>
<div>
<div class="media">
<img class="media-image" src="runner.png" />
<div class="media-body">
<h4>Strength</h4>
<p>
Strength training is an important part of injury prevention. Focus
on your core— especially your abs and glutes.
</p>
</div>
</div>
<div class="media">
<img class="media-image" src="shoes.png" />
<div class="media-body">
<h4>Cadence</h4>
<p>
Check your stride turnover. The most efficient runners take about
180 steps per minute.
</p>
</div>
</div>
<div class="media">
<img class="media-image" src="shoes.png" />
<div class="media-body">
<h4>Change it up</h4>
<p>
Don't run the same every time you hit the road. Vary your pace,
and vary the distance of your runs.
</p>
</div>
</div>
<div class="media">
<img class="media-image" src="runner.png" />
<div class="media-body">
<h4>Focus on form</h4>
<p>
Run tall but relaxed. Your feet should hit the ground beneath your
hips, not out in front of you.
</p>
</div>
</div>
</div>
</main>
</div>
</body>
Before | 코드 | After |
---|---|---|
.container {
max-width: 1080px;
margin: 0 auto;
width
대신에 max-width
를 설정하면 뷰포트가 1080px 이하일때 요소가 1080px 보다 더 작아질 수 있으며 최대로 커진 크기는 1080px가 된다는 말이다.
float
를 왜 사용해야하는지 알아야할까?
기존에 float를 사용해 만들었던 페이지 레이아웃을flexbox
가 빠르게 대체하고 있다. 물론 모던 브라우저에서는float
없이 얼마든지 레이아웃을 구성할 수 있다. 하지만 여러분의 서비스가 Internet Explorer를 지원한다면float
를 완전히 무시하고 살긴 어려울 것이다.flexbox
가 IE10 과 IE11에서만 지원되며 이마저도 간혹 버그가 발생하기 때문이다.
float
를 사용한 레이아웃의 경우 대개 최소한의 마크업이 가능하다는 장점이 있다.또한float
는 여전히 이미지를 페이지 한쪽에 띄우고 주변으로 텍스트를 흐르게 할 수 있는 유일한 방법이다.
float
는 원래대로 잘 작동하고 있는데 이로 인해 가끔 문제가 발생하는 경우가 있다.
내용 | 코드 | 결과 |
---|---|---|
1. .media div에 float: left 주기 |
.media
에 float:left
를 주었고 width: 50%
를 주어 한 줄에 2개의 이미지가 들어가도록 처리했다.
.main
에 적용되었던 background-color:white
가 더 이상 적용되지 않음을 볼 수 있다. 왜일까?
float
가 적용된 요소는 부모 요소에 height를 주지 않기 때문이다.
부모요소인 <div>
에 height가 0으로 나온다.
이 현상은 float
가 사용되었던 본질적 목적과 관련이 깊다.
만일 이미지의 높이가 텍스트 높이보다 큰 경우, 해당 문단이 이미지의 높이에 맞춰서 커지지 않는다. 다시 말하면, 만일 이미지가 문단의 텍스트 높이보다 큰 경우 다음 문단의 글이 바로 뒤이어 따라오게 된다는 것이다. (4.7 그림 참조)
우리의 예시로 다시 돌아오면 <main>
안의 요소들 중 <h2>
인 Running Tips를 제외하고 다른 요소들은 다 float
가 적용되어있는 상태다. 따라서 <h2>
의 height만 살아있는 상태다.
이를 고치기 위한 해결방법을 알아보자
clear
사용하기내용 | 코드 | 결과 |
---|---|---|
2. 마지막에 <div style="clear: both"></div> 추가하기 |
.media
의 부모요소와 형제가 되도록 빈요소를 다음과 같이 만들어 준다. <div style="clear: both"></div>
(clear: both도 동일한 결과가 나온다. 반면 clear: right를 적용하면 해당 div가 <h2>
바로 밑으로 가기 때문에 해당 container가 expand(확장)되지 않는다). 맨 마지막에 <div style="clear: both"></div>
를 넣어줌으로써 float
가 적용된 .media
주변을 흐르는 요소가 마지막에 하나 더 생기게 되면서 <main>
컨테이너의 높이가 정해진다.
이렇게 하면 문제가 해결될 수 있으나 사실 이 방법은 불필요한 마크업을 추가해야하기 때문에 그렇게 바람직한 방법이라고는 할 수 없다.
clearfix
이해하기불필요한 <div>
를 추가하는 대신 가상요소(pseudo-element)를 사용하여 처리할 수 있다.
<main>
에 clearfix라는 class를 추가한다.
.clearfix::after
<main>
의 마지막 부분(::after) 가상요소를 추가한다.
※ 주의사항
clearfix는 float
를 포함하고 있는 요소에 사용되어한다. float
가 직접 적용되어있는 요소에 적용되거나 float
를 포함하고 있는 요소의 다음 요소에 적용되는 일이 없도록 하자.
위 코드를 추가하게 하게 되면 <h2>
위에 margin이 아래 그림과 같이 적용된다.
가상요소에 display:table
를 적용하게 되면 table row와 table cell이 만들어지게 된다. table row와 table cell에서는 마진이 무너지지 않으므로 display:table
이 적용된 가상요소에서도 무너지지 않게 되는 것이다.
display:table-cell
도 동일한 효과를 낼 것으로 기대할 수 있지만 우리 예시의 경우 clear
속성은 block 레벨의 요소에만 적용이 되는데, table
은 block레벨이지만 table-cell
은 block레벨이 아니므로 clear
가 적용될 수 없어서 이 경우는 display:table
을 사용하는 것이 가장 적절하다.