본문 바로가기
프론트엔드/CSS

오버워치 영웅 선택 화면 실습

by step 1 2021. 4. 29.
반응형

출처: GitHub - ParkYoungWoong/overwatch-hero-selector-vanilla

 

ParkYoungWoong/overwatch-hero-selector-vanilla

Contribute to ParkYoungWoong/overwatch-hero-selector-vanilla development by creating an account on GitHub.

github.com

css 초기화: www.jsdelivr.com/package/npm/reset-css

 

jsDelivr - A free, fast, and reliable CDN for Open Source

Supports npm, GitHub, WordPress, Deno, and more. Largest network and best performance among all CDNs. Serving more than 80 billion requests per month. Built for production use.

www.jsdelivr.com

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Overwatch</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
    <link rel="stylesheet" href="./main.css">
</head>
<body>
    
    <div class="container">
        <div class="heroes">
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
        </div>
        <div class="logo">
            <img src="https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/logo_overwatch.png" alt="Overwatch">
        </div>
    </div>
</body>
</html>
body {
    width: auto;
    height: 100vh;  /*화면에 보이는 전체 영역*/
    /*배경이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/bg.jpg");
    background-size: cover; /*더 넓은 너비에 맞게 이미지 출력*/
    background-repeat: no-repeat; /*반복 안함*/
    background-attachment: fixed; /*배경이미지 고정*/
}
.container {
    padding: 50px 0;  /*밑으로 이동*/
}

.container .heroes {
    display: flex;  /*수평으로 정렬*/
    flex-wrap: wrap;  /*줄바꿈 처리*/
    justify-content: center; /*아이템 요소 가운데 정렬*/
    max-width: 700px; /*최대 가로 넓이 지정*/
    margin: 0 auto;   /* 가운데 정렬 */
    padding: 40px 20px;
}

.container .heroes .hero {
    width: 80px;
    height: 84px;
    margin: 4px;                /*각각 나눠보이게 하기 위해서*/
    border: 3px solid #fff;
    border-radius: 10px;        /*모서리 둥글게*/
    box-sizing: border-box;     /*border 사이즈 포함해서 전체 사이즈 고정*/
    background-color: #555;
    overflow: hidden;           /*넘치는 부분 잘라내기*/
    transform: skewX(-14deg);  /*기울기*/
    transition: 
        transform .1s,        /*바뀌는(요소가 커지는) 속도 조절*/
        background-color .6s; /*바뀌는(배경색 변하는) 속도 조절*/
}

/*마우스를 올렸을때 이벤트 처리*/
.container .heroes .hero:hover {
    background-color: #ff9c00;
    transform: scale(1.3) skewX(-14deg);  /*기존의 속성 삭제됨*/
    z-index: 1; /*쌓임 순서 지정(겹쳐지는 문제 해결)*/
}
.container .heroes .hero .image{
    width: 140%;    /*부모요소의 맞춰서 크기 조절하기위해 % 사용*/
    height: 100%;
    background-position: center;    /*이미지를 가운데 배치*/
    background-size: 90px;          /*가로 넓이 축소*/
    background-repeat: no-repeat;   /*이미지 반복 안함*/
    transform: skew(14deg)          /*안의 있는 내용 기울기 해제*/
               translateX(-16px);   /*이미지를 왼쪽으로 당겨옴*/
}

