티스토리 뷰

6. 그림자 효과의 세 가지 방법: box-shadow, text-shadow, drop-shadow

CSS에서 그림자를 표현하는 방법은 크게 세 가지가 있습니다:
1. box-shadow: 요소 전체에 그림자를 적용
2. text-shadow: 텍스트에만 그림자를 적용
3. filter: drop-shadow(): SVG나 PNG 이미지에 그림자를 적용

각각의 속성은 다음과 같은 형식으로 사용됩니다:
- box-shadow: x축 y축 blur 색상
- text-shadow: x축 y축 blur 색상
- filter: drop-shadow(x축 y축 blur 색상)

아래의 예제에서 볼 수 있듯이, 각각의 그림자 효과는 서로 다른 용도에 최적화되어 있습니다. box-shadow는 div와 같은 블록 요소에, text-shadow는 텍스트에, 그리고 drop-shadow는 투명도가 있는 이미지나 SVG에 가장 적합합니다.

특히 SVG 아이콘에 그림자를 넣을 때는 box-shadow 대신 drop-shadow를 사용해야 아이콘의 실제 모양을 따라 자연스러운 그림자가 생성됩니다.

// html
<div class="box-shadow">Box Shadow</div>
<h1 class="text-shadow">Text Shadow</h1>
<svg class="search-icon" xmlns="http://www.w3.org/2000/svg" height="154" viewBox="0 -960 960 960" width="154"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>

// css
body{
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 100px;
}
.search-icon{
  filter: drop-shadow(5px 5px 5px rgba(0, 0, 0, 0.3));
}

.box-shadow{
  height: 250px;
  width: 250px;
  text-align: center;
  align-content: center;
  font-size: 2rem;
  font-weight: 600;
  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1);
}
.text-shadow{
  text-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
}

 

7. grid-template-rows와 overflow를 활용한 애니메이션 효과

CSS Grid와 overflow 속성을 활용하면 자연스러운 확장/축소 애니메이션을 구현할 수 있습니다.

이 기법의 핵심은 다음과 같습니다:
1. grid-template-rows를 사용하여 콘텐츠 영역의 크기를 제어
2. overflow: hidden으로 넘치는 콘텐츠를 숨김
3. transition으로 부드러운 애니메이션 효과를 추가

grid-template-rows: 1.5em 0fr에서 1.5em은 헤더의 높이를, 0fr은 콘텐츠 영역의 높이를 의미합니다. 0fr일 때는 콘텐츠가 완전히 접히고, 1fr로 변경하면 콘텐츠가 자연스럽게 펼쳐집니다.

이 방식의 장점은 콘텐츠의 실제 높이를 계산할 필요 없이, fr 단위를 통해 자동으로 적절한 높이가 설정된다는 것입니다. 또한 transition과 결합하면 부드러운 애니메이션 효과를 쉽게 구현할 수 있습니다.

// html
<div class="container">
  <div class="summary">Hello World</div>
  <div class="hidden">
  <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Expedita  est ea ipsa possimus corporis harum, obcaecati recusandae optio,  dolore, maxime quibusdam eaque iure corrupti laboriosam laborum. Atque,  explicabo maiores! Omnis, quaerat nihil repellendus impedit obcaecati  iusto mollitia! Praesentium excepturi ipsa atque natus eum libero cum,  omnis minus id veritatis necessitatibus quis tenetur, soluta quo  commodi! Adipisci sapiente unde consequatur natus quas sequi numquam  dolores atque temporibus! Labore assumenda laudantium earum doloribus  nam tempore rerum maxime ut? Rem consequuntur laborum magnam  voluptatibus quidem ullam fuga repellendus aliquid. Accusamus et  officia saepe pariatur, iste autem. Ipsa qui amet sequi, officia quia  eaque.</p>
</div>

// js
const container = document.querySelector('.container');
container.addEventListener('click', () => {
  container.classList.toggle('open');
});

// css
.container{
  margin: 0 auto;
  width: min(500px, 100%);
  padding: 1.5em;

  background-color: #2a2f3d;
  color: white;
  cursor: pointer;
  transition: 150ms ease;

  display: grid;
  grid-template-rows: 1.5em 0fr;
}
.open{
  grid-template-rows: 1.5em 1fr;
}
p{
  margin-top: 2.5em;
}
.hidden{
  overflow: hidden;
}

 

8. clip-path로 요소 모양 변경하기

clip-path 속성을 사용하면 요소의 보여지는 영역을 다양한 도형으로 잘라낼 수 있습니다. 이를 통해 체크박스를 원형으로 만들거나 이미지를 삼각형 모양으로 표시하는 등 창의적인 디자인이 가능합니다.

