ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CSS] Box Model , Display, Position, float
    FrontEnd/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인 경우 해당 요소를 제외하고 배치된다. 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: left;

     

    float: 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

    중요도가 같다면 나중에 선언한 속성이 적용된다.

    댓글

Designed by Tistory.