이번 프로젝트는 유튜버 '드림코딩'님의 무료 강의 중 유튜브 클론코딩을 참고하였다.

 

디자인 및 문구정도만 참고, 코드는 참고하지 않았다.

강의를 보진 않았기에 어느 부분이 엘리님과 다른지 나중에 확인해 볼 필요가 있다.

마크업부터 CSS 박스모델링까지 내 코드가 훨씬 더러울테니...

 

이번에도 에디터는 repl.it을 사용했다.


01
완성본


<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Ryan's youTube Clone Coding</title>
  <link href="style.css" rel="stylesheet" type="text/css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>

<body>
  <div id='main-container'>
    <header id='header'>
      <h1 class='header-title'>
        <i class="fa-brands fa-youtube" style="color: #ff0000;"></i>
        <span>RyanTube</span>
      </h1>
      <div class='header-menu'>
        <i class="fa-solid fa-magnifying-glass"></i>
        <i class="fa-solid fa-ellipsis-vertical"></i>
      </div>
    </header>
    <section id="video">
      <video src="/videos/raindrop.mp4" controls autoplay></video>
    </section>
    <section id="bottom">
      <div class="bottom-left">
        <div class="left-tags">
          <span>#RyanCoding</span>
          <span>#RyanTube</span>
          <span>#Ryan</span>
        </div>
        <div class="left-title-container">
          <p class="left-title">
            클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
          </p>
          <button class="left-title-btn">
            <i class="fa-solid fa-caret-down"></i>
          </button>
        </div>
        <div class="left-view">
          <span>1M views</span>
          <span>1year age</span>
        </div>
        <div class="left-btn-container">
          <div class="left-btns">
            <i class="fa-solid fa-thumbs-up"></i>
            <span>1K</span>
          </div>
          <div class="left-btns">
            <i class="fa-solid fa-thumbs-down"></i>
            <span>0</span>
          </div>
          <div class="left-btns">
            <i class="fa-solid fa-share"></i>
            <span>Share</span>
          </div>
          <div class="left-btns">
            <i class="fa-solid fa-plus"></i>
            <span>Save</span>
          </div>
          <div class="left-btns">
            <i class="fa-solid fa-flag"></i>
            <span>Report</span>
          </div>
        </div>
        <div class="left-channel">
          <div class='channel-left-side'>
            <img src="/images/ryan.png" alt="채널 이미지 입니다.">
            <div class="channel-description">
              <p class="channel-name">Ryan's Playground</p>
              <p class="channel-sub">1M subscribers</p>
            </div>
          </div>
          <button class="channel-right-side">subscribe</button>
        </div>
      </div>
      <div class="bottom-right">
        <div class="right-up-next">Up Next</div>
        <div class="right-content-box">
          <div class="right-content">
            <img 
              src="/images/pillow-ryan.png"
              alt="다른 동영상 이미보기 이미지 입니다."
              >
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
          <div class="right-content">
            <img src="/images/pillow-ryan.png" alt="다른 동영상 이미보기 이미지 입니다.">
            <div class="right-content-description">
              <p class="right-title">
                클론코딩 유튜브 사이트 따라 만들기(HTML+CSS 연습편, 웹 포트폴리오) | 프론트엔드 개발자 입문편: HTML, CSS, Javascript
              </p>
              <p class='right-channel-name'>
                Ryan's Playground
              </p>
              <p class="right-views">
                32M views
              </p>
            </div>
            <button class="right-menu-btn">
              <i class="fa-solid fa-ellipsis-vertical"></i>
            </button>
          </div>
        </div>
      </div>
    </section>
  </div>


  
  <script src="script.js"></script>

  <!--
  This script places a badge on your repl's full-browser view back to your repl's cover
  page. Try various colors for the theme: dark, light, red, orange, yellow, lime, green,
  teal, blue, blurple, magenta, pink!
  -->
  <script src="https://replit.com/public/js/replit-badge-v2.js" theme="dark" position="bottom-right"></script>
</body>

</html>

HTML 코드

 

특별한 점은 없었다.


@import 'reset.css';

/* 폰트 */
@font-face {
    font-family: 'TheJamsil5Bold';
    src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2302_01@1.0/TheJamsil5Bold.woff2') format('woff2');
    font-weight: 300;
    font-style: normal;
}

html {
  font-size : 16px;
}

i {
  cursor: pointer;
}

button {
  background : none;
  border : none;
  outline : none;
  cursor: pointer;
  color : #fff;
}

#main-container {
  padding : 2rem 4rem;
  height : 100%;
  display: flex;
  flex-direction: column;
  background-color: #000;
  color: #fff;
  font-family: 'TheJamsil5Bold';
}

#header {
  display: flex;
  justify-content: space-between;
  align-items : center;
}

