9. Feature 구조-video
이 아래구조를 만들껀데.. 보면 만들어둔 inner와 길이가 안맞는 것을 알 수 있다. 그래서 크게 글, 동영상, 그림들 이렇게 3개로 구조를 나눈 후에, 설계하면 될 것 같다.
또한 화면이 줄어들었을때도 동영상크기도 줄어들고, 그림도 2줄씩 나오는걸로 변경되는게 보이는데 이 또한 직접 해주어야 한다!
<section class="section section--feature">
<div class="summary">
<div class="summary__title">
Welcome home, developers
</div>
<div class="summary__description">
GitHub fosters a fast, flexible, and collaborative development process that lets you work on your own or with others.
</div>
</div>
<div class="video">
<div class="video-ratio"> <!--비디오를 반응형으로 만들기 위함-->
<iframe width="1280" height="720" src="https://www.youtube.com/embed/afvT1c1ii0c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<div class="tiles">
</div>
</section>
다음과 같이 우선 video의 구조를 잡은 후에, 비디오를 16:9의 비율로 맞춰서 출력하고자 한다.
비디오를 16:9로 맞추는 스킬은 아래에서 확인해 보자.
See the Pen Untitled by supersfel (@supersfel) on CodePen.
위처럼 position과 padding을 잘 이용하면 비율을 일정하게 맞출 수 있다.
이를 실제 코드에 적용해보면,
/* FEATURE */
.section--feature{
background : #f5f5f5;
padding-top: 66px;
}
.section--feature .summary{
max-width : 820px; /*820이하에선 유동적으로*/
text-align : center;
margin : 0 auto;
}
.section--feature .video{
max-width : 650px;
margin : 50px auto; /*가운데 정렬 + 정렬*/
}
.section--feature .video .video-ratio{
height : 0;
padding-top : 56.25%;
position : relative;
}
.section--feature .video .video-ratio iframe{
position : absolute;
top : 10px;
left : 0;
width : 100%;
height: 100%;
}
위와 같다.
10. Feature 구조-Tiles
이미지도 반응형으로 만들것을 고려해서 구조를 만들면 다음과 같다.
<div class="tiles">
<div class="inner">
<ul>
<li>
<img src="img/feature-tile__build.png" alt="build">
<h3>For everything you build</h3>
<p>Host and manage your code on GitHub. You can keep your work private or share it with the world.</p>
</li>
<li>
<img src="img/feature-tile__work.png" alt="work">
<h3>A better way to work</h3>
<p>From hobbyists to professionals, GitHub helps developers simplify the way they build software.</p>
</li>
<li>
<img src="img/feature-tile__projects.png" alt="projects">
<h3>Millions of projects</h3>
<p>GitHub is home to millions of open source projects. Try one out or get inspired to create your own.</p>
</li>
<li>
<img src="img/feature-tile__platform.png" alt="platform">
<h3>One platform, from start to finish</h3>
<p>With hundreds of integrations, GitHub is flexible enough to be at the center of your development process.</p>
</li>
</ul>
</div>
</div>
우선, 이미지를 반응형으로 설정하기 위한 스킬을 보겠다.
See the Pen 반응형img by supersfel (@supersfel) on CodePen.
위처럼 padding을 사용하여 넘치지 않게 반응형 img를 설정할 수 있다.
/* FEATURE */
.section--feature{
background : #f5f5f5;
padding-top: 66px;
}
.section--feature .summary{
max-width : 820px; /*820이하에선 유동적으로*/
text-align : center;
margin : 0 auto;
}
.section--feature .video{
max-width : 650px;
margin : 50px auto; /*가운데 정렬 + 정렬*/
}
.section--feature .video .video-ratio{
height : 0;
padding-top : 56.25%;
position : relative;
}
.section--feature .video .video-ratio iframe{
position : absolute;
top : 10px;
left : 0;
width : 100%;
height: 100%;
}
.section--feature .tiles{
border-top : 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
}
.section--feature .tiles .inner{ /*덮어쓰기로 크기증가*/
max-width: 1200px;
}
.section--feature .tiles ul{
display : grid; /*4개그리드 사용*/
grid-template-columns: repeat(4,1fr);
}
.section--feature .tiles li{
padding : 34px 24px;
text-align : center;
line-height : 1.5;
border-right : 1px solid #e5e5e5;
box-sizing: border-box;
/*float : left;
width : 25%; 그리드는 구형 브라우저 지원 x > float사용
ul태그에 clearfix사용*/
}
.section--feature .tiles li:last-child{
border-right: none;
}
.section--feature .tiles li img{
max-width : 100%;
padding : 14px 10% 24px;
box-sizing: border-box;
}
.section--feature .tiles li h3{
font-size : 18px;
font-weight : 500;
margin-bottom : 10px;
}
.section--feature .tiles li p{
font-size : 14px;
color : #767676;
}
그 이후 위처럼 margin,fontsize등은 설정해주면 되는데,
위가 아닌, 가로로 나와야 하기때문에 그리드를 사용하였다. 구형 브라우저에서는 그리드가 지원되지 않기 때문에 주석처리된 부분인 float을 사용해도 괜찮다. 단, clearfix를 꼭 ul태그에 넣어줘야 한다.
동영상과 4개의 사진및 설명이 잘 들어간 모습이다.
11. where is 구역
위 부분을 구현하기 위해선 지도API를 통하여 구현해야한다. 지도 공유하기를 써도 삽입은 되지만, 권장하는 방법은 아니고 개발자 등록을 한 후에 지도 API를 사용하면 된다.
이번에는 public한 api key를 사용하겠다.
예전에 프로젝트 진행하다가 날씨 api를 사용한 적이 있는데 그것과 비슷한 것 같다.
우선 위에서 했던것과 동일하게 구조를 만들어준다.
<!-- Where is -->
<section class="section section--where-is">
<div class="inner">
<div class="summary">
<div class="summary__title">
Where is GitHub?
</div>
<div class="summary__description">
GitHub is where people build software. More than 18 million people use GitHub to discover, fork, and contribute to over 48 million projects.
</div>
</div>
<div id="map"></div>
</div>
</section>
그 후, css를 맞게 설정해주는데, 글자들은 위에서 설정을 했기에 안설정해주어도 된다
즉, 지도가 들어갈 #map부분위주만 영역표시를 해주면 된다.
* WHERE IS */
.section--where-is{
}
.section--where-is .inner{
padding-top : 80px;
}
#map{
width : 100%;
height: 400px;
margin-top: 40px;
border:1px solid rgba(0,0,0,.2);
border-bottom: none;
box-shadow : 0 0 20px rgba(0,0,0,.2);
box-sizing: border-box;
}
그 다음 실제로 지도가 들어오는 api를 설정해주어야 하는데 아래 자바스크립트 코드를 맨 마지막 자바스크립트 코드 바로 위에 넣어야 한다. 그래야 html파일을 다 읽은다음에 코드가 실행이 되고 오류가 나지 않는다.
<!--지도설정 스크립-->
<script>
function initMap(){
const myLatLng = {
lat : 37.782293,
lng : -122.391240
}
const map = new google.maps.Map(
document.getElementById('map'),
{
center : myLatLng,
scrollwheel : false,
zoom : 18
}
);
const marker = new google.maps.Marker({
position : myLatLng,
map : map,
title : 'GitHub'
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCTQIlxBn5AfKGvsfJiormAE1esN3fcCkg&callback=initMap" async defer></script>
12.Pricing 구역
만드는건 위에서 계속 했던거와 다르지않다. 우선 구조를 만들고
<!-- Pricing card -->
<section class="section section--pricing">
<div class="inner">
<div class="card">
<div class="cell cell1">
<a href="#" class ="btn btn--primary">Sign up for GitHub</a>
</div>
<div class="cell cell2">
Public projects are always free. Work together across unlimited private repositories for $7 / month.
</div>
</div>
</div>
</section>
이번에는 크게 다루는것 없이 꾸미기만 잘 해주면 된다.
/*PRICING CARD*/
.section--pricing{
background : linear-gradient(#f5f5f5,#fff)
}
.section--pricing .inner{
padding : 80px 0;
}
.section--pricing .card{
display : flex;
border : 1px solid #e5e5e5;
border-radius: 6px;
box-sizing: border-box;
}
.section--pricing .card .cell{
padding : 24px;
display :flex;
justify-content: center;
align-items: center;
}
.section--pricing .card .cell1 .btn{
height : 50px;
font-size : 16px;
}
.section--pricing .card .cell2{
font-size : 22px;
font-weight : 300;
line-height: 1.5;
flex : 1; /*visual부분에서 사용했던 방법*/
border-left : 1px solid #e5e5e5;
}
13.footer
화면의 맨 마지막을 만드는 footer이다 이 역시 중앙에 몰려져있는 inner을 사용하는데 크게 3가지 영역이 나누어져 있는 것을 알 수 있다. 그대로 만들 수도있지만,
크기를 줄여서 보면 header를 만들때와 비슷하게 위에서 아래의 순서와는 좀 다른 것을 알 수있다. 이역시 위에서 쌓이는 구조로 먼저 만들고, 순서를 css로 바꿔버리는것이 더 용이하단 것만 참고하고 만들면 될 것 같다.
<!-- FOOTER-->
<footer class = "section">
<div class="inner clearfix">
<ul class="site-links float--right">
<li><a href="#">Contact GitHub</a></li>
<li><a href="#">API</a></li>
<li><a href="#">Training</a></li>
<li><a href="#">Shop</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">About</a></li>
</ul>
<ul class="site-links float--left">
<li>© 2016 GitHub, Inc.</li> <!--링크연결 x-->
<li><a href="#">Terms</a></li>
<li><a href="#">Privacy</a></li>
<li><a href="#">Security</a></li>
<li><a href="#">Status</a></li>
<li><a href="#">Help</a></li>
</ul>
<a href="#" class="logo"> <!-- 코드를 이용하여 넣음 css로 색제어가능-->
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="24"
height="24"
viewBox="0 0 16 16"
fill="#ccc">
<path fill-rule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">
</path>
</svg>
</a>
</div>
</footer>
/*FOOTER */
footer{
}
footer .inner{
padding : 50px 0;
border-top : 1px solid #eee;
}
footer .site-links{
display : flex;
}
footer .site-links li{
font-size : 12px;
margin-right : 10px;
color : #767676;
}
footer .site-links li a{
color : #4078c0;
}
footer .site-links li a:hover{
text-decoration: underline;
}
footer .logo{
position : absolute;
top : 0;
bottom : 0;
left : 0;
right : 0; /*전체영역 사용*/
margin : auto;
width : 24px;
height : 24px; /*완벽히 가운데 배치를 하는 코드*/
}
footer .logo:hover svg{
fill : #4078c0; /*svg색을 채우겠다 */
}
footer도 위 과정과 거의 유사하고, 단 중간에 완벽히 가운데로 배치를 하는 footer .log부분만 조금 유심히 봐두면 될 것 같다.
14.미디어쿼리
현재 만든 페이지는 다음과같이 뷰포인트가 줄어들때 변하지 않는다. 작아지면 메뉴바도 만들고 하는 반응형 웹사이트를 만들어 볼 것이다.
이걸 알기위해서 우선 미디어쿼리에 대한 개념을 알아야 한다.
@media
다양한 미디어 유형이나 장치에 따라 서로다른 스타일 규칙을 적용
@media 미디어타입 and (미디어특성){
CSS코드
}
@media screen and(max-width : 1200px){
body {
color : red;
}
}
>>일종의 조건문처럼 사용 가능
all 모든 미디어 타입에 적용
screen 컴퓨터화면,탑르렛,스마트폰 등
print 인쇄 전용
미디어 특성
width 뷰포트 가로너비
max-width 뷰포트 최대 가로너비(이하)
min-width 뷰포트 최소 가로너비(이상)
height 뷰포트 세로너비
max-height 뷰포트 최대 세로 너비
min-height 뷰포트 최소 세로 너비
orientation 뷰포트방향(portrait,landscape)
>핸드폰이 옆으로 늬였을때랑 안늬였을때
See the Pen mideaqurry by supersfel (@supersfel) on CodePen.
위는 코드펜으로 한번 작성해본 미디어쿼리 예시이다. 뷰포인트를 변함에 따라 특성이 달라지게할 수 있다.
https://getbootstrap.com/docs/5.1/layout/grid/
위 페이지에서 각 기기마다 사이즈의 일반적인 특성을 확인해 볼 수 있다.
예를들어 xl < 모바일정도 이런식으로 확인하면 된다.
15.토글 버튼
사이트를 보면 크기가 줄어들 때
햄버거 모양의 토글버튼이 생기고, 위의 메뉴들이 저 안으로 쏙 들어간 부분을 알 수 있다.
그러기 위해서 우선 크기가 줄어들었을때 토글버튼이 눌리기전엔 안보이게 저 메뉴들을 숨길 필요가 있다. menu-group과 sign-group을 숨기기 위해 과정을 진행할 것임으로 HTML에서 두 클래스에 toggle클래스를 추가해서 숨기는 과정을 진행할 것이다.
또한, inner부분도 뷰포트가 최대가 정해지는것이 아닌, 작아진 크기에 맞게 조절됨을 알 수 있어 그부분도 해제해 주었다.
/* MEDIA */
@media (max-width : 1024px){
header.section .inner{ /* 명시도점수를 올리기 위함 */
max-width : none;
height : auto;
padding : 0 20px;
}
header .menu-group ,
header .sign-group{
float : none;
}
header .toggle{
display : none;
}
header .logo{
padding : 12px 0;
}
#toggle-btn{
background : url("../img/toggle-btn.svg");
width : 18px;
height : 24px;
position : absolute;
top : 16px;
right : 20px;
cursor : pointer;
text-indent:-9999px;
}
}
우선 toggle에 적용한 display none을 해제해주고, 줄어들었을때의 메뉴들을 꾸며주어야 한다.
/* MEDIA */
@media (max-width : 1024px){
header.section .inner{ /* 명시도점수를 올리기 위함 */
max-width : none;
height : auto;
padding : 0 20px;
}
header .menu-group ,
header .sign-group{
float : none;
}
header .menu-group{
display : block;
}
header .logo{
padding : 12px 0;
}
header .main-menu{
display : block; /*메뉴들 항목을 수직으로 다시 놔둠*/
margin-bottom : 10px;
}
header .main-menu li{
border-top : 1px solid #e5e5e5;
}
header .main-menu li a{
padding : 16px 0;
}
header .sign-group{
display : block; /*flex 해제 및 order도 해제된다*/
padding : 10px 0 20px;
}
header .btn-group{ /*btn이 inline-flex면 flex로 수정*/
display : block;
}
header .btn-group .btn{
justify-content: center;
}
header .btn-group .sign-in{
margin-right : 0;
margin-bottom : 12px;
}
#search-form{
margin-top: 12px;
margin-right: 0;
}
header .sub-menu{
margin-top: 12px;
margin-right: 0;
justify-content: center;
}
#search{
width : 100%;
height : 42px;
text-align: center;
}
header .toggle{
/* display : none; */
}
#toggle-btn{
background : url("../img/toggle-btn.svg");
width : 18px;
height : 24px;
position : absolute;
top : 16px;
right : 20px;
cursor : pointer;
text-indent:-9999px;
}
}
flex로 수평정렬했던것을 다 풀어준 모습이다. 여기서, btn이 inline-flex로 설정되어 있으면 display : block을 해도 정렬이 되지 않으니 btn을 flex로 풀어주자.
자 이제 다시 toggle클래스안의 display : none을 해제하고 저 햄버거버튼이 눌렸을 경우에만 메뉴버튼들이 나오게 해야한다. 이는 JS를 사용하여 이벤트 처리를 해야한다.
JS를 아직 공부하진 않았지만 어느정도 역할을 하는 함수란 것만 대충 이해하고 넘어가도 괜찮을 것 같다.
(function (window,document) {
'use strict';
const $toggles = document.querySelectorAll('.toggle'); //클래스찾기
const $toggleBtn = document.getElementById('toggle-btn'); //아이디찾기
$toggleBtn.addEventListener('click', function () {
toggleElements();
});//버튼을 클릭했을때
window.addEventListener('resize', function () {
if (window.innerWidth > 1024) {
offElements();
}
});
function toggleElements() {
[].forEach.call($toggles, function (toggle) {
toggle.classList.toggle('on');
});
}
function offElements() {
[].forEach.call($toggles, function (toggle) {
toggle.classList.remove('on');
});
}
}) (window,document)
간단하게 토글을 눌렀을때 .on클래스를 만들고 없애줘서 기능을 추가해준 것이다.
header .toggle.on{
display : block;
}
css엔 미리 toggle on 을 만들어두었다.
이 js를 적용시킬 때 주의할 점은
<script defer src="main.js"></script> <!--defer : html다 읽고 JS실행-->
head부분 맨 마지막에 추가하면 되는데, 꼭 defer를 추가해야지 html을 다 읽고 js가 실행된다는 점이다. 이게 싫으면 body태그 맨 밑에 defer없이 추가해도 괜찮다.
#toggle-btn{ /*안보이더라도 위에서 설정해두는 스타일이 좋다*/
display : none;
background : url("../img/toggle-btn.svg");
width : 18px;
height : 24px;
position : absolute;
top : 16px;
right : 20px;
cursor : pointer;
text-indent:-9999px;
}
또한 toggle-btn의 모양이나 css를 설정하는것이 mediaqurry안보다는 위에서 선언하는것이 조금더 규칙적인 코드이기에 쓰여진 부분을 header부분 맨 밑에 추가하였고, 미디어쿼리 안의 toggle-btn에는 display : block코드만 넣어주어 좀더 깔끔한 css로 만들어주었다.
16.Visual 콘텐츠 반응형
현재까지는 visual부분이 보기안좋게 짤려지는 모습을 볼 수 있는데 이 부분을 고쳐보겠다.
/*VISUAL */
.section--visual{
background-image: url(../img/bg-small.jpg);
/*조금더 작은 사이즈에 알맞은 이미지*/
}
.section--visual .inner{
display : block;
max-width: none;
padding : 80px 20px;
}
.section--visual .summary{
text-align: center;
margin-right: 0;
margin-bottom: 50px;
}
#sign-form{
width : auto;
max-width: 500px;
margin : 0 auto;
}
크게어려울 건 없고, 미디어쿼리 안쪽에 다음과 같은 코드로 정렬을 해주거나 크기를 조정해주면 된다.
또한, 백그라운드 이미지도 바꿔주어서 저 깃허브 캐릭터가 더 잘보이게 했다.
17.Feature , Where is , Pricing , Footer
위 항목들은 간단하니 한번에 해치워 버리겠다.
우선 Feature부분은
이를 쪼개기 위해서는 float을 해제해주면 된다.
/*FEATURE*/
.section--feature .summary{
padding : 66px 20px 0 20px;
}
.section--feature .tiles li{
width : 50%;
}
.section--feature .tiles li:nth-child(2){
border-right : none;
}
.section--feature .tiles li img{
padding : 14px 30% 24px;
}
이역시 미디어쿼리 안에 넣어야 한다. 만약에 이코드대로 넣었는데 되지 않았다면, float으로 정렬한것이 아닌 grid를 사용했을 수 있다. 그경우 float으로 바꾼 후 HTML상 clearfix도 넣고 하면서 float으로 바꾸던지, grid의 특성을 이용해서 2개씩 쪼개지게 설정해주면 될 것 같다.
그다음 밑의 부분은 간단한 부분들만 수정을 해주었다.
/*WHERE IS*/
.section--where-is .inner{
max-width: none;
padding : 80px 20px 0 20px;
}
/*PRICING CARD*/
.section--pricing .inner{
max-width: none;
padding: 80px 20px;
}
.section--pricing .card .cell2{
font-size : 20px;
}
/* FOOTER */
footer .inner{
padding : 50px 20px;
}
footer .logo{
display: none;
}
18. 미디어 쿼리 분리
지금까지 css폴더 안에서
@media (max-width : 1024px){
}
위 형식 안에 넣는방식으로 했는데 이러면 css코드도 엄청 길어지고 관리도 어려워 진다.
그래서 { } 중괄호 안의 부분만 복사를 한 후에, css파일 안에 새로운 파일을 만들어서 복사 붙여넣기를 해준다.
이름은 main_medium.css로 해두었고 main_small.css까지 만들어두었다.
<link rel="stylesheet" media ="(max-width : 1024px)"href="css/main_medium.css"> <!--미디어쿼리-->
<link rel="stylesheet" media ="(max-width : 768px)" href="css/main_small.css">
이를 HTML main.css넣어둔 밑에 저렇게 media옵션을 이용하여 넣어주면 똑같이 정상작동하는것을 알 수 있다.
19. SMALL Device
고칠부분은 우리가 만들어보기로 한페이지
https://heropcode.github.io/GitHub-Responsive/
위에서 특성들을 확인해 보면 될 것 같다.
대표적으로 feature부분이 사진이 정렬이 1개씩 되었고 footer에서도 수직정렬로 변하고 이런 간단한 것들이 변한것을 알 수 있다.
/* COMMON */
.summary__title{
font-size : 34px !important;/*visual칸 안의 글자도 줄어들게!*/
}
.summary_description{
font-size : 22px;
}
/*FEATURE*/
.section--feature .tiles li{
width : 100%;
border-right : none;
border-bottom: 1px solid #e5e5e5;
}
/*WHERE IS*/
#map{
width : auto; /*100%면 padding이 들어간 inner의 가로사이즈를 받아서 문제발생*/
margin : 40px -20px 0 -20px; /*맵 좌우를 늘려줌*/
border-left : none;
border-right: none;
}
/* PRICING */
.section--pricing .card{
display : block;
}
.section--pricing .card .cell2{
border-left: none;
border-top: 1px solid #e5e5e5;
}
/* FOOTER */
footer .site-links{
float : none;
display : block;
text-align:center;
}
footer .site-links:first-child{
margin-bottom: 20px;
}
footer .site-links li{
display :inline; /*footer 목록은 텍스트처럼 처리*/
}
해당코드처럼 추가하면 완성!
전체 코드랑 이미지는 위 파일을 첨부해보면 될 것 같다.
'프로젝트 > 소규모프로젝트들' 카테고리의 다른 글
JS_리액트_TodoList (0) | 2021.12.27 |
---|---|
MFC를 이용한 디지털신호처리 프로그램 (0) | 2021.12.15 |
JS_독서관리 시스템 (2) | 2021.12.10 |
GitHub 클론코딩-1 (0) | 2021.11.26 |
01_디지털 필터설계(C++) (2) | 2021.11.13 |