CSS 유튜브 클론 코딩

KHW·2021년 9월 26일
0

CSS

목록 보기
13/16

유튜브 클론 코딩

해당 레이아웃과 동작을 최대한 적용하고자 하였다.


grid와 flex 사용

전체를 grid로 처리하였고 컨텐츠 부분 또한 grid로 설정하였다.
flex의 경우 가로로 배열하는 것을 위해서 구독 부분의 사진과 이름들, header의 각각의 거리 간격 , 컨텐츠 미니 그림과 내용간의 간격등에 이용했다.


주요 태그 사진 정리

container아래에 5개의 태그가 있고 이를 정리했다.
파란색은 grid를
녹색은 flex를
그외에 주요태그는 회색
나머지 태그는 오렌지색으로 처리했다.


주요 문법 다루기

grid

template-rows , columns를 이용하여 2차원을 설정하되
주의할점은 브라우저 축소시 해당 적용이 되는것은 1fr로 가변처리 적용시키고영향을 가지않게 하는 부분은 px로 고정처리를 했다.
( 유튜브 축소시 컨텐츠가 줄어드는것에만 영향이 일반적으로 가게
aside바가 아예 사라지거나 하는 구현은 아직 못함 )

template-areas , grid-area를 이용해 레이아웃을 쉽게 설정했다.


flex

justify-content:space-between;를 이용해 컨텐츠마다 거리간격을 일정하게 부여했다.

align-items:center를 이용해 영역의 수직의 중앙으로 맞추었다.


a태그

기존에 보라색과 밑줄을 제거하기 위해서
color와 text-decoration:none을 사용


@media

컨텐츠를 필요에따라 처리하기 위해서 .main--container가 @media에 영향을 받게 해당 태그 안에서 각각 적용시켰다.


관련 사진들

Chrome 확장 프로그램인 Image Downloader를 사용하였다.


해당 결과

aside는 고정된 크기를 유지하며 필요애따라 컨텐츠 크기만 줄어든다.

느낀점

유튜브 클론코딩을 하면서 grid와 flex의 강의만으로 매번 배웠던 것이 아닌 직접 사용해보면서 적용할 수 있어 좋았고 아직 스크롤 시 컨텐츠만 스크롤이 되게하는 기능 같은 것은 부족하다고 느꼈다.
(grid flex 좋긴 좋다)

코드

  • index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<link rel="stylesheet" type="text/css" href="./style.css">
