DevelUP 퀘스트1 - 반응형 웹
Project/DevelUP

DevelUP 퀘스트1 - 반응형 웹

뉴비뉴 2019. 10. 21.

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%;
}

introduce . . . 등의 간격이 떨어진 것을 확인할 수 있다.

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: top; 하기 전 사진
vertical-align: top; 적용 후의 사진

위 사진들을 비교해보면 알겠지만 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>

MAP(0px), Bus(-30px), Weather(-60px), Contact(-90px)

풀어서 설명해보면 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를 이용하여 테두리를 지정해주는 것이다. 추후에 테두리는 제거해줘야한다.

댓글

💲 추천 글