[HTML·CSS] CSS 적용 방식과 박스 모델·시맨틱 레이아웃
목차
CSS 기본 구조

선택자는 HTML 안에서 스타일을 적용할 대상을 지정한다.

아래 예시에는 디자인 속성이 2가지 들어 있다.
.css(선택자). {margin:30px; color: #000;}
{}안은 선언 블록으로, 각각의 스타일을 선언한다(여기서는 2개).margin은 속성,30px은 값이다.
CSS 적용 방식
1) 내부(Internal) 형식 - <style> 태그 사용
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type = "text/css">
h1{
color:#00cc00; /*글자색*/
font-family: consolas; /*글자체*/
font-size:50pt; /*글자크기*/
} /*여기가 하나의 스타일*/
h2{
color:pink;
font-family: 궁서체;
font-size:20pt;
}/*여기가 하나의 스타일*/
</style>
</head>
<body>
<h1> css test </h1>
<h2> 내부 파일 형식</h2>
</body>
</html>
2) 외부(External) 형식 - 별도 CSS 파일 사용
mystyle.css 파일을 만들어 분리한다.
@charset "UTF-8";
h1{
color:magenta;
}
ul{
color:rgb(255,153,0);
list-style-type:square;
}

- 외부에 있는 스타일이 내부 스타일에 의해 덮어쓰기가 되어버린다.
- 가끔 필요에 의해 링크 태그를 내부 스타일보다 뒤에 적는 경우가 있는데, 이럴 경우 스타일이 다르게 나올 수 있다.
<link> 태그 대신 @import로도 외부 파일을 불러올 수 있으며 결과는 동일하다.
<!-- <link rel = "stylesheet" type = "text/css" href = "./mystyle.css"> -->
<style type = "text/css">
@import url("./mystile.css"); /*외부파일형식*/
3) 인라인(Inline) 형식 - 태그 안에 직접 작성
<h2 style = "color:pink;"> 세계 3대 미항 </h2> <!-- inline형식 -->
태그 안에 바로 스타일을 넣는 방식을 인라인 방식이라 한다. 다만 인라인 방식은 재사용성이 제일 떨어진다.
구글 폰트(웹 폰트) 사용

폰트 목록에서 1 style은 세부 스타일이 1개라는 뜻이다. 여기서 Akaya를 선택한다.


그러면 앞에서 본 것처럼 2가지 방식(<link>, @import)이 제공된다.

하나 더 찾아서 추가해 본다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Akaya+Telivigala&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Oi&display=swap" rel="stylesheet">
<!-- 웹 폰트에서 가져옴(구글폰트) -->
<style type = "text/css">
p{
font-family: 'Akaya Telivigala', cursive; /* 글자체 따옴표로 묶은건 공백이 있어서 */
color :magenta;
font-size:30pt;
}
h2{
font-family: 'Oi', cursive;
color:green;
font-size:20px;
}
/* 만약 처음 글자체 못 얻어오면 두번째 글자체 적용시키라는 뜻.(아까 h1,h2마냥 consolas가 없으면 궁서체 적용처럼) */
</style>
</head>
<body>
<h2>browser basic font</h2>
<p>this is web font <p>
</body>
</html>
- 글자체에 공백이 있으면 따옴표로 묶는다.
- 콤마로 여러 글자체를 적으면, 첫 글자체를 못 얻어올 때 두 번째 글자체를 적용한다(앞의
consolas없으면 궁서체 적용과 같은 원리).

클래스(class)와 아이디(id) 선택자
선택자로 태그 이름을 적지 않고, .(클래스)이나 #(아이디)으로 시작해 이름을 정하고 속성을 준다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- class/id: 동일한 스타일을 세분화 시켜 적용할 때 사용 -->
<style type = "text/css">
.blue{
color:blue;
}
.green{
color:green;
}
.red{
color:red;
}
#pink{ /* #: 아이디 */
color:pink;
}
</style>
</head>
<body>
<body>
<h1 class = "blue">this is body the first h1 tag.</h1>
<h1 class = "green">this is body the second h1 tag.</h1>
<h1 class = "red">this is body the third h1 tag.</h1>
<h1 class = "green">this is body the third h1 tag.</h1>
<h1 id = "pink">this is body the third h1 tag.</h1>
<p class = "blue"> hhhjsdf</p>
</body>
</body>
</html>
id는 CSS가 적용되긴 하지만, 같은id가 붙은 태그가 2개가 되면 문제가 생긴다.- 나중에 자바스크립트로 아이디가
pink인 대상을 찾아 쓰려 할 때, 중복이면 원하는 대상을 고를 수 없게 된다. id는 CSS에 적용할 때도#을 붙여서 사용한다.
h1 id = "pink"
id는 사실 식별자로 쓰려고 붙인 것이지 CSS 용도로 붙인 것은 아니다.
class/id : 동일한 스타일을 세분화시켜 적용할 때 사용. 아무 클래스나 만들어 넣을 수 있다.
박스 모델(Box Model)
박스 모델은 HTML 태그를 둘러싼 사각형 영역을 의미한다.
- 콘텐츠 안쪽 여백 = 패딩(padding)
- 그 바깥 경계선 = 보더(border)
- 보더 바깥 여백 = 마진(margin)
즉, border 기준으로 안쪽은 패딩, 바깥쪽은 마진이다.