<body>
<div class="container">
    <header>
        <div class="header--container">
            <div id="header--left">
                <img src="img/header/asideToggle.png">
                <img src="img/header/mainPageUrl.png">
            </div>
            <div id="header--center">
            <input type="text" placeholder="검색">
            </div>
            <div id="header--right">
            <img src="img/header/user.jpg">
            </div>
        </div>
    </header>
    <aside>
        <div class="aside--container">

            <div id="guide">
            <div>
                <img src="img/aside/home.png"></div>
            <div>
                <img src="img/aside/search.png">
                탐색
            </div>
            <div>
                <img src="img/aside/subscribe.png">
                구독
            </div>
                <hr>
            <div>
                <img src="img/aside/storage.png">
                보관함
            </div>
            <div>
                <img src="img/aside/watchRecord.png">
                시청 기록
            </div>
            <div>
                <img src="img/aside/myVideo.png">
                내 동영상
            </div>
            <div>
                <img src="img/aside/laterSee.png">
                나중에 볼 동영상
            </div>
            <div>
                <img src="img/aside/myClip.png">
                내 클립
            </div>
            </div>

            <hr>

            <div id="subscribe">
                <div>
                    <img src="img/aside/mirae.jpg"><div class="subscribe--name">미래에셋</div>
                </div>
                <div>
                    <img src="img/aside/ow.jpg"><div class="subscribe--name">오버워치 리그</div>
                </div>
                <div>
                    <img src="img/aside/toon.jpg"><div class="subscribe--name">짤툰</div>
                </div>
                <div>
                    <img src="img/aside/a924.jpg"><div class="subscribe--name">아구이뽀 A924</div>
                </div>
                <div>
                    <img src="img/aside/pacplay.jpg"><div class="subscribe--name">팍플레이Pacplay</div>
                </div>
                <div>
                    <img src="img/aside/bro.jpg"><div class="subscribe--name">정브르</div>
                </div>
            </div>

            <hr>

            <div id="youtube--information">
                <a href="/">정보</a> <a href="/">보도자료</a> <a href="/">저작권</a>
                <a href="/">문의하기</a> <a href="/">크리에이터</a> <a href="/">광고개발자</a>
                <br><br>
                <a href="/">약관</a> <a href="/">개인정보처리방침</a> <br>
                <a href="/">정책 및 안전</a> <br>
                <a href="/">YouTube 작동의 원리</a> <br>
                <a href="/">새로운 기능 테스트하기</a> <br>
                <br><br>
                <div>© 2021 Google LLC</div>
                <div>CEO: 선다 피차이</div>
                <div>주소: 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.</div>
                <div>전화: 080-822-1450(무료)</div>
            </div>


        </div>
    </aside>
    <section>
        <div class="section--container">
            <button>전체</button>
            <button>음악</button>
            <button>실시간</button>
            <button>만화 영화</button>
            <button></button>
            <button>믹스</button>
            <button>축구</button>
            <button>플랫폼 게임</button>
            <button>액션 어드벤처 게임</button>
        </div>
    </section>
    <nav>
        <div class="nav--container">
            <img src="https://www.gstatic.com/youtube/img/promos/growth/864dc47e45a7a0b06602f73155980de282b939a6d0adc7bdcda231f965bf796a_640x48.png"
                 alt=""><br>
            <button id="nav--btn">1개월 무료체험</button>
        </div>
    </nav>
    <main>
        <div class="main--container">
            <div>
                <img src="img/main/ss-1.webp" class="main--ss--webp">
                <div class="parent">
                    <img src="img/main/1.jpg" class="main--jpg">
                    <div class="main--title">
                        <div>우타이테 메들리</div>
                        <div>우타이테</div>
                        <div>조회수 100만회 * 1년 전</div>
                    </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-2.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/2.jpg" class="main--jpg">
                <div class="main--title">
                    <div>자결식당 -밥발련초밥- 풀버전</div>
                    <div>a924</div>
                    <div>조회수 30만 * 4일 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-3.webp" class="main--ss--webp">
                <div class="parent">
                    <img src="img/main/3.jpg" class="main--jpg">
                <div class="main--title"><div>4:4 빠른무한</div>
                <div>김정우TV[매정우]</div>
                <div>10만회 * 1개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-4.webp" class="main--ss--webp">
                <div class="parent">
                    <img src="img/main/4.jpg" class="main--jpg">
                <div class="main--title"><div>깃 제대로 배워보자</div>
                <div>드림코딩 by 엘리</div>
                <div>40만회 * 2개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-5.webp" class="main--ss--webp">

                <div class="parent">
                    <img src="img/main/5.jpg" class="main--jpg">
                <div class="main--title"><div>오버워치 리그 2021시즌|플레이오프|4일차</div>
                <div>오버워치 리그</div>
                <div>조회수 20만회 * 3일 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-6.webp" class="main--ss--webp">
                <div class="parent">
                    <img src="img/main/6.jpg" class="main--jpg">

                    <div class="main--title"><div>오버워치 리그 2021시즌|플레이오프|5일차</div>
                <div>오버워치 리그</div>
                <div>조회수 20만회 * 2일 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-7.webp" class="main--ss--webp">

                <div class="parent">
                    <img src="img/main/7.jpg" class="main--jpg">
                <div class="main--title"><div>비동기 프로그리맹이란?</div>
                <div>얄팍한 코딩사전</div>
                <div>조회수 10만회 * 1개월 전 </div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-8.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/8.jpg" class="main--jpg">
                <div class="main--title">
                    <div>짐슴친구들 몰아보기</div>
                <div>짤툰</div>
                <div>조회수 100만회 * 2개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-9.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/9.jpg" class="main--jpg">
                <div class="main--title">
                    <div>오버워치 리그 2021시즌|플레이오프|1일차</div>
                <div>오버워치 리그</div>
                <div>조회수 30만회 * 7일전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-10.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/10.jpg" class="main--jpg">
                <div class="main--title">
                    <div>송어를 잡아 먹어보자</div>
                <div>헌터퐝</div>
                <div>조회수 200만회 * 10개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-11.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/11.jpg" class="main--jpg">
                <div class="main--title">
                    <div>[ENG] [SMTM10] 프로듀서 8인의 역사적인 첫 만남...</div>
                <div>Mnet TV</div>
                <div>조회수 23만 * 1일 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-12.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/12.jpg" class="main--jpg">
                <div class="main--title">
                    <div>암살 그웬</div>
                <div>마재TV</div>
                <div>조회수 14만회 * 1일 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-13.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/13.jpg" class="main--jpg">
                <div class="main--title"><div>[짐승친구들] 찌찌 구출 작전</div>
                <div>짤툰</div>
                <div>조회수 200만회 * 2개월 전 </div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-14.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/14.jpg" class="main--jpg">
                <div class="main--title"><div>정글 제드</div>
                <div>팍플레이</div>
                <div>조회수 50만회 * 1개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-15.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/15.jpg" class="main--jpg">
                <div class="main--title"><div>[크리스마스 특선] 짐승친구들 몰아보기</div>
                <div>짤툰</div>
                <div>조회수 200만회 * 9개월 전</div>
                </div>
                </div>
            </div>
            <div>
                <img src="img/main/ss-16.webp" class="main--ss--webp">
                <div class="parent">
                <img src="img/main/16.jpg" class="main--jpg">
                <div class="main--title"><div>고라니</div>
                <div>짤툰</div>
                    <div>조회수 80만회 * 3개월 전 </div>
                </div>
                </div>
            </div>
        </div>
    </main>