.header-title {
  cursor: pointer;
  display : flex;
  align-items: center;
}

.header-title span {
  font-weight : 700;
  margin-left: .25rem;
}

.header-menu {
  display : flex;
}

.header-menu i {
  padding : .25rem .5rem;
  margin : 0 .25rem;
}

#video {
  width : 100%;
  margin: 2rem 0;
  position : relative;
}

#video video {
  display:block;
	width:100%;
	
  border-radius: 12px;
}

#bottom {
  width: 100%;
  height: 100%;
  display : flex;
  justify-content: center;
}

.bottom-left,.bottom-right {
  width : 47.5%;
  height : 100%;
}

.left-tags {
  margin-bottom: 1rem;
  color: lightskyblue;
  font-size : .75rem;
}

.left-tags > * {
  margin-right: .25rem;
}

.left-title-container {
  margin-bottom : .5rem;
  display: flex;
  align-items : center;
}

.left-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-right: .5rem;
}

.left-title-btn {
  transition: 300ms;
}

.more {
  -webkit-line-clamp: 10;
}

.rotate {
  transform: rotate(180deg);
  transition: 300ms;
}

.left-view {
  color : #777;
  font-size : .75rem;
  margin-bottom: 1rem;
}

.left-btn-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding : 0 1rem;
  margin-bottom: 1rem;
}

.left-btns {
  display : flex;
  flex-direction: column;
  align-items: center;
}

.left-btns span {
  margin-top: .5rem;
}

.left-channel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 0;
  border-top: 2px solid #777;
  border-bottom: 2px solid #777;
}

.channel-left-side {
  display: flex;
  align-items: center;
}

.left-channel img {
  width : 36px;
  height : 36px;
  border-radius: 50%;
  background-color : #cde9fb;
  border : none;
  margin-right: .5rem;
}
  
.channel-description {
  display: flex;
  flex-direction: column;
}

.channel-sub {
  font-size : .75rem;
  margin-top: .25rem;
  color: #777;
}

.channel-right-side {
  text-transform: uppercase;
  font-weight : 700;
}

.bottom-right {
  display : flex;
  flex-direction: column;
  margin-left: 1rem;
  max-height : 250px;
}

.right-up-next {
  font-size : .75rem;
  color : #777;
  margin-bottom: 1rem;
}

.right-content-box {
  height: 100%;
  overflow: scroll;
}

.right-content {
  display: flex;
  margin-bottom: 1rem;
  position : relative;
}
  
.right-content img {
  width : 33%;
  margin-right: .5rem;
  border-radius: 4px;
  background-color: #394456;
  cursor: pointer;
}

.right-content-description {
  padding: .5rem 1.5rem .5rem .5rem;
}

.right-content-description > * {
  margin-bottom: .5rem;
}

.right-title {
  cursor: pointer;
}
  
.right-views {
  color : #777;
  font-size : .75rem;
}

.right-menu-btn {
  position: absolute;
  top: .5rem;
  right: 0rem;
}
/* 갤럭시 S20 울트라(세로) 기준 */
@media screen and (max-width : 413px) {
  #bottom {
    flex-direction: column;
    align-items: center;
  }
  .bottom-left,.bottom-right {
    width : 100%;
  }
  .bottom-right {
    margin-top: 1rem;
    max-height : none;
  }
}
/* 갤럭시 S20 울트라(가로) 기준 */
@media screen and (max-width : 916px) {
  html {
    font-size : 13px;
  }
  #main-container {
    padding : 1rem 1.5rem;
  }
  #video video {
    width : 75%;
    margin: 0 auto;
  }
}

CSS 코드

 

디자인하는데 시간이 꽤 걸렸다.

디자인에 진심인 회사에는 CSS 전문가를 따로 둔다던데,, 눈도 못 마주칠 고수들이겠지? ㄷㄷ

 

인상 깊었던 부분은 overflow 관련 코드였다.

.left-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-right: .5rem;

 

특히 webkit-line-clamp 속성은 사용자가 원하는 숫자를 넣으면 해당 문장은 그 숫자의 길이만큼만 보이게 된다는 것이다.


const leftTitle = document.querySelector('.left-title');
const leftTitleBtn = document.querySelector('.left-title-btn');

leftTitleBtn.addEventListener(('click'), () => {
  leftTitle.classList.toggle('more');
  leftTitleBtn.classList.toggle('rotate');
})

JS 코드

 

별로 한 게 없어서 딱 다섯 줄이다.

영상 타이틀 옆의 삼각형 버튼을 누르면 overflow로 가려져 있던 내용이 보이게끔, 그리고 삼각형을 180도 회전시키는 간단한 로직이다.

사전에 CSS에 more, rotate라는 값을 설정해놔야 한다.