position 속성은 요소의 위치를 정의한다. top, bottom, left, right 속성과 함께 사용하여 위치를 지정한다.
static은 position 속성의 기본값으로 position 속성을 지정하지 않았을 때와 같다.
기본적인 요소의 배치 순서에 따라 위에서 아래로, 왼쪽에서 오른쪽으로 순서에 따라 배치되며 부모 요소 내에 자식 요소로서 존재할 때는 부모 요소의 위치를 기준으로 배치된다.
기본적으로 이 값을 지정할 일은 없지만 이미 설정된 position을 무력화하지 위해 사용할 수 있다.
좌표 속성(top, bottom, left, right)를 같이 사용할 수 없으며 사용될 경우 무시된다.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; }
.parent {
width: 150px;
height: 150px;
background: #bcbcbc;
border: 1px solid #bcbcbc;
}
.static-box {
position: static;
background: #2E303D;
color: #e55c3c;
font-weight: bold;
text-align: center;
line-height: 150px;
}
</style>
</head>
<body>
<div class="parent">
<div class="static-box">static box</div>
</div>
</body>
</html>
기본 위치(static으로 지정되었을 때의 위치)를 기준으로 좌표 속성(top, bottom, left, right)를 사용하여 위치를 이동시킨다. static을 선언한 요소와 relative를 선언한 요소의 차이점은 좌표 속성의 동작 여부뿐이며 그 외는 동일하게 동작한다.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; }
.parent {
width: 150px;
height: 150px;
background: #bcbcbc;
border: 1px solid #bcbcbc;
margin: 50px;
}
.relative-box {
position: relative;
top: 50px; left: 50px;
background: #2E303D;
color: #e55c3c;
font-weight: bold;
text-align: center;
line-height: 150px;
}
</style>
</head>
<body>
<div class="parent">
<div class="relative-box">relative box</div>
</div>
</body>
</html>
위의 코드에서 parent 클래스의 자식인 relative-box 클래스 요소의 width, height가 부모 요소와 동일하다. 이는 상속에 의한 것이 아니라(width, height는 상속되지 않는다.) relative를 적용한 요소는 좌표 속성이 적용되는 것만 다를 뿐 그 이외는 static을 지정했을 때와 동일하게 동작하기 때문이다. 즉 width는 100%가 적용되어 부모 요소의 width와 동일한 값을 갖게된 것이고, height는 auto가 적용되지만 line-height: 150px이 적용되어 부모 요소와 hight가 동일하게 된 것이다.
부모 요소 또는 가장 가까이 있는 조상 요소(static 제외)를 기준으로 좌표 속성(top, bottom, left, right)만큼 이동한다. 즉, relative, absolute, fixed 속성이 선언되어 있는 부모 또는 조상 요소를 기준으로 위치가 결정된다.
만일 부모 또는 조상 요소가 static인 경우, document body를 기준으로 하여 좌표 속성대로 위치하게 된다.
따라서 부모 요소를 배치의 기준으로 삼기 위해서는 부모 요소에 relative를 정의해야한다.
이때 다른 요소가 먼저 위치를 점유하고 있어도 뒤로 밀리지 않고 덮어쓰게 된다.(이런 특성을 부유 또는 부유 객체라 한다.)
absolute 선언 시, block 속성 요소의 width는 inline 요소와 같이 content에 맞게 변화되므로 적절한 width를 지정하여야 한다.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; }
.parent {
width: 200px;
height: 200px;
background: #bcbcbc;
border: 1px solid #bcbcbc;
margin: 50px 0 0 300px;
position: relative;
}
.absolute-box {
position: absolute;
height: 200px; width: 200px;
top: 50px; left: 50px;
color: #e55c3c;
font-weight: bold;
text-align: center;
background: #2E303D;
line-height: 200px;
}
</style>
</head>
<body>
<div class="parent">
<div class="absolute-box">absolute box (in parent)</div>
</div>
<div class="absolute-box">absolute box (no parent)</div></body>
</html>
relative 속성과 absolute 속성의 차이점은 아래와 같다.
relative 속성은 기본 위치(static으로 지정되었을 때의 위치)를 기준으로 좌표 속성(top, bottom, left, right)을 사용하여 위치를 이동시킨다. 따라서 무조건 부모를 기준으로 위치하게된다.
absolute 속성은 부모에 static 이외의 position 속성이 지정되어 있을 경우에만 부모를 기준으로 위치하게 된다. 만일 부모, 조상이 모두 static 속성인 경우, document body를 기준으로 위치하게 된다.
따라서 absolute 속성 요소는 부모 요소의 영역을 벗어나 자유롭게 어디든지 위치할 수 있다.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0;}
.parent {
width: 150px;
height: 150px;
background: #bcbcbc;
border: 1px solid #bcbcbc;
margin: 50px;
float: left;
/*position: relative;*/
}
.relative-box {
position: relative;
top: 10px; left: 10px;
width: 150px;
height: 150px;
background: #2E303D;
color: #e55c3c;
font-weight: bold;
text-align: center;
line-height: 150px;
}
.absolute-box {
position: absolute;
top: 10px; left: 10px;
width: 150px;
height: 150px;
background: #2E303D;
color: #e55c3c;
font-weight: bold;
text-align: center;
line-height: 150px;
}
</style>
</head>
<body>
<div class="parent">
<div class="absolute-box">absolute box</div>
</div>
<div class="parent">
<div class="relative-box">relative box</div>
</div>
</body>
</html>
부모 요소와 관계없이 브라우저의 viewport를 기준으로 좌표 속성(top, bottom, left, right)을 사용하여 위치를 이동시킨다.
스크롤이 되더라도 화면에서 사라지지 않고 항상 같은 곳에 위치한다.
fixed 속성 사용시, block 요소의 width는 inline 요소와 같이 content에 맞게 변화되므로 적절한 width를 지정해야한다.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; }
.fixed-box {
position: fixed;
color: #e55c3c;
font-weight: bold;
text-align: center;
background: #2E303D;
}
.sidebar {
width: 50px;
height: 100%;
top: 0;
right: 0;
padding-top: 100px;
}
.footer {
width: 200px;
width: 100%;
height: 50px;
bottom: 0;
left: 0;
line-height: 50px;
}
</style>
</head>
<body>
<div class="fixed-box sidebar">fixed box (side-bar)</div>
<div class="fixed-box footer">fixed box (footer)</div>
</body>
</html>
z-index 속성에 큰 숫자값을 지정할수록 화면 전면에 출력된다. position 속성이 static 이외인 요소에만 적용된다.
<!DOCTYPE html>
<html>
<head>
<style>
.normal-box {
width: 100px; height: 100px;
}
.absolute-box {
width: 100px; height: 100px;
position: absolute;
}
/* z-index는 positon 프로퍼티가 static 이외인 요소에만 적용된다. */
.orange {
background-color: orange;
z-index: 1000;
}
.red {
background-color: red;
left: 50px; top: 50px;
z-index: 100;
}
.green {
background-color: green;
left: 100px; top: 100px;
z-index: 10;
}
.blue {
background-color: blue;
left: 150px; top: 150px;
z-index: 1;
}
</style>
</head>
<body>
<div class="normal-box orange"></div>
<div class="absolute-box red"></div>
<div class="absolute-box green"></div>
<div class="absolute-box blue"></div>
</body>
</html>
overflow 속성은 자식 요소가 부모 요소의 영역을 벗어났을 때 처리 방법을 정의한다.
속성값 | 설명 |
---|---|
visible | 영역을 벗어난 부분을 표시한다.(기본값) |
hidden | 영역을 벗어난 부분을 잘라내어 보이지 않게 한다. |
scroll | 영역을 벗어난 부분이 없어도 스크롤 표시한다.(현재 대부분 브라우저는 auto와 동일하게 작동한다.) |
auto | 영역을 벗어난 부분이 있을 때만 스크롤을 표시한다. |
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 150px;
height: 150px;
padding: 10px;
margin: 30px;
font-size: 1.2em;
border-radius: 6px;
border-color: gray;
border-style: dotted;
float: left;
}
.visible { overflow: visible; }
.hidden { overflow: hidden; }
.scroll { overflow: scroll; }
.auto { overflow: auto; }
</style>
</head>
<body>
<h1>overflow</h1>
<div class="visible"><h3>visible</h3>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div class="hidden"><h3>hidden</h3>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div class="scroll"><h3>scroll</h3>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div class="auto"><h3>auto</h3>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
</body>
</html>
특정 방향으로만 스크롤을 표시하고자 할 때는 overflow-x 또는 overflow-y 속성을 사용한다.
div { overflow-y: auto; }
float 속성은 주로 레이아웃을 구성할 때 블록 레벨 요소를 가로 정렬하기 위해 사용되는 중요한 기법이다. flexbox 레이아웃을 사용한다면 더욱 간단하게 정렬을 구현할 수도 있지만 flexbox 레이아웃을 지원하지 않는IE를 고려한다면 float 속성을 사용해야 한다.
float 속성은 본래 아래 예제와 같이 이미지와 텍스트가 있을때, 이미지 주위를 텍스트로 감싸기 위해 만들어진 것이다.
<!DOCTYPE html>
<html>
<head>
<style>
img {
float: left;
margin-right: 10px;
}
</style>
</head>
<body>
<img src="https://poiemaweb.com/img/doug.jpg">
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</body>
</html>
float 속성은 해당 요소를 다음 요소 위에 떠 있게(부유하게)한다. 여기서 떠 있다(float)는 의미는 요소가 기본 레이아웃 흐름에서 벗어나 요소의 모서리가 페이지의 왼쪽이나 오른쪽으로 이동하는 것이다. float 속성을 사용할 때 요소의 위치를 고정시키는 position 속성의 absolute를 사용하면 안된다.
속성값 | 설명 |
---|---|
none | 요소를 떠 있게 하지 않는다.(기본값) |
right | 요소를 오른쪽으로 이동시킨다. |
left | 요소를 왼쪽으로 이동시킨다. |
float 속성을 사용하지 않은 block 요소들은 수직으로 정렬된다. float:left 속성을 사용하면 왼쪽부터 가로로 정렬되고, float:rigth; 속성을 사용하면 오른쪽부터 가로로 정렬된다.
오른쪽 가로 정렬의 경우, 먼저 기술된 요소가 가장 오른쪽에 출력되므로 출력 순서가 역순이 된다.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
color: white;
font-weight: bold;
font-size: 50px;
border-radius: 6px;
width: 100px;
height: 100px;
margin: 10px;
padding: 10px;
}
.d1, .d2 {
float: left;
}
.d1 {
background: red;
}
.d2 {
background: orange;
}
.d3, .d4 {
float: right;
}
.d3 {
background: red;
}
.d4 {
background: orange;
}
</style>
</head>
<body>
<div class="container">
<div class="box d1"> 1 </div>
<div class="box d2"> 2 </div>
<div class="box d3"> 3 </div>
<div class="box d4"> 4 </div>
</div>
</body>
</html>
float 속성은 좌측, 우측 가로정렬만 가능하다. 중앙 가로 정렬은 margin 속성을 사용해야한다.
div {
width: 960px;
margin: 0 auto;
}
width 속성의 기본값은 100%이므로 width 속성값을 지정하지 않은 block 요소는 부모 요소의 가로폭을 가득 채운다.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
color: white;
font-weight: bold;
font-size: 30px;
line-height: 50px;
height: 50px;
margin: 0 10px;
padding: 10px;
}
.d1 {
background: red;
}
.d2 {
background: orange;
}
</style>
</head>
<body>
<div class="box d1"> div </div>
<div class="box d2"> div </div>
</body>
</html>
width 속성을 선언하지 않은 block 요소에 float 속성이 선언되면 width가 inline 요소와 같이 content에 맞게 최소화되고 다음 요소 위에 떠 있게(부유하게)된다.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
color: white;
font-weight: bold;
font-size: 30px;
line-height: 50px;
height: 50px;
margin: 0 10px;
padding: 10px;
}
.d1 {
float: left;
background: red;
}
.d2 {
background: orange;
}
</style>
</head>
<body>
<div class="box d1"> float: left; </div>
<div class="box d2"> div </div>
</body>
</html>
위의 코드에서 d1 클래스 요소에는 float:left; 를 선언하였고 d2 클래스 요소에는 float를 선언하지 않았다. 이 때 d1 클래스 요소는 width가 inline 요소와 같이 content에 맞게 최소화되고 다음 요소인 d2 클래스 요소 위에 떠 있게 (부유하게)된다.
주의할 것은 d1 클래스 요소가 d2 클래스 요소 위에 떠 있게 되어도 d2 클래스 요소의 width는 d1 클래스 요소가 차이한 width 만큼 줄어들지 않고 100% 유지한다는 점이다. 이는 d2 클래스 요소는 float를 선언하지 않았기 때문에 본래의 width를 유지하기 때문이다. 따라서 d2 클래스 요소는 본래의 width(100%)를 유지한 상태에서 d1 클래스 요소가 그 위에 위치한다.
위의 코드에서 두 요소는 차례대로 정렬된 것처럼 보이지만 사실은 float 속성이 선언된 요소가 다음 요소 위에 떠 있는 (부유하고 있는) 상태이다. 따라서 두 요소간 margin은 제대로 표현되지 않는다.
이것은 두번째 요소에 float 속성을 선언하지 않았기 때문에 발생하는 박스 모델 상의 문제이다. 이 문제를 해결하는 가장 쉬운 방법은 float 속성을 선언하지 않은 요소(d2)에 overflow:hidden; 를 부여하는 것이다.
overflow:hidden; 속성은 자식 요소가 부모 요소의 영역보다 클 경우 넘치는 부분을 안보이게 해주는 역할을 하는데 여기서 float 속성이 없어서 제대로 표현되지 못하는 요소를 제대로 출력해준다.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
color: white;
font-weight: bold;
font-size: 30px;
line-height: 50px;
height: 50px;
margin: 0 10px;
padding: 10px;
}
.d1 {
float: left;
background: red;
}
.d2 {
overflow: hidden;
background: orange;
}
</style>
</head>
<body>
<div class="box d1"> float: left; </div>
<div class="box d2"> div </div>
</body>
</html>
두 번째 요소에도 float 속성을 선언하면 overflow:hidden 속성은 선언하지 않아도 되지만 너비는 최소화 된다.
아래 코드에서 float속성이 선언된 두 개의 자식요소를 포함하는 부모 요소의 높이가 정상적인 값을 가지지 못하는 문제가 발생한다. float 요소는 일반적인 흐름상에 존재하지 않기 때문에 float 요소의 높이를 알 수 없기 때문인데 이 문제는 부모 요소 이후에 위치하는 요소의 정렬에 문제를 발생시킨다.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
color: white;
text-align: center;
padding: 10px;
background-color: #def0c2;
}
.d1, .d2 {
float: left;
width: 50%;
padding: 20px 0;
}
.d1 {
background-color: #59b1f6;
}
.d2 {
background-color: #ffb5b4;
}
</style>
</head>
<body>
<div class="container">
<div class="d1">1</div>
<div class="d2">2</div>
</div>
<div style="background:red;padding:10px;color:white;">3</div>
</body>
</html>
이 문제를 해결하는 가장 쉬운 방법은 float 속성이 선언된 자식 요소의 부모 요소(.container)에 overflow:hidden 속성을 선언하는 것이다.
다른 방법으로 부모 요소(.container)에 float 속성을 선언하는 방법도 있다. 하지만 부모 요소의 너비는 float된 두 개의 자식요소의 컨텐츠를 표현할 수 있는 만큼 작게 줄어들게 된다. 권장할 수 있는 방법은 아니다.
container 영역이 끝나기 직전 빈 요소를 만들고 clear:both를 설정하는 방법도 가능하다. 하지만 의미 없는 빈 요소를 사용하여야 하기 때문에 이 방법 역시 권장할 수 있는 방법은 아니다.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
color: white;
text-align: center;
padding: 10px;
background-color: #def0c2;
/*overflow: hidden;*/
}
.d1, .d2 {
float: left;
width: 50%;
padding: 20px 0;
}
.d1 {
background-color: #59b1f6;
}
.d2 {
background-color: #ffb5b4;
}
.clear {
height: 0;
clear: both;
}
</style>
</head>
<body>
<div class="container">
<div class="d1">1</div>
<div class="d2">2</div>
<div class="clear"></div>
</div>
<div style="background:red; padding:10px; color:white;">3</div>
</body>
</html>
overflow:hidden;과 함께 많이 사용되는 방법은 ::after 가상 요소 선택자를 이용하는 것이다. 가상 요소 선택자는 CSS2 문법(:after)과 CSS3 문법(::after)이 있는데 IE8까지 지원하는 CSS2 문법을 사용하는 편이 좋다.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
color: white;
text-align: center;
padding: 10px;
background-color: #def0c2;
/*overflow: hidden;*/
}
.clearfix:after {
content: "";
display: block;
clear: both;
}
.d1, .d2 {
float: left;
width: 50%;
padding: 20px 0;
}
.d1 {
background-color: #59b1f6;
}
.d2 {
background-color: #ffb5b4;
}
</style>
</head>
<body>
<div class="container clearfix">
<div class="d1">1</div>
<div class="d2">2</div>
</div>
<div style="background:red;padding:10px;color:white;">3</div>
</body>
</html>
부모 요소에 위와 같이 사적에 작성한 clearfix 클래스만 추가하거나, 해당요소를 클릭하여 클리어 문법만 선언하면 되기에 가장 깔끔하고 간편하다. 이 방법을 사용하는 것을 추천한다.
.clearfix:after {
content: "";
display: block;
clear: both;
}
/* or */
selector:after {
content: "";
display: block;
clear: both;
}
또 다른 방법은 float속성 대신 display:inline-block;을 선언하는 것이다. 주의해야할 점은 inline-block 속성 요소를 연속 사용하는 경우, 두 요소 사이에 정의하지 않은 공백(4px)가 자동 지정되는 것이다.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
color: white;
text-align: center;
padding: 10px;
background-color: #def0c2;
}
.d1, .d2 {
display: inline-block;
width: 50%;
padding: 20px 0;
}
.d1 {
background-color: #59b1f6;
}
.d2 {
background-color: #ffb5b4;
}
</style>
</head>
<body>
<div class="container">
<div class="d1">1</div>
<div class="d2">2</div>
</div>
<div style="background:red;padding:10px;color:white;">3</div>
</body>
</html>
위의 코드에서 d1, d2 요소에 display:inline-block;을 선언하여 텍스트와 같이 배치되도록 하였지만 두 요소 사이에 정의하지 않은 공백(4px)이 자동으로 지정되어 부모 요소의 width를 초과하여 가로 정렬이 되지 않았다.
이 현상을 회피하기 위해 부모 요소에 font-size:0; 을 선언하여 두 요소 사이에 정의하지 않은 공배글 제거한다.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
color: white;
text-align: center;
padding: 10px;
background-color: #def0c2;
/* 폰트 사이즈를 0으로 지정하여 두 요소 사이에 정의하지 않은 공백을 제거 */
font-size: 0;
}
.d1, .d2 {
display: inline-block;
width: 50%;
padding: 20px 0;
/* 폰트 사이즈를 재지정 */
font-size: 1rem;
}
.d1 {
background-color: #59b1f6;
}
.d2 {
background-color: #ffb5b4;
}
</style>
</head>
<body>
<div class="container">
<div class="d1">1</div>
<div class="d2">2</div>
</div>
<div style="background:red;padding:10px;color:white;">3</div>
</body>
</html>
상속이란 상위(부모, 조상) 요소에 적용된 속성을 하위(자식, 자손) 요소가 물려 받는 것을 의미한다. 상속 기능이 없다면 각 요소의 Rule set에 속성을 매번 각각 지정해야한다.
하지만 모든 속성이 상속되는 것은 아니다. 속성 중에는 상속이 되는 것과 되지 않는 것이 있다.
속성 | Inherit |
---|---|
width/height | no |
margin | no |
padding | no |
border | no |
box-sizing | no |
display | no |
visibility | yes |
opacity | yes |
background | no |
font | yes |
color | yes |
line-height | yes |
text-align | no |
text-decoration | no |
white-space | yes |
position | no |
top/right/bottom/left | no |
z-index | no |
overflow | no |
float | no |
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.text-red {
color: red;
border: 1px solid #bcbcbc;
padding: 10px;
}
</style>
</head>
<body>
<div class="text-red">
<h1>Heading</h1>
<p>Paragraph<strong>strong</strong></p>
<button>Button</button>
</div>
</body>
</html>
color는 상속되는 속성으로 자식 요소는 물론 자손 요소까지 적용된다. 하지만 button처럼 요소에 따라 상속 받지 않는 경우도 존재한다. border, padding은 상속되지 않는 요소로 하위 요소에 적용되지 않는다.
상속디지 않는 경우(상속디지 않은 요소 또는 상속되지 않는 속성, inherit 키워드를 사용하여 명시적으로 상속받게 할 수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.text-red {
color: red;
border: 1px solid #bcbcbc;
padding: 10px;
}
.text-red button {
color: inherit;
}
.text-red p {
border: inherit;
padding: inherit;
}
</style>
</head>
<body>
<div class="text-red">
<h1>Heading</h1>
<p>Paragraph<strong>strong</strong></p>
<button>Button</button>
</div>
</body>
</html>
요소는 하나 이상의 CSS 선언에 영향을 받을 수 있다. 이 때 충돌을 피하기 위해 CSS 적용 우선순위가 필요한데, 이를 캐스캐이딩(Cascading Order)이라고 한다.
캐스캐이딩에는 다음과 같은 세가지 규칙이 있다.
중요도
CSS가 어디에 선언 되었는지에 따라서 우선순위가 달라진다.
명시도
대상을 명확하게 특정할수록 명시도가 높아지고 우선순위가 높아진다.
선언순서
선언된 순서에 따라 우선 순위가 적용된다. 즉, 나중에 선언된 스타일이 우선 적용된다.
CSS가 어디에 선언되었는지에 따라서 우선순위가 달라진다.
css 파일
/* style.css */
body {
background-color: red;
color: white;
}
html 파일
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<style>
body {
background-color: beige;
color: navy;
}
</style>
</head>
<body>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</body>
</html>
대상을 명확하게 특정할수록 명시도가 높아지고 우선순위가 높아진다.
!important > 인라인 스타일 > 아이디 선택자 > 클래스/어트리뷰트/가상 선택자 > 태그 선택자 > 전체 선택자 > 상위 요소에 의해 상속된 속성
<!DOCTYPE html>
<html>
<head>
<style>
p { color: red !important; }
#thing { color: blue; }
div.food { color: chocolate; }
.food { color: green; }
div { color: orange; }
</style>
</head>
<body>
<p id="thing">Will be Red.</p>
<div class="food">Will be Chocolate.</div>
</body>
</html>
선언된 순서에 따라 우선 순위가 적용된다. 즉, 나중에 선언된 스타일이 우선 적용된다.
<!DOCTYPE html>
<html>
<head>
<style>
p { color: blue; }
p { color: red; }
.red { color: red; }
.blue { color: blue; }
</style>
</head>
<body>
<p>Will be RED.</p>
<p class="blue red">Will be BLUE.</p>
</body>
</html>
CSS 표준으로 확정되기 전, 또는 표준은 아니지만 특정 브라우저에만 지원되면 CSS 속성을 사용하기 위해서 제공되는 기능이다.
또는, CSS 표준에 대한 속성 구현이 특정 브라우저에서는 다르게 된 경우, 해당 브라우저를 위한 별도의 속성 값을 지정할 때도 사용할 수 있다.
CSS 호환성을 위해 전용의 CSS 속성을 부여할 수 있도록 웹 브라우저 제조사 별로 제공할 수 있도록 제공되는 표준 CSS 속성 기술 방법이다.
같은 CSS 속성을 브라우저 종류에 따라 다르게 적용되도록 별도의 접두어를 속성명 앞에 붙여서 해당 브라우저가 속성을 인식하고 사용하도록 할 수 있다.
.box{
display: -ms-grid;
display: grid;
-webkit-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
위와 같은 형태로 프리픽스를 사용해 웹킷(-webkit-)과 오페라(-o-) 브라우저를 위한 별도의 tannsition 속성을 추가 했다. 이에 벤더 프리픽스 "-webkit-"을 인식하는 브라우저는 앞서 정의된 "-webkit-transition" 속성이 적용되어 0.5초 동안 트랜지션이 적용된다.
단, CSS 속성은 속성이 오는 순서에 따라 순차적으로 적용되기 때문에 벤더 프리픽스가 붙은 속성과 표준 속성이 모두 있을 경우 나중에 나오는 속성이 적용됩니다.
위의 코드에서는 결국 "transition: all.5s;" 속성이 적용된다.
표준 속성의 적용을 우선해야 하기에, 벤더 프리픽스가 있는 속성은 표준 속성 앞쪽에 표시하는 것이 원칙이다.
웹 브라우저 시장의 경쟁이 구글 크롬 중심으로 정리가 되고, 주요 웹 브라우저들이 최신 CSS 표준을 빠르게 지원하면서 벤더 프리픽스는 점차 사용되지 않는 추세이며, 벤더 프리픽스를 사용할 필요성도 점차 줄어들고 있다.
브라우저 별 벤더 프리픽스는 다음과 같다.
브라우저 | Vender Prefix |
---|---|
IE or Edge | -ms- |
Chrome | -webkit- |
Firefox | -moz- |
Safari | -webkit- |
Opera | -o- |
iOS Safari | -webkit- |
Android Browser | -webkit- |
Chrome for Android | -webkit- |
텍스트에 그림자 효과를 부여하는 속성이다.
선택자 { text-shadow: Horizontal-offset Vertical-offset Blur-Radius Shadow-Color; }
속성값 | 단위 | 설명 | 생략 |
---|---|---|---|
Horizontal-offset | px | 그림자를 텍스트의 오른쪽으로 지정값만큼 이동시킨다. | |
Vertical-offset | px | 그림자를 텍스트의 아래로 지정값만큼 이동시킨다. | |
Blur-Radius | px | 그림자의 흐림정도를 지정한다. 지정값만큼 그림자가 커지고 흐려진다.(양수) | 가능 |
Shadow-Color | color | 그림자의 색상을 지정한다. | 가능 |
<!DOCTYPE html>
<html>
<head>
<style>
h1:nth-child(1) {
text-shadow: 5px 5px;
}
h1:nth-child(2) {
text-shadow: 5px 5px red;
}
h1:nth-child(3) {
text-shadow: 5px 5px 3px red;
}
h1:nth-child(4) {
color: white;
text-shadow: 5px 5px 3px black;
}
h1:nth-child(5) {
text-shadow: 0 0 3px red;
}
/*Multiple Shadows*/
h1:nth-child(6) {
text-shadow: 0 0 3px red, 0 0 10px blue;
}
/*Multiple Shadows*/
h1:nth-child(7) {
color: white;
text-shadow: 1px 1px 2px black, 0 0 25px blue, 0 0 5px darkblue;
}
</style>
</head>
<body>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
</body>
</html>
요소에 그림자 효과를 부여하는 속성이다.
선택자 { box-shadow: Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color; }
속성값 | 단위 | 설명 | 생략 |
---|---|---|---|
Inset | inset | inset 키워드를 지정하면 그림자가 요소 안쪽에 위치한다. | 가능 |
Horizontal-offset | px | 그림자를 텍스트의 오른쪽으로 지정값만큼 이동시킨다. | |
Vertical-offset | px | 그림자를 텍스트의 아래로 지정값만큼 이동시킨다. | |
Blur-Radius | px | 그림자의 흐림정도를 지정한다. 지정값만큼 그림자가 커지고 흐려진다.(양수) | 가능 |
Spread | px | 그림자를 더 크게 확장시킨다.(음수, 양수) | 가능 |
Shadow-Color | color | 그림자의 색상을 지정한다. | 가능 |
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 300px;
height: 100px;
padding: 15px;
margin: 20px;
background-color: yellow;
}
/*box-shadow: Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color;*/
/* Horizontal-offset Vertical-offset */
div:nth-of-type(1) {
box-shadow: 10px 10px;
}
/* Horizontal-offset Vertical-offset Shadow-Color */
div:nth-of-type(2) {
box-shadow: 10px 10px blue;
}
/* Horizontal-offset Vertical-offset Blur-Radius Shadow-Color */
div:nth-of-type(3) {
box-shadow: 10px 10px 5px blue;
}
/* Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
div:nth-of-type(4) {
box-shadow: 10px 10px 5px 5px blue;
}
/* Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
div:nth-of-type(5) {
box-shadow: inset 10px 10px 5px 5px blue;
}
/* Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
div:nth-of-type(6) {
background-color: white;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
</head>
<body>
<div>This is a div element with a box-shadow</div>
<div>This is a div element with a box-shadow</div>
<div>This is a div element with a box-shadow</div>
<div>This is a div element with a box-shadow</div>
<div>This is a div element with a box-shadow</div>
<div>This is a div element with a box-shadow</div>
</body>
</html>
그레이디언트(Gradient)는 2가지 이상의 색상을 혼합하여 부드러운 색감의 배경 등을 생성하는 것이다. CSS3가 이 기능을 제공하기 이전에는 포토샵 등의 소프트웨어를 사용하여 그레이디언트 효고를 이미지를 제작하여 사용하였다. 그러나 이러한 방법은 이미지 다운로드에 시간이 소요되는 문제와 이미지를 확대하였을 때 해상도가 나빠지는 문제 등을 내포하고 있었다.
그레이디언트는 2가지 종류가 있다.
그레이디언트는 CSS3가 비교적 최근부터 제공하는 기술로서 대부부분의 브라우저에 벤더프리픽스를 사용하여야 하고 브라우저에 따라 조금씩 문법이 상이하여 다루기가 수월하지 않다. 따라서 그레이디언트를 직접 작성하는 것 보다 작성 툴을 이용하는 것이 보편적이다.
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
div {
width: 100vw;
height: 100vh;
}
.dawn {
/* Old browsers */
background: #b3cae5;
/* FF3.6+ */
background: -moz-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
/* Chrome,Safari4+ */
background: -webkit-gradient(linear, left top, right bottom, color-stop(12%, #b3cae5), color-stop(46%, #dbdde4), color-stop(70%, #e4e3e4), color-stop(94%, #f7ddbb), color-stop(100%, #efcab2));
/* Chrome10+,Safari5.1+ */
background: -webkit-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
/* Opera 11.10+ */
background: -o-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
/* IE10+ */
background: -ms-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
/* W3C */
background: linear-gradient(135deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
}
</style>
</head>
<body>
<div class="dawn"></div>
</body>
</html>
트랜지션(transition)은 CSS 속성의 값이 변화할 때, 속성 값의 변화가 일정 시간(duration)에 걸쳐 일어나도록 하는 것이다. 예를 들어 코드에서는 div요소는 기본 상태에서 hover 상태로 변화할 때, CSS 속성 border-radius, background의 속성값이 변화한다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
}
div:hover {
border-radius: 50%;
background: blue;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
상대 변화에 따라 CSS 속성이 변경되면 속성 변경에 따른 변화(transition)은 즉시 발생된다.
트랜지션(transition)은 상태 변화에 동반하여 변경되는 CSS 속성 값에 의한 표시의 변화를 부드럽게 하기 위해 애니메이션 속도를 조절한다. 즉, 속성 값의 변경이 표시의 변화에 즉시 영향을 미치게 하는 대신 그 속성 값의 변화가 일정 시간(duration) 에 걸쳐 일어나도록 하는 것이다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
/* 트랜지션 효과: 모든 프로퍼티의 변화를 2초에 걸쳐 전환한다. */
transition: all 2s;
}
div:hover {
border-radius: 50%;
background: blue;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
위의 코드에서는 div 요소에 마우스가 올라갈 때(hover-on)와 마우스가 내려올 때(hover-off) 속성 값의 변화가 발생한다. 그리고 이는 2초에 걸쳐 일어난다.
div의 RoleSet에 트랜지션을 설정하면 hover-on, hover-off 모두 트랜지션이 발동한다. 하지만 div:hover RoleSet에 트랜지션을 설정하면 마우스가 올라갈 때(hover-on)는 트랜지션이 발동하나, 마우스가 내려갈 때(hover-off)는 트랜지션이 발동하지 않는다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
}
div:hover {
background: blue;
border-radius: 50%;
/* hover on에서만 발동한다. */
transition: all 2s;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
transition은 자동으로 발동되지 않는다. :hover와 같은 가상 클래스 선택자(Pseudo-Classes) 또는 JavaScript의 부수적인 액션에 의해 발동한다. 위 예제의 div 요소에 적용된 트랜지션은 이와 같은 부수적 액션없이는 어떤 효과도 볼 수 없다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
transition: all 2s;
}
.hover {
background: blue;
border-radius: 50%;
}
</style>
</head>
<body>
<div></div>
<script>
const elem = document.querySelector('div');
elem.addEventListener('mouseover', function () {
this.classList.add('hover');
});
elem.addEventListener('mouseleave', function () {
this.classList.remove('hover');
});
</script>
</body>
</html>
만일 트랜지션이 자동 발생(self-invoking transition)하도록 하고 싶다면 CSS 애니메이션을 사용하도록 한다.
transition의 속성은 아래와 같다.
속성 | 설명 | 기본값 |
---|---|---|
transition-property | 트랜지션의 대상이 되는 CSS 속성을 지정한다 | all |
transition-duration | 트랜지션이 일어나는 지속시간(duration)을 초 단위(s) 또는 밀리 초 단위(ms)로 지정한다 | 0s |
transition-timing-funtion | 트랜지션 효과를 위한 수치 함수를 지정한다. | ease |
trnastion-delay | 속성이 변화한 시점과 트랜지션이 실제로 시작하는 사이에 대기하는 시간을 초 단위, 밀리초단위로 지정한다. | 0s |
transition | 모든 트랜지션 속성을 한번에 지정한다. |
transition-property 속성은 트랜지션의 대상이 되는 CSS 속성명을 지정한다. 지정하지 않는 경우 모든 속성이 트랜지션의 대상이된다. 여러 개의 속성을 지정하는 경우 쉼표(,)로 구분한다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 50px;
background-color: red;
margin-bottom: 10px;
transition-property: width, background-color;
transition-duration: 2s, 2s;
}
div:hover {
width: 300px;
background-color: blue;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
주의할 점은 모든 CSS 속성이 트랜지션의 대상이 될 수 없다는 점이다. 예를 들어 width, font-size, background-color 등은 하나의 범주(width, font-size는 크기, background-color는 색상)안에서 값이 변화하지만 display 속성은 그렇지 않다.
속성의 대상이 될 수 있는 CSS 속성은 다음과 같다.
// Box model
width height max-width max-height min-width min-height
padding margin
border-color border-width border-spacing
// Background
background-color background-position
// 좌표
top left right bottom
// 텍스트
color font-size font-weight letter-spacing line-height
text-indent text-shadow vertical-align word-spacing
// 기타
opacity outline-color outline-offset outline-width
visibility z-index
또한 요소의 속성값이 변화하면 브라우저는 속성 값의 변화에 영향을 받는 모든 요소의 위치와 크기값을 계산하여 layout 작업을 수행한다. 이것은 브라우저에게 스트레스를 주어 성능 저하의 요인이 된다. 심지어 다수의 자식 요소를 가지고 있는 요소(예를 들어 body 요소)가 변경되면 모든 자식 요소의 기하값이 재계산될 수도 있다. 따라서 layout에 영향을 주는 트랜지션 효과는 회피하도록 노력해야한다.
layout에 영향을 주는 속성은 다음과 같다.
width height padding margin border
display position float overflow
top left right bottom
font-size font-family font-weight
text-align vertical-align line-height
clear white-space
transition-duration 속성은 트랜지션에 일어나는 지속시간(duration)을 초 단위(s), 밀리 초 단위(ms)로 지정한다. 속성값을 지정하지 않을 경우 기본값 0s이 적용되어 어떠한 트랜지션 효과도 볼 수 없다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 50px;
padding: 10px;
color: white;
background-color: red;
margin-bottom: 10px;
transition-property: width, opacity;
}
div:nth-child(1) {
transition-duration: 0.5s;
}
div:nth-child(2) {
transition-duration: 2s, 1s;
}
div:nth-child(3) {
transition-duration: 5s, 2.5s;
}
div:hover {
width: 300px;
opacity: .1;
}
</style>
</head>
<body>
<div>0.5s</div>
<div>2s, 1s</div>
<div>5s, 2.5s</div>
</body>
</html>
transition-duration 속성값은 transition-property 속성값과 1:1 대응한다. 아래의 경우, width 속성은 2초의 지속시간을 갖는다.
div {
transition-property: width;
transition-duration: 2s;
}
아래의 경우, width 속성은 2초, opacity 속성은 4초의 지속시간을 갖는다.
div {
transition-property: width, opacity;
transition-duration: 2s, 4s;
}
또한 transition 속성만으로 축약 표현이 가능하다.
div {
/* shorthand syntax */
transition: width 2s, opacity 4s;
}
아래의 경우, width 속성은 2초, opacity 속성은 1초. left 2초, top 1초의 지속시간을 갖는다.
div {
transition-property: width, opacity, left, top;
transition-duration: 2s, 1s;
}
트랜지션 효과의 변화 흐름, 시간에 따른 변화 속도와 같은 일종의 변화의 리듬을 지정한다.
transition-timing-function 속성값으로 미리 정해둔 5개의 키워드가 제공된다. 디폴트는 ease이다.
속성값 | 효과 |
---|---|
ease | 기본값, 느리게 시작하여 점점 빨라졌다가 느려지면서 종료한다. |
linear | 시작부터 종료까지 등속 운동을 한다. |
ease-in | 느리게 시작한 후 일정한 속도에 다다르면 그 상태로 등속 운동한다. |
ease-out | 일정한 속도의 등속으로 시작해서 점점 느려지면서 종료한다. |
ease-in-out | ease와 비슷하게 느리게 시작하여 느려지면서 종료한다. |
<!DOCTYPE html>
<html>
<head>
<style>
div {
font: bold 16px/50px "Open Sans";
color: white;
text-align: center;
width: 100px;
height: 50px;
background-color: red;
margin-bottom: 10px;
transition: width 2s;
}
div:nth-child(1) {
transition-timing-function: ease;
}
div:nth-child(2) {
transition-timing-function: linear;
}
div:nth-child(3) {
transition-timing-function: ease-in;
}
div:nth-child(4) {
transition-timing-function: ease-out;
}
div:nth-child(5) {
transition-timing-function: ease-in-out;
}
div:hover {
width: 300px;
}
</style>
</head>
<body>
<h3>transition-timing-function</h3>
<div>ease</div>
<div>linear</div>
<div>ease-in</div>
<div>ease-out</div>
<div>ease-in-out</div>
</body>
</html>
속성이 변화한 시점과 트랜지션이 실제로 시작하는 사이에 대기하는 시간을 초 단위(s), 밀리 초 단위(ms)로 지정한다. 즉, transtion-delay로 대기 시간을 지정하여 속성의 값이 변화하여도 즉시 트랜지션이 실행되지 않고, 일정 시간 대기한 후 트랜지션이 실행되도록 한다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
font: bold 16px/50px "Open Sans";
color: white;
text-align: center;
width: 100px;
height: 50px;
background-color: red;
margin-bottom: 10px;
transition: width 1s;
}
div:nth-of-type(1) {
transition-delay: 0s;
}
div:nth-of-type(2) {
transition-delay: 1s;
}
div:nth-of-type(3) {
transition-delay: 3s;
}
div:hover {
width: 300px;
}
</style>
</head>
<body>
<h3>transition-delay</h3>
<div>0s</div>
<div>1s</div>
<div>3s</div>
</body>
</html>
모든 트랜지션 속성을 한번에 지정할 수 있는 shorthand 이다. 값을 지정하지 않은 속성에는 기본값이 지정된다.
transition: property duration function delay
transition-duration은 반드시 지정해야한다. 지정하지 않는 경우 기본값 0으로 설정되어 어떠한 트랜지션도 실행되지 않는다. transition의 기본값은 아래와 같다
all 0 ease 0
<!DOCTYPE html>
<html>
<head>
<style>
div {
font: bold 0.5em/50px "Open Sans";
color: white;
text-align: center;
width: 100px;
height: 50px;
margin-bottom: 10px;
background-color: red;
}
div:nth-of-type(1) {
/* property duration function delay */
transition: width 1s ease-in 1s;
}
div:nth-of-type(2) {
/* duration */
transition: 1s
}
div:nth-of-type(3) {
/* property duration */
transition: width 1s
}
div:nth-of-type(4) {
/* duration function */
transition: 1s ease-in;
}
div:nth-of-type(5) {
/* duration delay*/
transition: 1s 1s;
}
div:hover {
width: 300px;
}
</style>
</head>
<body>
<div>width 1s ease-in 1s</div>
<div>1s</div>
<div>width 1s</div>
<div>1s ease-in</div>
<div>1s 1s</div>
</body>
</html>