</div>
</body>
</html>
  • style.scss
.container{
  border : 2px solid;
  display : grid;
  grid : {
    template-rows : 70px 70px 140px 1fr;
    template-columns : 250px repeat(2,1fr);
    template-areas:
            "h h h "
            "a s s "
            "a n n "
            "a m m ";

    /*   grid-gap : 10px 40px; */
    row-gap : 10px;
    column-gap : 40px;
  }
}

.container > *  {
  border: 2px solid;
}
.container header{
  grid-area : h;
}
.container main  { grid-area : m; }
.container aside  { grid-area : a; }
.container nav  { grid-area : n; }
.container section  { grid-area : s; }


//header
.header--container {
  display:flex;
  justify-content:space-between;
}

.header--container #header--left img{
  height:50px;
  margin:5px;
}

.header--container #header--center input{
  height:50px;
  margin:5px;
}


.header--container #header--right img{
  border-radius: 50%;
  height:50px;
}

//aside
aside{
  position:sticky;
}
.aside--container{
  height:900px;
  overflow-y: scroll;
}

#guide img{
  margin:5px;
}


#subscribe div{
  height:50px;
  margin:10px;
}


.aside--container #subscribe div{
  display:flex;
  align-items: center;
}

.aside--container #subscribe div img{
  border-radius:50%;
  height:100%;
  margin:5px;
}

.aside--container #subscribe div div{
  left:70px;
  margin:5px;
  vertical-align: middle;
}

#youtube--information{
  margin:7px;
}

a {
  color:black;
  text-decoration:none !important
}