보더를 기준으로 안쪽에 들어가는 부분이 패딩이다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type = "text/css">
p{
border-color:red;
border-style:solid;
border-width:2px; /* 두께 */
}
</style>
</head>
<body>
<!-- box model : html tag를 둘러싼 주변의 사각형 -->
<p>this is p tag.</p>
<p>this is p tag.</p>
</body>
</html>


페이지 검사(개발자 도구)를 통해 각 패딩, 마진, 보더의 상세 정보를 확인할 수 있다.

- 마진은 공유해서 쓴다(margin collapse). 마진을 30px과 50px로 줬다면, 더 큰 50px을 기준으로 띄운다.

상하좌우 패딩을 다르게 주고 싶다면 다음처럼 적는다.
padding :20px 30px 40px 50px; /*보더기준 안 쪽 여백 사방 지정 가능*/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type = "text/css">
p{
/* border-color:red;
border-style:solid;
border-width:2px; */
border : 2px blue dotted;
padding :20px 30px 40px 50px; /*보더기준 안 쪽 여백 사방 지정 가능*/
margin :30px
}
</style>
</head>
<body>
<!-- box model : html tag를 둘러싼 주변의 사각형 -->
<p>this is p tag.</p>
<p>this is p tag.</p>
</body>
</html>
border 형식 테스트
solid, double, dotted, groove, ridge, inset, outset, dashed 등 다양한 border 스타일을 테스트해 본다.
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
<style type="text/css">
.solid{
border: 10px solid red ;
}
.double{
border: 10px double blue;
}
.dotted{
border: 10px dotted blue;
}
.groove{
border: 10px groove blue;
}
.ridge{
border: 10px ridge blue;
}
.inset{
border: 10px inset blue;
}
.outset{
border: 10px outset blue;
}
.dashed{
border: 10px dashed blue;
}
</style>
</head>
<body>
<p class="solid">solid border</p>
<p class="double">double border</p>
<p class="dotted">dotted border</p>
<p class="groove">groove border</p>
<p class="ridge">ridge border</p>
<p class="inset">inset border</p>
<p class="outset">outset border</p>
<p class="dashed">dashed border</p>
</body>
</html>

