https://www.youtube.com/watch?v=KYo62fhaR7M
반응형 자기소개 웹사이트 따라 만들기 | 티티하우스 | 빔캠프
# 스피드코딩 미리보기 https://www.youtube.com/watch?v=RbYrzl8uLs0 # 본 예제 보기 및 다운로드는? http://t.veam.me/aboutme/ 🚩 오프라인 강의는? https://veamcamp.com
www.youtube.com
.portrait
padding-top: 100%; 여기의 % 의 기준은 portrait 의 부모의 너비 기준으로 크기를 잡는다.
하지만 사람들이 많이 쓰는 비율 16:9로 만들어보고 싶다.
이럴 땐 9/16을 하면 0.5625 라는 값이 나오는데 이것을 %로 변경해주면 56.25%가 된다.
padding-top: 56.25%;
하지만 내가 지정한 사진의 크기가 너무 크기 때문에 화면에 표시되는 사진이 짤려서 보여지게된다.
이럴 땐 background-size: cover; 로 해주면 이미지의 비율이 그대로 유지되면서 자신의 너비 기준으로 또는 높이 기준으로 적절하게 사이즈를 조절해준다.
추가로 위치가 마음에 안든다면 background-position: center; 로 잡아주면 된다.
이렇게 설정하게 되면 웹 사이트를 크기조절하는거에 맞춰 사진의 크기가 늘었다가 줄었다가를 반복한다.
body {
margin: 0;
}
body {
background-color: #111;
color: #999;
}
.portrait {
background-image: url("/static/images/profile.png");
background-size: cover;
background-position: center;
padding-top: 56.25%;
}
.profile
profile div 태그 안에 몇 개의 덩어리를 만들지 먼저 생각해보아야 한다.
나는 송추에 대한 소개 페이지를 만들기로 하였고, 필요 정보들을 API로도 받아야 한다.
- 송추를 소개하는 단락(지도까지)
- 교통(버스정보API)
- 날씨(날씨정보API)
- 댓글기능
- contact
우선 위와 같이 정리하였고, 5개의 div 를 생성하도록 하겠습니다.
5개의 무수히 많은 마크업들을 당장 하는 것은 좋은 방법이 아니다.
최대한 전체적인 마크업을 작성하고, css를 같이 들어가는 것이 좋고, 전체적인 큰 간격들을 먼저 잡아주는것이 좋다.
div 간의 간격
간격들부터 잡아보도록 하겠습니다.
index.html
<div class="portrait"> {# 배경사진 #}
</div>
<div class="sc"> {# sc는 songchu의 줄임 #}
<div class="sc-introduce">introduce</div>
<div class="sc-section">bus</div>
<div class="sc-section">weather</div>
<div class="sc-section">reply</div>
<div class="sc-section">contact</div>
</div>
style.css
.sc {
padding: 7%; /* padding 7% 는 top, right, bottom, left 전부를 7%로 */
}
.sc-introduce,
.sc-section { /* introduce안의 section의 bottom padding을 전부 설정해주도록 하자*/
padding-bottom: 7%;
}

class 이름 지정
다음 해야 할 일은 대충 들어갈 값들을 넣어보고, class 이름을 지정해주는 것이다.
index.html
<div class="portrait"></div>
{# 배경사진 #}
<div class="sc"> {# sc는 songchu의 줄임 #}
<div class="sc-introduce">
<div class="header">
<div class="introduce">
I'm a
<ul class="introduce-function">
<li>MAP</li>
<li>Bus</li>
<li>Weather</li>
<li>Contact</li>
</ul>
<h1 class="introduce-title">Introducing Songchu</h1></div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Reiciendis accusamus impedit quam ratione illo quod,
ipsum dolore dolor laboriosam voluptas sunt nostrum,
facilis natus. Pariatur optio, harum vel ipsa delectus.</p>
</div>
<div class="sc-section">bus</div>
<div class="sc-section">weather</div>
<div class="sc-section">reply</div>
<div class="sc-section">contact
<div class="icons">
<a class="instagram" href="">Instagram</a>
<a class="github" href="">Github</a>
<a class="blog" href="">Blog</a>
</div>
</div>
</div>
기본 스타일 초기화
그 다음에는 브라우저가 기본으로 제공하는 스타일을 없애야 한다.
최초에 body에 대한 margin을 제거한 것 처럼 나머지 태그들의 스타일들을 없앨 필요가 있다.
이러한 초기화를 초기에 하지 않게되면 내가 작성하지 않은 스타일 때문에 나중에 뒤통수를 맞게되는 일이 생긴다.
style.css
body, h1, p, ul {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
h1 {
font-size: 100%; /* 원래 사이즈대로 가겠다.*/
font-weight: normal;
}
a {
color: inherit; /* 부모의 폰트 사이즈를 상속받게끔*/
text-decoration: none; /* a 태그의 밑줄 삭제*/
}
body {
background-color: #111;
color: #999;
}
[?] vertical-align: top 이란?
style.css
.introduce-function {
display: inline-block;
background-color: red;
/*vertical-align: top; !* .name-function 의 inline-block 의 시작점을 맞춰준다? 사진*!*/
}
index.html
<ul class="introduce-function">
<li>MAP</li>
<li>Bus</li>
<li>Weather</li>
<li>Contact</li>
</ul>


위 사진들을 비교해보면 알겠지만 vertical-align을 적용하기 전에는 I'm a 가 맨 아래 붙었다면 top 을 적용하였을 때는 맨 위에 붙어있는 것을 확인할 수 있다.
style.css
.introduce {
font-size: 30px;
}
.introduce-function {
display: inline-block;
background-color: red;
vertical-align: top; /* .introduce-function 의 inline-block 의 시작점을 맞춰준다? 사진*/
}
.introduce-title {
font-size: 1.5em; /* .introduce-title의 부모는 .introduce 이다.*/
/* 자신의 부모 폰트사이즈 30px의 1.5배가 되게끔 해라! 자신의 부모 폰트사이즈가 변경되면 같이 변경된다.*/
}
introduce-function을 움직일 수 있게끔
style.css
.introduce {
font-size: 30px;
line-height: 1; /*한 줄의 높이를 의미하는 것이다. 그럼 폰트사이즈 30이 line-height가 의미하는 것은 30이 된다.*/
}
.introduce-function {
display: inline-block;
background-color: red;
vertical-align: top; /* .introduce-function 의 inline-block 의 시작점을 맞춰준다? 사진*/
height: 30px; /* 30px 로 높이를 제한해둔 상태에서 */
overflow: hidden; /* overflow: 넘쳐흐르는 것을 잘라주겠다. */
}
.introduce-function-list { /* 움직임이 생기는 부분 */
margin-top: -30px;
/* 0 30 60 90 단위로 .introduce-function-list의 있는 값들이 하나씩 나오게된다. */
}
[!] vertical-align 속성은
- inline이나 inline-block 요소에만 적용 됨, 따라서 block 요소인 <div> 는 이 속성을 썼을 때 작동되지 않음
- 요소 자체만을 정렬하고, 내용에는 영향을 미치지 않음 (table cell에 적용할 때는 제외)
- table cell 에 적용할 때는 내용에 영향을 미침
- vertical-align은 정렬하려는 요소를 다른 인라인 요소에 상대적으로 정렬함
그래서 같은 줄에서 인라인 요소의 크기에 따라 높낮이가 달라질 수 있고,
그 줄에 있는 line-height 설정에 따라서도 달라질 수 있음
[!] overflow 속성은 요소의 박스에 내용이 더 길 때 어떻게 보일지 선택하는 속성입니다.
- visible: 기본값으로 내용이 더 길어도 그대로 보인다.(내용이 흘러넘친다.)
- hidden: 내용이 넘치면 자른다. 자른 부분은 보이지 않습니다.
- scroll: 내용이 넘치지 않아도 항상 스크롤바가 보입니다.
- auto: 내용이 잘릴 대만 스크롤바가 보입니다.
index.html
해당 작업을 수행하기 위해 div를 하나 더 추가해준다.
<div class="introduce-function">
<ul class="introduce-function-list">
<li>MAP</li>
<li>Bus</li>
<li>Weather</li>
<li>Contact</li>
</ul>
</div>
<h1 class="introduce-title">Introducing Songchu</h1></div>
</div>

풀어서 설명해보면 style.css 의 line-height: 1; 로 한 줄을 30px 로 선언하고,
.introduce-funtion 의 height 를 30px로 조절한 뒤 overflow: hidden; 속성으로 30px; 위에 나오는 값들은 hidden으로 숨긴다.
.introduce-function-list 로 보여지는 값을 지정한다. 사진 설명 참고
하지만 부모(introduce)의 폰트사이즈가 변경되면 introduce-function의 height의 값이 30px로 되어있기 때문에 문제가 발생하게 된다. 이럴 땐 introduce-function 안에 있는 height의 값을 30px 에서 1em 으로 변경해주면 된다.
.introduce {
font-size: 30px;
line-height: 1.5; /*한 줄의 높이를 의미하는 것이다. 그럼 폰트사이즈 30이 line-height가 의미하는 것은 30이 된다.*/
font-style: italic; /* 폰트지정 */
}
.introduce-function {
display: inline-block;
background-color: red;
vertical-align: top; /* .introduce-function 의 inline-block 의 시작점을 맞춰준다? 사진*/
height: 1.5em; /* introduce의 font-size *1 을 해서 값을 가져온다. 결국 부모의 값과 같은 값이 들어온다.*/
overflow: hidden; /* overflow: 넘쳐흐르는 것을 잘라주겠다. */
padding-right: 0.5em; /* 폰트지정 후 오른쪽 공간이 짤려서 추가적으로 늘려주었다. */
}
.introduce-function-list { /* 움직임이 생기는 부분 */
margin-top: -1.5em; /* 부모의 기준 폰트가 수정되면 같이 수정된다.*/
/* 0 30 60 90 단위로 .introduce-function-list의 있는 값들이 하나씩 나오게된다. */
}
.introduce-title {
font-size: 1.5em; /* .introduce-title의 부모는 .introduce 이다.*/
line-height: 1;
/* 자신의 부모 폰트사이즈 30px의 1.5배가 되게끔 해라! 자신의 부모 폰트사이즈가 변경되면 같이 변경된다.*/
}
우리가 생각하는 최종목표는 .introduce-function-list의 margin-top 이 애니메이션으로 값이 변경되면서 우리가 지정한 li의 값들이 자동으로 변경되게끔 설정하는 것이다.
완벽한 이해를 위해선 line-height 와 em 그리고 inline-block의 정의를 한번 다시 짚어보고 갈 필요가 있다.
자동으로 애니메이션 기능
/* Animation */
@keyframes rolling { /* 익스플로러에서는 지원하지 않는다.*/
0% {
margin-top: 0;
}
25%{
margin-top: -1.5em;
}
50%{
margin-top: -3em;
}
75%{
margin-top: -4.5em;
}
100% {
margin-top: -6em; /* 0 ~ -1.5 로 애니메이션 되게 할 수 있다.*/
}
}
.introduce-function-list { /* 움직임이 생기는 부분 */
animation-name: rolling; /* 위에서 선언한 rolling을 가져온다. */
animation-duration: 3s; /* 초 단위 */
animation-iteration-count: infinite;/* 수동으로 새로고침하지않고 자동으로 값이 변경되게하기 위해선 infinite 평생실행 */
}
index.html
<div class="introduce-function">
<ul class="introduce-function-list">
<li>Contact</li> // 추가해서 간단하게 사용할 수 있게
<li>MAP</li>
<li>Bus</li>
<li>Weather</li>
<li>Contact</li>
</ul>
</div>

/* Animation */
@keyframes rolling { /* 익스플로러에서는 지원하지 않는다.*/
0% {
margin-top: 0;
}
25%{
margin-top: -1.5em;
}
50%{
margin-top: -3em;
}
75%{
margin-top: -4.5em;
}
100% {
margin-top: -6em; /* 0 ~ -1.5 로 애니메이션 되게 할 수 있다.*/
}
}
.introduce-function-list { /* 움직임이 생기는 부분 */
animation-name: rolling; /* 위에서 선언한 rolling을 가져온다. */
animation-duration: 3s; /* 초 단위 */
animation-iteration-count: infinite;/* 수동으로 새로고침하지않고 자동으로 값이 변경되게하기 위해선 infinite 평생실행 */
}
Transform
하지만 위와 같은 코드에서 margin을 사용하는 것보다 Transform을 사용하는 것이 더 효율적이다.
/* Animation */
@keyframes rolling { /* 익스플로러에서는 지원하지 않는다.*/
0% {
transform: translateY(0); /* 자기 자신의 너비 또는 높이 기준에서의 % 를 가져올 수 있다.*/
/* Y를 해주었기 때문에 자기 높이 기준의 ~%를 올린다 이런식으로 생각하면 된다.*/
}
25%{
transform: translateY(-20%);
}
50%{
transform: translateY(-40%);
}
75%{
transform: translateY(-60%);
}
100% {
transform: translateY(-80%);
}
}
애니메이션 동작을 위에서 아래로 내려가는 것을 동작하고자 할 떄는 animation-direction: reverse; 로 해주면 된다.
추가적으로 duration 시간을 10초로 늘려서 좀 더 내려가는 것이 잘 보이도록 수정하였습니다.
.introduce-function-list { /* 움직임이 생기는 부분 */
animation-name: rolling; /* 위에서 선언한 rolling을 가져온다. */
animation-duration: 10s; /* 초 단위 */
animation-iteration-count: infinite;/* 수동으로 새로고침하지않고 자동으로 값이 변경되게하기 위해선 infinite 평생실행 */
animation-direction: reverse;/* 위에서부터 아래로 내려가는 것을 동작하고자 할 때 */
}
경계면이 안보이게 부드럽게 처리

.introduce-function {
display: inline-block;
color: white;
vertical-align: top; /* .introduce-function 의 inline-block 의 시작점을 맞춰준다? 사진*/
height: 1.5em; /* introduce의 font-size *1 을 해서 값을 가져온다. 결국 부모의 값과 같은 값이 들어온다.*/
overflow: hidden; /* overflow: 넘쳐흐르는 것을 잘라주겠다. */
padding-right: 0.5em;
position: relative; /* 해당 태그의 위치를 살짝 변경하고 싶을 때 position: relative */
}
.introduce-function::after { /* ::after 가상요소를 css 단에서 추가할 수 있다. 자식으로 생성된다.*/
content: ' ';
position: absolute; /* after 자식이 부모의 크기만큼 덮을 수 있게 크기를 조절해준다. */
left: 0;
top: 0;
right: 0;
bottom: 0;
/* 왼쪽과 오른쪽은 부드럽게 표시할 필요가 없으므로 -1em 으로 영향을 끼치지않게 설정해준다.*/
/*border: 1px solid red; !* 테두리를 생성함으로써 자식이 부모를 덮고있는 범위를 확인가능 *!*/
margin-left: -1em;
margin-right: -1em;
box-shadow: inset 0 0 10px 10px #111;
}

.introduce-function을 덮을 ::after 를 만들어주고, 부모의 크기만큼 크기를 설정해준 뒤 box-shadow를 이용하여 테두리를 지정해주는 것이다. 추후에 테두리는 제거해줘야한다.
'Project > DevelUP' 카테고리의 다른 글
| DevelUP 퀘스트1 - 반응형 웹(Disqus, Naver Map, 레이아웃 반응형) (0) | 2019.10.24 |
|---|---|
| DevelUP 퀘스트1 - 반응형 웹(icons) (0) | 2019.10.22 |
| DevelUP 퀘스트1 - 구성 (0) | 2019.10.21 |
댓글