//section
.section--container{
  white-space:nowrap;
  overflow-x: scroll;
}

.section--container button{
  height:40px;
  border-radius: 1.5em;
  padding:10px;
  margin : 10px 5px 0px 10px;
}

//nav
.nav--container{
  margin:5px;
}

#nav--btn{
  color:blue;
  border:1px solid;
  width:150px;
  height:50px;
  margin : 20px;
}


//main
.main--container{
  font-size:0.8em
}


//width를 row와 column이 차지하는 부분에서의 최대만큼만 넓게
.main--ss--webp{
  width:100%;
}

.parent{
  display:flex;
  align-items: flex-start;
  height:120px;
}

.main--jpg{
  margin:5px;
  border-radius:50%;
  width:20%;
}

.main--title{
  margin:5px;
  font-size:1em;
  font-weight:bold;
  left : 30%;
  display:inline-block;
  width:70%;
}

@media screen and (max-width:770px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(1,1fr);
      template-columns : repeat(1,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:770px) and (max-width:900px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(2,1fr);
      template-columns : repeat(2,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:900px) and (max-width:1116px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(3,1fr);
      template-columns : repeat(3,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:1116px) {
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(4,1fr);
      template-columns : repeat(4,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}

관련 리뷰 피드백

@mixin @include의 사용 추가1

  • 기존 코드
.header--container #header--left img{
  height:50px;
  margin:5px;
}

.header--container #header--center input{
  height:50px;
  margin:5px;
}


.header--container #header--right img{
  border-radius: 50%;
  height:50px;
}
  • 수정한 코드
@mixin header--container{
  height:50px;
  margin:5px;
}

.header--container{
  #header--left{
    img{
      @include header--container;
    }
  }
  #header--center{
    input {
      @include header--container;
    }
  }
  #header--right{
    img{
      border-radius: 50%;
      @include header--container;
    }
  }
}

@mixin을 통해 header--container라는 이름의 @mixin을 정의하고 해당 내용을 각각의 필요한 부분에 @include로 첨부하였고
중첩을 통하여 함께 써주었다. (.header--container 중복 피하기)

@mixin @include의 사용 추가2

  • 기존 코드
@media screen and (max-width:770px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(1,1fr);
      template-columns : repeat(1,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:770px) and (max-width:900px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(2,1fr);
      template-columns : repeat(2,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:900px) and (max-width:1116px){
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(3,1fr);
      template-columns : repeat(3,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
@media screen and (min-width:1116px) {
  .main--container{
    margin:10px;
    display : grid;
    grid : {
      template-rows : repeat(4,1fr);
      template-columns : repeat(4,1fr);

      /*   grid-gap : 10px 40px; */
      row-gap : 10px;
      column-gap : 40px;
    }
  }
}
  • 수정코드
@mixin media-grid-style($n , $fr)
{
  .main--container {
    margin: 10px;
    display: grid;
    grid : {
            template-rows : repeat($n,$fr);
            template-columns : repeat($n,$fr);

            /*   grid-gap : 10px 40px; */
            row-gap : 10px;
            column-gap : 40px;
          }
  }
}

@media screen and (max-width:770px){
  @include media-grid-style(1, 1fr);
}
@media screen and (min-width:770px) and (max-width:900px){
  @include media-grid-style(2, 1fr);
}
@media screen and (min-width:900px) and (max-width:1116px){
  @include media-grid-style(3, 1fr);
}
@media screen and (min-width:1116px) {
  @include media-grid-style(4, 1fr);
}

확실히 @mixin과 @include를 쓰니 간편해졌다.

멘토님 피드백

  • id 는 중복될 경우에 js 에서 처리하기 힘든 부분이 있어서 디자인을 입히기 위해 사용하는 부분은 지양
  • class 명에 header--container 보다는 #header .container .left 와 같은 조합으로 구성하는게 css 를 볼때 가독성이 더 좋을 것 같습니다.
profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글