실습: 안내 박스 페이지
이제 응용해서 간단한 프로젝트를 구현해 본다.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>market</title>
<style type = "text/css">
#container{
width:650px; /*제일 큰 애*/
/*650을 중앙에 두고 남는 크기를 반반 둠.*/
margin : 0 auto;/*중앙 정렬 */
/*0은 상하, auto는 좌우 값을 정렬*/
/* border:1px solid red; */
padding : 5px;
}
#check{
width:640px; /*컨텐츠 담고 있는 애*/
border:1px solid #ccc;
}
h1 {
color: white; /* 글자색 */
font-size: 1em; /* 글자 크기 */
background: #222; /* 배경색 background-color:black;*/
margin: 0; /* 제목과 다른 요소 간의 마진 여백 */
padding: 10px; /* 테두리와 제목 텍스트 사이의 패딩 여백 */
}
h2 {
color: #ff0000; /* 글자색 color : red;*/
font-size: 1.2em; /* 글자 크기 */
text-align: center; /* 가운데 정렬 */
}
p {
font-size: 1.5em; /* 글자 크기 */
line-height: 2em; /* 줄높이 */
font-weight: bold; /* 굵게 */
text-align: center; /* 가운데 정렬 */
}
.accent {
color: blue; /* 글자색 */
}
.smalltext {
font-size: 10pt; /* 글자 크기 */
color:green;
}
*/
</style>
</head>
<body>
<div id="container">
<div id="check" margin : 0 auto;>
<h1>확인하세요</h1>
<h2>주문 및 배송</h2>
<p><span class= "accent">오후 2시 이전 </span>주문건은 당일 발송합니다<br>
2시 이후 주문건은 다음날 발송합니다(주말 제외)</p>
<hr>
<h2>교환 및 환불</h2>
<p><span class= "accent">불만족</span>시 100% 환불해 드립니다<br>
고객센터로 전화주세요</p>
<hr>
<h2>SSAFY고객센터 </h2>
<p>1234-5678<br>
<span class = "smalltext">상담시간 : 오전 9시 ~ 오후 6시 (토/일, 공휴일 휴무)</span></p>
</div>
</div>
</body>
</html>
CSS 길이 단위
상대적인 단위
em: 현재 사용 중인 폰트 크기를 1로 함ex: 문자 ‘x’의 크기를 1로 함px: 모니터의 화소(“픽셀”)에 대한 상대적인 크기
절대적인 단위
in: inches, 1in = 2.54cmcm: centimetersmm: millimeterspt: points, 1pt = 1/72inpc: picas, 1pc = 12pt
블록 요소와 인라인 요소
엘리먼트(element)가 태그(tag)보다 더 큰 요소다.
1) 블록(block) 요소
h1,h2,p등 줄바꿈이 되는 태그div도 블록 요소이며,span은 기능은div와 같지만 줄바꿈이 안 된다.
2) 인라인(inline) 요소
- 줄바꿈이 되지 않는 태그
span,a등이 있다.
각 블록 요소와 인라인 요소는 CSS display 속성으로 서로 바꿀 수 있다.

