비전공자 개발일기

Circular Progress Bar 본문

HTML _CSS

Circular Progress Bar

HiroDaegu 2022. 10. 17. 11:18
728x90
SMALL

 

<!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>CIRCULAR PROGRESS BAR</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">

    <div class="box">
      <div class="shadow"></div>
      <div class="content">
        <div class="percent" data-text="HTML" style="--num:85;">
          <div class="dot"></div>
          <svg>
            <circle cx="70" cy="70" r="70"></circle>
            <circle cx="70" cy="70" r="70"></circle>
          </svg>
        </div>
        <div class="number">
          <h2>85<span>%</span></h2>
        </div>
      </div>
    </div>

    <div class="box">
      <div class="shadow"></div>
      <div class="content">
        <div class="percent" data-text="CSS" style="--num:90;">
          <div class="dot"></div>
          <svg>
            <circle cx="70" cy="70" r="70"></circle>
            <circle cx="70" cy="70" r="70"></circle>
          </svg>
        </div>
        <div class="number">
          <h2>90<span>%</span></h2>
        </div>
      </div>
    </div>

    <div class="box">
      <div class="shadow"></div>
      <div class="content">
        <div class="percent" data-text="JS" style="--num:70;">
          <div class="dot"></div>
          <svg>
            <circle cx="70" cy="70" r="70"></circle>
            <circle cx="70" cy="70" r="70"></circle>
          </svg>
        </div>
        <div class="number">
          <h2>70<span>%</span></h2>
        </div>
      </div>
    </div>

  </div>
</body>
</html>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: consolas;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background-color: #CFD1E1;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 80px 100px;
  flex-wrap: wrap;
}

.container .box {
  position: relative;
  width: 240px;
  height: 250px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container .box::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 20px;
  height: 100%;
  background: linear-gradient(#FFF, #FFF, #E3E3E3);
  filter: blur(1px);
  z-index: 1;
}

.container .box::after {
  content: '';
  position: absolute;
  top: 1px;
  right: -1px;
  width: 20px;
  height: 100%;
  background-color: #9D9D9D;
  filter: blur(1px);
  z-index: 1;
}

.container .box .shadow {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: #EEE;
}

.container .box .shadow::before {
  content: '';
  position: absolute;
  top: 0;
  left: calc(100% + 5px);
  width: 100%;
  height: 200%;
  background: linear-gradient(rgba(0, 0, 0, .075), transparent);
  transform: skewX(45deg);
}

.container .box .shadow::before {
  content: '';
  position: absolute;
  bottom: -200%;
  left: calc(100% + 15px);
  width: 100%;
  height: 200%;
  background: linear-gradient(rgba(0, 0, 0, .075), transparent);
  transform: skewX(45deg);
}

.container .box .content {
  position: relative;
  width: 100%;
  height: 100%;
  background: linear-gradient(#DBDAE1, #A3AABA);
  box-shadow: 5px 5px 5px rgba(0, 0, 0, .1), 15px 15px 15px rgba(0, 0, 0, .1), 20px 20px 20px rgba(0, 0, 0, .1), 50px 50px 50px rgba(0, 0, 0, .1), inset 3px 3px 2px #FFF;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.container .box .content .percent {
  position: relative;
  width: 150px;
  height: 150px;
}

.container .box .content .percent::before {
  content: attr(data-text);
  position: absolute;
  inset: 20px;
  background-color: #555;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #FFF;
  font-size: 1.75em;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.container .box .content .percent svg {
  position: relative;
  width: 150px;
  height: 150px;
  transform: rotate(270deg);
}

.container .box .content .percent svg circle {
  width: 100%;
  height: 100%;
  fill: transparent;
  stroke-width: 3;
  stroke: rgba(0, 0, 0, .05);
  transform: translate(5px, 5px);
}

.container .box .content .percent svg circle:nth-child(2) {
  stroke: #555;
  stroke-dasharray: 440;
  stroke-dashoffset: calc(440 - (440 * var(--num)) / 100);
  opacity: 0;
  animation: fadeIn 1s linear forwards;
  animation-delay: 2.5s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.container .box .content .percent .dot {
  position: absolute;
  inset: 5px;
  z-index: 10;
  animation: animateDot 2s linear forwards;
}

@keyframes animateDot {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(calc(3.6deg * var(--num)));
  }
}

.container .box .content .percent .dot::before {
  content: '';
  position: absolute;
  top: -7px;
  left: 50%;
  transform: translateX(-50%);
  width: 14px;
  height: 14px;
  background-color: #555;
  border-radius: 50%;
}

.container .box .content .number {
  position: relative;
  inset: 0;
  opacity: 0;
  animation: fadeIn 1s linear forwards;
  animation-delay: 2.5s;
}

.container .box .content .number h2 {
  font-size: 2.5em;
  color: #555;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container .box .content .number h2 span {
  font-weight: 300;
  font-size: .5em;
  margin-left: 5px;
}
728x90
LIST

'HTML _CSS' 카테고리의 다른 글

Task Dashboard  (0) 2022.10.20
Animated BG  (0) 2022.10.18
Multi-step Growing BTN  (0) 2022.10.14
Password Strength Checker  (0) 2022.10.13
Eye Follow Mouse Cursor  (0) 2022.10.12