-
[CSS] Box Model , Display, Position, floatFrontEnd/CSS 2021. 2. 19. 02:45
BoxModel
Box에는 content, padding, border, margin이 있다.
-박스 크기는 이렇게 구해진다.
너비: width + left/padding + left/border + left/margin
높이: height + top/bottom padding + top/border + top/bottom margin
-값을 따로 정하지 않으면 기본값 auto가 적용된다. (margin에 auto를 주면 브라우저 중앙에 위치하게 된다.)
-값을 지정할 경우 px, % 등의 단위를 쓴다. 박스모델 관련 속성은 상속되지 않는다.
-top, right, bottom, left가 모두 같다면 margin: 25px; 처럼 한번에 지정해도 된다.
-box-sizing 프로퍼티는 content-box나 border-box을 값으로 받는다. border-box로 지정하는 경우 padding값까지가 박스모델에 포함된다. box-sizing 프로퍼티는 상속되지 않는다.
-border-style에는 none | hidden | dotted | dashed(- - -) | solid | double | groove | ridge | inset | outset 가 있다. top, right, bottom, left에 대해 각각 지정도 가능하다. border: none solid dotted dashed라면 순서대로 top 없음 right 일반선 bottm 점선 left - - -선이 나타난다. 3개만 쓰는 경우, right의 속성이 left에도 적용된다.
-모서리를 둥글게 표현하려면 radius를 사용하면 된다. 단위로는 px, em, % 등을 사용한다. 기본적으로는 수평 반지름을 설정하지만, 수직 반지름을 추가해서 여러가지 모양을 만들 수 있다. 각 방향을 표현하려면 border-top-left-radius: 10px;처럼 쓴다. 반지름을 2개 사용해서 border-top-left-radius: 50px 25px; 처럼 표현하거나, border-radius: 50px 0 0 0 / 25px 0 0 0; 처럼 표현한다.
-border:로 border-width border-style border-color를 한번에 설정할 수 있다. 5px solid red 처럼 지정하면 된다.
Position
위치를 정의한다. top, bottom, left, right 프로퍼티와 함께 쓰인다.
-기본값을 static이라고 부른다. 위 > 아래, 왼쪽 > 오른쪽 순으로 배치되고, 자식은 부모의 위치를 기준으로 배치된다. 기존 설정을 초기화할 경우 position: static처럼 쓰면 된다. 이 경우 top, right, bottom, left, z-index의 값은 0이다.
-relative를 주면 top, right, bottom, left, z-index에 준 값이 적용된다. 다른 요소들은 이 요소가 원래 위치에 있는 것처럼 취급된다. 출발 좌표는 부모의 좌표.
-absolute를 주면 부모를 기준으로 출발 좌표가 결정된다. 부모에서 상속 받을 좌표값이 없으면 body에서 상속 받는데, body의 position이 기본값인 static이라면 (0, 0, 0, 0)에서 시작하게 된다.
-position값이 absolute인 경우 다른 요소와의 관계성은 무시된다. 다른 요소들에게는 마치 없는 요소처럼 취급되고, 다른 맥락에서 공간을 점유한다. (absolute를 가지는 요소는 새로운 레이어에 배치되는 느낌?) 다른 요소가 차지하고 있는 자리도 덮어쓸 수 있다.
-absolute인 경우 block 요소더라도 width가 content에 맞게 지정되므로 적절한 width를 줘야한다.
<div class="parent"> <div class="box relative">relative</div> <div class="box relative">relative</div> <div class="box absolute">absolute</div> <div class="box relative">relative</div> </div>
.parent { position: relative; top: 100px; left: 100px; width: 220px; height: 220px; border: solid 3px black; } .box { display: inline-block; border: none; width: 100px; /* 안주면 글자 크기만큼 줄어든다 */ height: 100px; background: coral; color: white; } .relative { position: relative; } .absolute { background: darkgray; position: absolute; }
absolute가 적용되지 않으면 다른 요소들이 해당 요소의 맥락을 고려해서 배치되지만
absolute인 경우 해당 요소를 제외하고 배치된다. absolute값을 갖는 요소는 부모 요소의 영역을 벗어날 수도 있다.
-fixed: 부모 요소가 아니라 viewport를 기준으로 출발 좌표가 결정된다. fixed값을 갖는 요소는 스크롤이 되더라도 항상 화면의 같은 위치에 위치한다. fixed도 block 요소더라도 width가 content에 맞게 지정되므로 적절한 width를 줘야한다.
z-index
겹칠 경우 앞에 보여줄 우선순위를 설정한다. 큰 숫자가 앞에 온다. position이 static인 경우 무시된다.
<div class="first">First</div> <div class="second">Second</div> <div class="third">Third</div>
div { width: 100px; height: 100px; position: absolute; text-align: center; } .first { background: lightskyblue; top: 20px; left: 20px; z-index: 2; } .second { background: lightpink; top: 40px; left: 40px; z-index: 1; } .third { background: lightgray; top: 60px; left: 60px; }
Overflow
-자식 요소가 너무 커서 영역을 벗어났을 때 처리 방법을 지정한다.
-visible: (기본값) 영역을 벗어나도 표시한다.
-hidden: 영역을 벗어나면 안 보이게 처리한다.
-scroll: 영역을 벗어나면 스크롤을 추가해준다.
-auto: 영역이 벗어난 부분이 있을 때만 스크롤을 추가한다.
Display
-block: 줄바꿈O, 기본적으로 라인 전체를 차지, width, height, margin, padding 지정 가능 (div, h1~h6, p, ol, ul, li, hr, table, form ... )
-inline: 줄바꿈X, 다른 요소와 같은 줄에 위치 가능, content 너비만큼 차지, width, height, margin-top, margin-bottom 지정 불가, 상하여백은 line-height을 이용 (span, a, strong, img, br, input, select, textarea, button, ... )
-inline-block: 줄바꿈X, 다른 요소와 같은 줄에 위치 가능, width, height, margin, padding 지정 가능
-none: 안 보이게 하고, 해당 요소가 차지하던 공간도 사라짐
Visibility
-visible: (기본값)
-hidden: 안 보이지만 해당 요소가 차지하는 공간은 유지
-collapse/none: table의 행이나 열을 안 보이게 한다.
Opacity
-0.0 ~ 1.0 사이의 값을 받아 투명도를 지정한다.
Float
-보통 이미지를 추가하면 글과 다른 문단으로 추가된다. 이때 이미지를 (현재 상태처럼) 글자와 같은 줄에 두고 싶다면, 글 왼쪽 정렬 등의 옵션을 통해 글의 오른쪽에 둘 것인지, 왼쪽에 둘 것인지 정해야 한다.
-float 프로퍼티를 이용하면 text나 inline 요소들과 같은 라인에 표현할 수 있다.
-즉, float은 block 요소를 가로정렬하는 데에 쓰인다. block은 기본적으로 해당 라인을 전부 점유하기 때문에(width: 100%), 옆 그림처럼 세로로 표시된다.
-width를 별도로 지정하지 않은 block 요소에 float을 지정하면 width는 content에 맞게 줄어든다.
-받을 수 있는 값으로는 none, left, right가 있다.
-right의 경우, 먼저 나온 값이 제일 오른쪽으로 간다.
-float된 block요소와 일반 block 요소를 함께 쓰면, float된 요소의 width는 content 만큼 줄어들고, 일반 block요소는 width: 100%를 유지해서 이런 모양이 된다.
<div class="float">float: left;</div> <div class="normal">normal div</div> <div class="float">float: left;</div>
div { line-height: 50px; padding: 20px; } .float { float: left; background: red; } .normal { background: skyblue; opacity: 0.5; }
아래의 float: left는 비교용으로 추가했다.
normal div는 여전히 width 100%를 차지하고 있고, float: left가 그 중 일부에 놓여 있는 모양새다.
이런 특징 때문에 몇 가지 문제가 생길 수 있다.
1. 둘이 겹쳐 있으면 margin은 어디로?
위와 같은 경우, float-left나 normal div 위에 겹쳐 있는 상태이기 때문에 둘 사이에 공간을 주고 싶어도 제대로 표현이 되지 않는다. div { margin: 0 10px; } 준다고 해도 아래처럼 글자는 밀리지만 공간이 생기지는 않는다.
이 문제를 해결하려면 normal div에 overflow: hidden을 주면 된다.
div { line-height: 50px; margin: 0 10px; padding: 10px; } .float { float: left; background: red; } .normal { background: skyblue; overflow: hidden; opacity: 0.5; }
float: left가 차지하고 있는 부분은 숨겨져서 보이지 않게 되었다!
2. 자식이 float일 때 부모의 높이는?
위 예제에 부모가 있다고 하면
<div class="container"> <div class="float">float: left;</div> <div class="normal">normal div</div> <div class="float">float: left;</div> </div>
.container { background-color: lightgray; } div { line-height: 50px; margin: 0 10px; padding: 10px; } .float { float: left; background: red; } .normal { background: skyblue; opacity: 0.5; overflow: hidden; }
아래처럼 2번째 float이 부모 영역 바깥으로 나가는 문제가 생긴다. float 요소의 높이가 제대로 반영되지 않는다.
(*float이 없는 경우 아래처럼 정상적으로 표시된다.)
(*normal div가 없으면 아래 같은 상황이 생긴다.)
이 문제는 부모에 overflow:hidden을 지정해주면 해결된다.
왜인지 궁금해서 찾아보니 MDN의 Block_formatting_context 부분에 보면 Contain internal floats 예제가 있다.
overflow값이 초깃값인 visible만 아니면 float을 잡아주는 새로운 BFC가 생성된다고 한다. 새로운 BFC > 회색 컨테이너가 되는 것.
다만 overflow 처리 관련해서 예상치 못한 결과(갑자기 스크롤?)가 생길 수도 있고, overflow 부분이 float를 잡아두려고 쓰였다는 게 분명하지 않기도 하니까 주석을 달아주라고 권해준다.
이 문제를 해결하기 위해 display: flow-root가 추가되었다고 하니, 부수적인 효과 없이 BFC만 생성하고 싶다면 이 옵션을 쓰면 된다.
Inheritance
부모 요소에 적용된 프로퍼티 중에는 자식에게 상속되는 것이 있고, 안 되는 것이 있다.
width/height이나 margin, padding, border, box-sizing, display, top/right/bottom/left, postion 같은 요소는 상속이 되지 않고,
font, color, line-height, text-align 등은 상속이 된다.
상세되지 않는 프로퍼티라도, width: inherit;을 지정하면 상속받도록 할 수 있다.
상세 내용은 이쪽을 살펴보면 된다. www.w3.org/TR/CSS21/propidx
Cascading
한 요소는 여러 CSS문에 영향을 받을 수 있다. class, id가 모두 있는 p태그라면 세 선택자에서 모두 영향을 받는다.
이때 충돌을 해결하기 위해 우선순위(Cascading Order)가 필요하다.
Origin of CSS declarations (선언 장소에 따라 우선)
HTML <head> 내의 <style> 태그 > <link href="file.css" rel="stylesheet"> > 브라우저 디폴트 스타일시트
Specificity (구체적으로 선택할수록 우선)
!important > (html 요소 태그 내에 사용되는) 인라인 스타일 > 아이디 선택자 > 클래스/어트리뷰트/가상 선택자 > 태그 선택자 > 전체 선택자 > 상위 요소에 의해 상속된 속성
아래 페이지에 보면 specificity 정도를 결정하는 표가 있다. inline은 1000점, 아이디 선택자는 100점, 일반 태그는 1점 등이다.
developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance태그는
Source Order
중요도가 같다면 나중에 선언한 속성이 적용된다.
'FrontEnd > CSS' 카테고리의 다른 글
[HTML & CSS] Google Clone (2) 내비게이션, 검색 (0) 2021.02.22 [HTML & CSS] Google Clone (1) Flex Container, 로고, footer (0) 2021.02.21 [CSS] Font, Background (0) 2021.02.21 CSS - 선택자, 속성값, Reset CSS (0) 2021.02.17