- 위 메뉴는
li안의 글자라 색이 잘 바뀌지만, 아래는 글자가 앵커(a) 태그 안에 소속되어 있어 색이 바뀌지 않는다. - 아래를 바꾸려면
ul li a태그를 대상으로 지정해야 한다.
ul li a { /* 계층구조 따라 가면서 ul 태그 밑에 li 태그 밑에 a 태그 */
text-decoration:none;
color: orange;
}
위처럼 넣어서 바꿔 본다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type = "text/css">
body{
background-color: pink;
}
h1,h2{
color:red;
}
ul li { /*ul 태그 아래 li를 의미*/
display: inline; /*화면 표시 형식을 inline 요소 처럼 줄바꿈 안함 */
padding: 0px 10px; /*보더 기준 안쪽 여백 */
letter-spacing: 10px; /*글자간격 */
text-transform: uppercase; /*대문자로 변경 */
}
ul li a { /* 계층구조 따라 가면서 ul 태그 밑에 li 태그 밑에 a 태그 */
text-decoration:none;
color: orange;
}
/* 만약 여기 menu 앞에 ul 이 없으면 모든 메뉴에서 공통 속성 */
ul.menu{
border-bottom: 1px solid blue;
border-top:1px solid blue;
text-align:center;
padding: 10px 0px; /*상하: 10px, 좌우:0px */
}
.green {
color: green;
}
/* ol li { ul 태그 아래 li를 의미
} */
</style>
</head>
<body>
<h1> list를 이용한 menu </h1>
<ul class = "menu green">
<li>coffee</li>
<li>milk</li>
<li>juice</li>
</ul>
<hr>
<ul class = "menu">
<li><a href = "#"> 회사소개 </a></li>
<li><a href = "#"> 도서 </li>
<li><a href = "#"> 자료실 </li>
<li><a href = "#"> 질문 답변 </li>
<li><a href = "#"> 동영상 강의 </li>
</ul>
</body>
</html>
float 연습

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>박스모델</title>
<style>
div {
padding:20px;
margin:10px;
width: 100px;
height: 100px;
}
.box1{
background:#ffd800;
float:left;
}
.box2 {
background: #0094ff;
float:left;
}
.box3 {
background: #00ff21;
float:right;
/*float : right */
}
.box4 {
background:#a874ff;
clear: both; /* 이전에 지정했던 float 속성을 모두 무효화시킴*/
}
</style>
</head>
<body>
<div class="box1">박스1</div>
<div class="box2">박스2</div>
<div class="box3">박스3</div>
<div class="box4">박스4</div>
</body>
</html>
clear: both는 이전에 지정한 float 속성을 모두 무효화시킨다.
시맨틱 태그(Semantic Tag)
div 대신 의미를 가진 시맨틱 태그(section, article 등)로 구역을 나눈다.
<section> <!-- 문서에서 구역을 나누는 역할의 태그 -->
<article> <!-- 기사(주제) 1건 -->
<h2>본문1</h2>
<div>
<p>재산권의 행사는 공공복리에 적합하도록 하여야 한다. 정부는 회계연도마다 예산안을 편성하여 회계연도 개시
90일전까지 국회에 제출하고, 국회는 회계연도 개시 30일전까지 이를 의결하여야 한다.</p>
<p>대통령의 임기가 만료되는 때에는 임기만료 70일 내지 40일전에 후임자를 선거한다. 제2항과 제3항의 처분에
대하여는 법원에 제소할 수 없다. 언론·출판에 대한 허가나 검열과 집회·결사에 대한 허가는 인정되지 아니한다.</p>
</div>
</article>
section안에article이 들어갔는데, 반대로article안에section이 들어갈 수도 있다.- 처음에
div태그로만 있던 구조를 시맨틱 태그로 바꿨다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>2단 레이아웃-메뉴/테이블</title>
<style type= "text/css">
</style>
</head>
<body>
<div>
<header>
<h1>사이트 제목</h1>
<nav>
<ul>
<li><a href="#">메뉴1</a></li>
<li><a href="#">메뉴2</a></li>
<li><a href="#">메뉴3</a></li>
<li><a href="#">메뉴4</a></li>
</ul>
</nav>
</header>
<aside> <!-- 메인 내용 아니고 부가적인 내용을 포함하는 부분 -->
<h2>사이드 바</h2>
<p>모든 국민은 근로의 의무를 진다. 국가는 근로의 의무의 내용과 조건을 민주주의원칙에 따라 법률로 정한다.</p>
</aside>
<section> <!-- 문서에서 구역을 나누는 역할의 태그 -->
<article> <!-- 기사(주제) 1건 -->
<h2>본문1</h2>
<div>
<p>재산권의 행사는 공공복리에 적합하도록 하여야 한다. 정부는 회계연도마다 예산안을 편성하여 회계연도 개시
90일전까지 국회에 제출하고, 국회는 회계연도 개시 30일전까지 이를 의결하여야 한다.</p>
<p>대통령의 임기가 만료되는 때에는 임기만료 70일 내지 40일전에 후임자를 선거한다. 제2항과 제3항의 처분에
대하여는 법원에 제소할 수 없다. 언론·출판에 대한 허가나 검열과 집회·결사에 대한 허가는 인정되지 아니한다.</p>
</div>
</article>
<article>
<h2>본문2</h2>
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>이 헌법시행 당시의 대법원장과 대법원판사가</td>
<td>강감찬</td>
</tr>
<tr>
<td>2</td>
<td>대한민국은 국제평화의 유지.</td>
<td>장영실</td>
</tr>
<tr>
<td>3</td>
<td>정당은 법률이 정하는 바에.</td>
<td>안중근</td>
</tr>
<tr>
<td>4</td>
<td>공공필요에 의한 재산권의 수용·</td>
<td>김두한</td>
</tr>
<tr>
<td>5</td>
<td>국회의원은 그 지위를 남용하여 국가·</td>
<td>계백</td>
</tr>
<tr>
<td>6</td>
<td>정기회의 회기는 100일을, 초과할 수 없다.</td>
<td>최무선</td>
</tr>
</tbody>
</table>
</article>
</section>
<footer>
<h2>푸터</h2>
<p>이 헌법시행 당시의 법령과 조약은 이 헌법에 위배되지 아니하는 한 그 효력을 지속한다.</p>
</footer>
</div>
</body>
</html>
테이블 홀수/짝수 행 구분 - nth-child
tbody tr:nth-child(2n){ /*바디에 들어가는 부분 , 홀수 짝수행 구분해줘야.*/
}
n은 n번째 자식을 의미하며,tr의 몇 번째 자식인지 따져서 CSS를 적용하거나 적용하지 않는다.n이 0부터 시작한다고 생각하면2n은 짝수로 올라간다.tr을 선택할 때 해당 내용을 적용시켜 올린다는 뜻이다.
실무에서는 이렇게 일일이 적용하기보다 라이브러리로 구현된 부분을 가져와 적용한다. 그래도 수정이나 구현을 하려면 어느 정도는 알아둬야 한다.
실습: 2단 레이아웃 페이지
이제껏 배운 것으로 간단한 페이지를 만들어 본다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>2단 레이아웃-메뉴/테이블</title>
<style type="text/css">
#container{ /* 전체 다 포함시키는거라 중앙정렬 시키자. */
width: 960px;
margin: 0px auto;/*중앙정렬*/
padding: 20px;
border: 1px solid red;
}
header{
padding: 20px;
margin-bottom:20px; /*헤더 아래쪽 태그들과의 여백*/
background-color: #88cc00;
}
#contents{ /*section: 본문. 왼쪽으로 가야 함*/
width: 620px;
float: left;
border: 1px solid #ccc;
padding: 20px;
margin-bottom:20px;
}
#sidebar{
width: 220px;
float: right;
padding: 20px;
margin-bottom:20px;
border: 1px solid #ccc;
background-color: #eee;
}
#footer{
clear:both;/*이전에 float 값 취소. */
border: 1px solid #ccc;
padding: 20px;
}
article div{ /* 자기를 포함하던 article 100%면 꽉 차게 */
background-color: #e6e600;
width: 90%;
/* border: 1px solid red; 경계선*/
margin-left: auto;
margin-right: auto;
}
li{
display:inline;
}
li a{
text-decoration: none;
color: green;
text-align: center;
padding: 15px 15px;
}
table{
width: 90%;
margin-left: auto;
margin-right: auto;
border-collapse: collapse; /* 경계선이 밑에 바닥에 안 드러나게 해줘야 */
}
th, td{
border-bottom: 1px solid gray;
padding: 10px;
text-align: center;
}
thead tr{ /*헤더에 들어가는 제목부분*/
background-color: #0d47a1;
color: white;
}
tbody tr:nth-child(2n){/* 0~ 짝수행*/
background-color: #bbdefb;
}
tbody tr:nth-child(2n + 1){/* 1~ 홀수행*/
background-color: #e3f2fd;
}
</style>
</head>
<body>
<div id="container">
<header> <!-- semantic tag: html5에서 추가된 태그들 -->
<h1>사이트 제목</h1>
<nav>
<ul>
<li><a href="#">메뉴1</a></li>
<li><a href="#">메뉴2</a></li>
<li><a href="#">메뉴3</a></li>
<li><a href="#">메뉴4</a></li>
</ul>
</nav>
</header>
<aside id="sidebar"> <!-- 메인 내용 아니고 부가적인 내용을 포함하는 부분 -->
<h2>사이드 바</h2>
<p>모든 국민은 근로의 의무를 진다. 국가는 근로의 의무의 내용과 조건을 민주주의원칙에 따라 법률로 정한다.</p>
</aside>
<section id="contents"> <!-- 문서에서 구역을 나누는 역할의 태그 -->
<article> <!-- 기사(주제) 1건 -->
<h2>본문1</h2>
<div>
<p>재산권의 행사는 공공복리에 적합하도록 하여야 한다. 정부는 회계연도마다 예산안을 편성하여 회계연도 개시
90일전까지 국회에 제출하고, 국회는 회계연도 개시 30일전까지 이를 의결하여야 한다.</p>
<p>대통령의 임기가 만료되는 때에는 임기만료 70일 내지 40일전에 후임자를 선거한다. 제2항과 제3항의 처분에
대하여는 법원에 제소할 수 없다. 언론·출판에 대한 허가나 검열과 집회·결사에 대한 허가는 인정되지 아니한다.</p>
</div>
</article>
<article><!-- 기사(주제) 1건 -->
<h2>본문2</h2>
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>이 헌법시행 당시의 대법원장과 대법원판사가</td>
<td>강감찬</td>
</tr>
<tr>
<td>2</td>
<td>대한민국은 국제평화의 유지.</td>
<td>장영실</td>
</tr>
<tr>
<td>3</td>
<td>정당은 법률이 정하는 바에.</td>
<td>안중근</td>
</tr>
<tr>
<td>4</td>
<td>공공필요에 의한 재산권의 수용·</td>
<td>김두한</td>
</tr>
<tr>
<td>5</td>
<td>국회의원은 그 지위를 남용하여 국가·</td>
<td>계백</td>
</tr>
<tr>
<td>6</td>
<td>정기회의 회기는 100일을, 초과할 수 없다.</td>
<td>최무선</td>
</tr>
</tbody>
</table>
</article>
</section>
<footer id="footer">
<h2>푸터</h2>
<p>이 헌법시행 당시의 법령과 조약은 이 헌법에 위배되지 아니하는 한 그 효력을 지속한다.</p>
</footer>
</div>
</body>
</html>
각 부분은 주석으로 설명을 달아 두었다.