clip-path는 다음과 같은 값들을 사용할 수 있습니다:
- circle(): 원형으로 잘라냅니다. 예) circle(50%)
- polygon(): 다각형 모양으로 잘라냅니다. 좌표값을 지정하여 원하는 모양을 만들 수 있습니다.

이 속성은 이미지나 폼 요소 등 거의 모든 HTML 요소에 적용할 수 있어 활용도가 높습니다. 특히 appearance: none과 함께 사용하면 기본 스타일을 완전히 재정의할 수 있어 커스텀 UI 컴포넌트를 만드는데 유용합니다.

// html
<input type="checkbox">

//css
input[type="checkbox"]{
  height: 20px;
  width: 20px;
  clip-path: circle(50%);
  accent-color: #9443d7;
  appearance: none;
  background: #cacaca;
}
input[type="checkbox"]:checked{
  appearance: auto;
}
img{
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

 

9. 동적 가상 요소로 라벨 만들기

가상 요소(::before, ::after)와 data 속성을 활용하면 HTML 구조를 변경하지 않고도 동적인 라벨을 만들 수 있습니다. 이는 앞서 살펴본 그림자 효과나 clip-path와 함께 사용하면 멋진 UI를 만들 수 있습니다.

이 기법의 핵심은 다음과 같습니다:
1. HTML 요소에 data-* 속성으로 라벨 텍스트를 지정
2. ::before 가상 요소에서 attr() 함수로 data 속성값을 가져옴
3. position: absolute로 원하는 위치에 배치

특히 이 방식은 다음과 같은 장점이 있습니다:
- HTML 구조가 깔끔해짐
- JavaScript 없이도 동적인 콘텐츠 표시 가능
- CSS만으로 스타일링과 위치 조정이 자유로움

grid나 clip-path 등 다른 모던 CSS 기능들과 조합하면 더욱 다양한 디자인을 만들 수 있습니다. 예를 들어, grid로 카드 레이아웃을 만들고 각 카드에 동적 라벨을 추가하거나, clip-path로 라벨 모양을 커스터마이징할 수 있습니다.

// html
<div data-label="free" class="product">
  <h2>HTML Course</h2>
  <p>Learn the basics of web development with HTML5 as beginner-friendly as possible.</p>
  </div>
  <div data-label="best selling" class="product">
  <h2>HTML & CSS Course</h2>
  <p>Learn HTML5 and CSS3 in 7 Days completely from scratch.</p>
  </div>
  <div data-label="coming soon" class="product">
  <h2>JavaScript Course</h2>
  <p>Learn the JavaScript Basics and Advanced Concepts by completing practical projects.</p>
</div>

// css
*{
  margin: 0;
  padding: 0;
}
body{
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
  background-color: #0F1016;
  color: white;
}
.product{
  padding: 2em;
  width: 350px;
  background-color: #272935;
  border-radius: .3em;
  display: grid;
  gap: 1em;
  text-align: center;
  position: relative;
} 
h2{
  font-size: 2rem;
  text-align: center;
}
img{
  border-radius: .3em;
}
.product::before{
  content: attr(data-label);
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -50%;
  background-color: #ffdd0035;
  border: 1px solid #ffdd00;
  color: #ffdd00;
  padding: .5em 2em;
  border-radius: 100px;
  text-transform: uppercase;
}

 

10. 원뿔형 그라데이션을 활용한 회전 애니메이션

CSS의 `conic-gradient`와 `@property` 규칙을 사용하여 동적인 회전 애니메이션을 만들 수 있습니다.

이 예제에서는 `--angle` 커스텀 속성을 정의하고, 이를 `conic-gradient`의 시작 각도로 사용합니다. 
`animation` 속성으로 각도를 0도에서 360도까지 변화시켜 회전하는 효과를 구현했습니다.

자식 요소는 부모의 크기를 상속받아 중앙에 정렬되며, 부모 요소의 그라데이션 애니메이션이 배경으로 표시됩니다.

이러한 기법은 로딩 인디케이터나 장식적인 UI 요소를 만드는 데 활용할 수 있습니다.

// html
<div class="element">
  <div class="child">
    <h1>This is a child element</h1>
    <p>And the parent's background has the gradient animation</p>
  </div>
</div>

// css
body{
  min-height: 100vh;
  display: grid;
  place-content: center;
}
@property --angle{
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.element{
  height: 400px;
  width: 400px;
  padding: 1em;
  background-image: conic-gradient(from var(--angle), red, blue, red);  
  animation: 1s spin linear infinite;
  display: flex;
  align-items: center;
  justify-content: center;
}
@keyframes spin{
  from{
    --angle: 0deg;
  }
  to{
    --angle: 360deg;
  }
}
.child{
  height: 100%;
  width: 100%;
  background-color: #1e1a2b;
  color: white;
  text-align: center;
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함