Web : CSS (Box Model)
이번에는 뼈대에 살을 붙여볼 차례다. 다양한 예시로 이해하시겠지만, 나는 해골에서 사람으로 변화하는 과정이라고 생각한다. 외운다면 굉장히 할게 많겠지만, 주로 쓰이는 것은 자동적으로 외워질 것이고 써야할 부분이 생긴다면 검색을 통해 해결해나가는 것도 방법이다. 놀라운 점은 html css는 네모네모 빔에 맞아서 기본은 네모에서 시작한다는 점이다. 그럼 원이나 삼각형은 어떻게?? 만드냐고? 그것은 다양한 명령을 전달해서 네모를 깎아 만든다고 생각하면 된다. 천천히 css에 쓰이는 명령어를 보면서 이해하자.
CSS Box Model
: 먼저 알아야 할 원칙이 3가지 있다.
CSS원칙 첫번째는 모든 Html 요소를 사각형 박스로 표현하는 개념으로 다양한 모양은 직접 깎아만드는 것이다. 또한 기본적으로 위에서부터 아래로, 왼쪽에서부터 오른쪽으로 쌓이게 된다. (좌측 상단 배치)
Google 홈페이지에서 키보드의 F12 버튼을 눌러 개발자 도구(Developer Tools)를 살펴볼 수 있다. 개발자 도구에 관해서는 잠시 뒤에 다룰 예정이다.
CSS Box model의 기본 구성요소 4가지
- 내용(content)
글이나 이미지 등 요소의 실제 내용이 기입되는 공간이다.
- 안쪽 여백(padding)
테두리 안쪽의 내부 여백으로 요소에 적용되는 배경색, 이미지는 padding까지 적용된다.
- 테두리(boreder)
테두리 영역으로 padding을 감싸고 있다.
- 외부 간격(margin)
테두리 바깥의 외부 여백으로 배경색을 지정할 수 없다.
위 이미지의 예시로
border: 상, 하, 좌, 우 = 1px
margin: 상, 하 = 11px, 좌, 우 = 4px
padding: 상, 하 = 0px, 좌, 우 = 16px
content: 상, 하 = 34px, 좌, 우 = 108.938px
임을 확인할 수 있다. 여기서 content의 height가 개발자 도구에는 height: 36px로 기입되어있는데 왜 34px인지 궁금해야 한다. padding의 상, 하는 0px이므로 아닐 것 같고, border가 사방으로 1px이 만들어져있다는 것을 알 수 있다. 따라서 한개의 Box 크기는 border+padding+content 라는 것을 알 수 있다. 그렇다면 나는 content의 내용을 width 고정하고 싶었는데, 계속 border와 padding의 크기를 계산해주는 번거로움이 있을 수 있다.
이를 해결하기위해 width 값을 계산하는 기준을 바꿔줄 수 있다.
shorthand & 속성
Box 구성 | 방향 | 상 / 우 / 하 / 좌 :요소 4개 | 상 / 좌 + 우 / 하 :요소 3개 | 상 + 하 / 좌 + 우 | 상 + 우 + 하 + 좌 |
margin padding |
padding: 15px 10px 10px 15px; > 상 방향 15px > 우 방향 10px > 하 방향 10px > 좌 방향 15px |
padding: 15px 10px 5px; > 상 방향 15px > 우 + 좌 방향 10px > 하 방향 5px |
margin: 15px 10px; > 상 + 하 방향 15px > 우 + 좌 방향 10px |
margin: 10px; > 4방향 10px |
네 방향이 모두 같은 값을 같는다면, shorthand를 통해 표현할 수 있다. 유의할 점은 요소가 3개일때와 4개일때 인데, 평상시에 쓰는 단어가 상 하 좌 우 인데, 요소가 4개일때는 상 우 하 좌 로 시계방향임을 기억하자. 요소가 3개일때는 위에서부터 아래로 상 좌+우 하이다.
또한 숫자나 단위 대신 auto;인 경우는 브라우저의 크기를 자동으로 계산해 적절한 크기를 지정한다. 정중앙으로 정렬할 때 쓰인다.
그렇다면 사각형 하나를 만들어서 정렬해볼까?
그럼 초기값이 margin-right: auto;로 되어있어서 좌상단에 박스가 위치할까? 그것은 아니다. 바로 아래에서 다룰 것이지만 div는 block 박스타입이기 때문에 생성하면 한 줄이 모두 포함되고 html은 좌 상단을 규칙으로 Normal Flow를 지키기 때문이다.
그럼 box를 오른쪽으로 이동시키려면 어떻게 하면 될까? box를 정렬하면 될까? 박스(content)의 바깥쪽 영역을 설정해야하니 padding과 border는 아닐 것이다. 그럼 margin을 왼쪽에 걸어볼까?
여기서 잘 생각해야 할 점은, 어디에 속성을 부여할지 잘 생각해보자. 예를들어 PPT에서 무언가를 정렬할 때 어디를 기준으로 정렬해야 하는지, 어딜 클릭해야 이동하는지 상상해보며 속성을 부여할 곳을 찾는 것도 좋다. (내가 PPT를 잘쓴다.)
오른쪽을 했으니 중앙도 해봐야겠지 않을까?
왼쪽의 margin-left를 auto로 걸어서 최대치를 넣었다면 좌 우 모두 넣어주면 되지 않을까? 그렇다면 이번엔 두개 다 넣으면 될거 같구나.
개인적으로 느끼는 바이지만, 배울때는 아 이건 이거다! 해서 바로 맞추는 것도 좋지만, 여러가지를 시도해봐도 좋을 것 같다. 교육서를 보면서 해도 정렬할 때 text-align도 써보고 align-items도 써보고 여러가지 시행착오가 있었다. 실제로 text-align은 text를 조정하는 것, align-items는 나중에 배울 flexbox에서 사용되는 속성이다.
속성 | 정의 |
auto | 기입하지 않는다면 초기값. 조화로운 최대치로 정렬 |
initial | 부모 요소로부터 상속받은 속성 값을 무시하고 초기값으로 되돌린다 기본값보다 우선순위가 높다 |
inherit | 부모 요소의 값을상속 받음 |
unset | 명시되지 않은 경우와 동일하다 기본값보다 우선순위가 낮아 기본값이 있다면 기본값으로 적용된다 |
auto이외에는 자주 사용해본 적은 없으나 다양한 속성이 있다.
박스 타입(Box Type)
: HTML에 CSS를 적용하지 않았을 경우 웹 페이지 요소가 기본적으로 배치되는 방향은 위의 그림과 같다.
block 타입 | inline 타입 |
> 항상 새로운 행으로 나뉘어 작성된다 > width와 height 속성을 사용하여 너비와 높이를 지정할 수 있다 > 기본적으로 width 속성을 지정하지 않으면 박스는 inline 방향으로 사용 가능한 공간을 모두 차지한다 (width를 사용가능한 공간의 100%로 채우는 것) > 대표 block 타입 태그 (h1 ~ h6, p, div) |
> 새로운 행으로 나뉘지 않는다 > width와 height 속성을 사용할 수 없다 > 수직방향 padding, margin, border가 적용되지만 다른 요소를 밀어낼 수는 없음 > 수평방향 padding, margin, border가 적용되어 다른 요소를 밀어낼 수 있음 > 대표 inline 타입 태그 (a, img, span) |
그렇다면 일일이 block 타입과 inline 타입을 바꾸어가며 써야할까??? 다행히 아니다. display 속성에 직접 설정을 해줄 수 있다. 먼저 다뤄볼 속성은 4개인데, 이후에 flex와 grid에 대해서 다룰 예정이니 지금은 잠깐 넣어두자. 위에는 기본적으로 타입 태그에 설정된 기본 값이며, display로 정의를하면 설정값을 재정의 할 수 있다고 보면 된다.
display 속성들을 간단히 살펴보자(block과inline은 위와 동일하다)
속성 | 정의 |
display: block; | 타입을 block으로 지정하며, 항상 새로운 줄에서 시작하고 최대 가로폭을 차지한다 |
display: inline; | 타입을 inline으로 지정하며, 다른 인라인 요소와 함께 텍스트 흐름에 따라 배치되며 새로운 줄에서 시작하지 않는다. |
display: inline-block; | 타입을 inline block으로 지정하며, text 흐름에 따라 배치되면서동시에 크기와 내용을 제어할 수 있다. 새로운 줄에서 시작하지 않고 다른 inline 요소와 함께 배치된다. |
display: none; | 타입을 숨기고 렌더링되지 않는다. 레이아웃에서 차지하는 공간도 없다. 주로 동적 요소 제어하는 JavaScript와 함께쓰이기도 한다. |
그럼 애초에 span으로 쓰면 되는거 아닌가? 싶은데, 실상 기술상으로는 차이가 없다. 굳이 block 속성을 inline으로, inline을 block속성으로 바꾸는 것보다 타입 태그를 잘 쓰는게 중요할 수 있다.
display: none; 은 어디에 쓰이는지 감이 안 잡힐 수 있는데, 티스토리에도 사용되고 있다. 아마 블로그 글을 보면서 오른쪽에 하나 따라다니는 친구가 있을텐데,
버튼을 클릭하면 새로운 목록들이 뜰 것이다. 그럼 이 항목들은 어디서 온걸까? 우린 새로운 페이지로 이동하지도 않았는데 말이다. 이들은 이미 로드되어있고 존재하고있다. 다만 보이지 않았고, 표현을 막아두었다. 이때, display:none;을 사용한다. 레이아웃에서 차지하는 공간도 없으며 렌더링되어있지 않는다는것은 이 뜻이다. 크롬 개발자 도구를 통해 확인해볼까?
앞서 보여준 리스트가 보이지 않는데 만약 버튼을 누르고 개발자 도구를 확인해본다면 ?
css의 분량이 조금 많은 편이라 2편까지 있을 것 같고 더 길다면 3편까지 나올 것같다. 뭔가 가지나물만 먹다가 고등어 먹는 기분이랄까? 나름 눈에 보이는 것을 만들다보니 흥미도 생기는 것 같다. 하지만 제대로 만들어지지 않을때 만큼은 알고리즘도 그립다..