/*첫번째 자식요소*/
.container .heroes .hero:nth-child(1) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero1.png");
}
.container .heroes .hero:nth-child(2) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero2.png");
}
.container .heroes .hero:nth-child(3) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero3.png");
}
.container .heroes .hero:nth-child(4) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero4.png");
}
.container .heroes .hero:nth-child(5) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero5.png");
}
.container .heroes .hero:nth-child(6) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero6.png");
}
.container .heroes .hero:nth-child(7) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero7.png");
}
.container .heroes .hero:nth-child(8) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero8.png");
}
.container .heroes .hero:nth-child(9) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero9.png");
}
.container .heroes .hero:nth-child(10) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero10.png");
}
.container .heroes .hero:nth-child(11) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero11.png");
}
.container .heroes .hero:nth-child(12) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero12.png");
}
.container .heroes .hero:nth-child(13) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero13.png");
}
.container .heroes .hero:nth-child(14) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero14.png");
}
.container .heroes .hero:nth-child(15) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero15.png");
}
.container .heroes .hero:nth-child(16) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero16.png");
}
.container .heroes .hero:nth-child(17) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero17.png");
}
.container .heroes .hero:nth-child(18) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero18.png");
}
.container .heroes .hero:nth-child(19) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero19.png");
}
.container .heroes .hero:nth-child(20) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero20.png");
}
.container .heroes .hero:nth-child(21) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero21.png");
}
.container .heroes .hero:nth-child(22) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero22.png");
}
.container .heroes .hero:nth-child(23) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero23.png");
}
.container .heroes .hero:nth-child(24) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero24.png");
}
.container .heroes .hero:nth-child(25) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero25.png");
}
.container .heroes .hero:nth-child(26) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero26.png");
}
.container .heroes .hero:nth-child(27) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero27.png");
}
.container .heroes .hero:nth-child(28) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero28.png");
}
.container .heroes .hero:nth-child(29) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero29.png");
}
.container .heroes .hero:nth-child(30) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero30.png");
}
.container .heroes .hero:nth-child(31) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero31.png");
}
.container .heroes .hero:nth-child(32) .image{
    /*이미지 가져오기*/
    background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/hero32.png");
}

.container .logo {
    max-width: 300px;   /*로고 최대 크기 지정*/
    margin: 0 auto;       /*수평 가운데 조절*/
    padding: 0 20px;
}
.container .logo img {
    width: 100%;        /*부모요소의 맞게 이미지 크기 지정*/
    
}

 

결과

 

 

SCSS 사용으로 코드 반복을 줄인 결과

 

SCSS 코드

이미지를 가져오는 URL을 변수로 저장

중첩 기능 사용

상위 선택자 참조 기능 사용

반복적으로 이미지를 가져오는 코드를 반복문을 이용하여 처리하였다.

$url: "https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images";

body {
  height: 100vh;
  background-image: url("#{$url}/bg.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

.container {
  padding: 50px 0;

  .heroes {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    max-width: 660px;
    margin: 0 auto;
    padding: 40px 20px;

    .hero {
      width: 80px;
      height: 84px;
      margin: 4px;
      border: 3px solid #fff;
      border-radius: 10px;
      box-sizing: border-box;
      overflow: hidden;
      background-color: #555;
      transform: skewX(-14deg);
      transition:
        transform .1s,
        background-color .6s;

      &:hover {
        background-color: #ff9c00;
        transform: skewX(-14deg) scale(1.3);
        z-index: 1;
      }

      .image {
        width: 140%;
        height: 100%;
        transform: translateX(-16px) skewX(14deg);
        background-position: center;
        background-repeat: no-repeat;
        background-size: 90px;
      }
      // 반복문 처리
      @for $i from 1 through 32 {
        // .hero
        &:nth-child(#{$i}) .image {
          background-image: url("#{$url}/hero#{$i}.png");
        }
        // & .image {
        //   background-color: red;
        // }
      }
    }
  }
  .logo {
    max-width: 300px;
    margin: 0 auto;
    padding: 0 20px;
    img {
      width: 100%;
    }
  }
}


 

실행 결과는 동일

반응형

'프론트엔드 > CSS' 카테고리의 다른 글

특정 영역의 문자를 ... 으로 표현하는 방법  (0) 2021.09.16
CSS 변환 효과 (요소의 변환 효과)  (0) 2021.04.28
전환 효과  (0) 2021.04.28
요소의 정렬(플렉스)  (0) 2021.04.26
요소의 배치  (0) 2021.04.25