"CSS만으로 매우 간단하게"
특정 숫자가 입력되었을 때, 숫자가 증가하고 감소하는 count component를 구현해보고자 한다.
완성 결과는 아래와 같을 것이다.
숫자 변화 하는 효과 (Count up, Count down) 구현
이번 포스트의 주요사항은 CSS의 conuter의 사용법이지만, 이를 조금 더 편리하게 사용하기 위해 나는 vue3를 이용하기로 했다.
vue를 이용하지 않는 방법에 대해서도 마지막에 간단히 정리하고자 하니 잘 따라 와주면 좋겠다.
만약 JS변수를 바로 CSS에서 사용하는 방법에 대해 모른다면 이전 포스트를 참고하자.
1. 숫자 변하는 효과 - html, js
우선, Count라는 컴포넌트를 아래와 같이 만들었다.
매우 간단한 컴포넌트지만, 만들 때 범용성을 위해 고려한 사항은 아래와 같았다.
(사실 duration 부분은 내가 필요할 것 같아 추가한 부분이지만 스킵하고 진행하면 훨씬 편하게 구현 할 수 있다. 바로 CSS쪽으로 가도 무방하다.)
- 해당 컴포넌트에 원하는 숫자 전달이 가능할 것.
- 숫자가 변화하는 시간을 정할 수 있을 것.
그럼 바로 코드를 통해 알아보자.
<template>
<div class="num"></div>
</template>
<script lang="ts">
import { PropType, defineComponent, computed } from 'vue';
import { RequireBothOrNever } from '@/types/type';
interface CountOption {
duration?: number;
timeUnit?: 's' | 'ms';
num: number;
}
type CountProp = RequireBothOrNever<CountOption, 'duration' | 'timeUnit'>;
export default defineComponent({
props: {
options: Object as PropType<CountProp>,
},
setup(props) {
const curOptions = computed(() => {
const defaultOptions = {
duration: 1000,
timeUnit: 'ms',
num: 0,
completeDuration: '1000ms',
};
if (props.options?.duration && props.options.timeUnit) {
defaultOptions.completeDuration = props.options.duration + props.options.timeUnit;
}
return { ...defaultOptions, ...props.options };
});
return {
//variables
curOptions,
};
},
});
</script>
간단한 코드이니 짧게 살펴보자.
- CountProp타입으로 필요한 매개변수들을 전달 받는다.
이때, duration과 timeUnit은 동시에 전달 받거나 아예 전달 받지 않도록 한다. - 전달 받은 값을 curOptions에 computed를 이용하여 저장한다.
만약 duration 관련하여 전달 받지 못한 경우 default 값으로 1000ms으로 설정한다.
이제 script에 저장한 변수 curOptions를 style쪽에서 바로 사용하면 된다.
2. 숫자 변하는 효과 - CSS
이제 기본 세팅은 끝났다. 여기서 주의해서 볼 점은 아래 두 가지이다.
- @property
- counter
<style lang="scss" scoped>
//1. 변수 선언
@property --num {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
@property --duration {
syntax: '<time>';
initial-value: 1000ms;
inherits: false;
}
.num {
//2. 변수 재 할당
--num: v-bind('curOptions?.num');
--duration: v-bind('curOptions.completeDuration');
//3. transition 효과 추가
transition: --num var(--duration);
//4. counter 설정
counter-set: customCounter var(--num);
//5. pseudo요소를 이용한 숫자 표시
&::after {
content: counter(customCounter);
text-shadow: 0px 0px 15px rgba(255, 255, 255, 0.6);
}
}
</style>
1. 변수선언
@property는 기본적으로 CSS 변수와 같은 방식으로 작동하지만, 그 형식과 초기값, 상속여부를 설정 할 수 있다는 것만 다르다.
즉, 위의 코드를 보면, --num이라는 변수를 선언하고 초기값을 0으로 할당 했다.
2. 변수 재 할당
vue에서 제공하는 방식인 v-bind를 이용해서 앞서 script에 저장해뒀던 변수를 들고와서 CSS변수에 재 할당 해주었다.
만약, vue를 사용하지 않고 순수한 js, css를 사용한다면 아래처럼 js파일에서 변수에 값을 저장해주면 된다
document.documentElement.style.setProperty("--duration", duration);
document.documentElement.style.setProperty("--num", num);
3. transition 효과 추가
숫자가 한번에 바뀌는 것이 아니라, 일정 시간(duration)동안 변화 되어야 하기에 transition 을 설정 해 준다.
target을 --num, 변화하는 시간을 --duration으로 설정 해 준다.
4. counter 설정
counter는 css로 숫자를 생성할 수 있게 도와주는 속성이다.
보통 아래 형식으로 생성한다.
counter-reset: [이름] [initValue]
하지만 위에서 나는 counter-set을 사용했다.
counter-set은 기존에 존재하는 counter를 정해진 값으로 세팅하는 역할을 하는데 만약 해당 이름의 counter가 존재하지 않는다면 새로운 counter를 생성하기에 더 적절하다고 생각했기 때문이다. 사용방식은 아래에서 볼 수 있듯 reset과 동일하다. (참고 문서)
counter-set: [이름] [number]
5. pseudo요소를 이용한 counter 표시
content 속성을 통해 우리는 CSS에서 html에 표시될 내용을 추가 할 수 있다.
여기에서 앞서 4번에서 설정한 counter를 사용하여 보여주자.
content: counter(customCounter);
위에서 볼 수 있듯이 counter-set 혹은 counter-reset으로 설정한 counter는 counter([Counter이름])을 통해 그 값을 불러 올 수 있다. 앞서 나는 customCounter로 생성 했기에 그 이름을 그대로 넣어주었다.
이를 통해 Counter 컴포넌트 구현이 모두 완료 되었다.
이제 이 Counter 컴포넌트는 아래 방식으로 사용 할 수 있다.
//Parent.vue
<input type="number" v-model="num" />
<Count :options="{ num: num, duration: 1000, timeUnit: 'ms' }" />
'CSS' 카테고리의 다른 글
[CSS] Reset for Modern CSS (0) | 2023.10.31 |
---|---|
Reset CSS / 초기화 CSS (0) | 2023.02.07 |
[ Scss ] Sass 함수 사용하기 (feat. css 유성효과) (0) | 2022.11.06 |
반응형 정사각형 만들기 (margin, padding 기준) (0) | 2022.08.19 |
한줄에서 넘치는 글자 '...' 으로 생략하기 (0) | 2022.08.10 |