웹 개발에서는 다양한 UI 라이브러리와 프레임워크가 존재하지만,
때로는 이러한 라이브러리에 과하게 의존하는 경향이 있다.
(대표적으로 내가 그런 사람..)
하지만 이는 프로젝트의 복잡성을 증가시키고, 추가적인 의존성 관리 및 번들 크기 증가로 이어질 수 있기에,
어느 정도 웹에 대해 공부하신 분들은 아시리라 생각이 들지만,
기본 HTML 태그와 CSS를 활용하여 간단한 기능들을 구현할 수 있는 기능들을 소개하고자 한다.
라이브러리에 과하게 의존하지 않기
1. Select box(Select, OptGroup, Option)
각종 디자인 라이브러리(antd
, 'bootstrap',mui
, shadcn/ui
등)의 Select
컴포넌트나 React Select
, Downshift
등의 라이브러리를 사용하지 않고,
기본 HTML의 <select>
와<optgroup>
, <option>
태그를 활용하여 선택 가능한 입력을 만들 수 있다.
import { useState } from 'react';
import styled from 'styled-components';
const SelectContainer = styled.div`
margin: 20px;
`;
const SelectInput = styled.select`
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
width: 200px;
`;
const SelectableInput = () => {
const [selectedValue, setSelectedValue] = useState('');
return (
<SelectContainer>
<SelectInput value={selectedValue} onChange={(e) => setSelectedValue(e.target.value)}>
<option value="">Select an option</option>
<optgroup label="Group 1">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</optgroup>
<optgroup label="Group 2">
<option value="option3">Option 3</option>
<option value="option4">Option 4</option>
</optgroup>
</SelectInput>
</SelectContainer>
);
};
export default SelectableInput;
2. Accordion(Detail + Summary)
마찬가지로 각종 디자인 라이브러리의 Accordion
컴포넌트나 React Accordion
같은 라이브러리를 사용하지 않고,
HTML의 <details>
와 <summary>
태그를 사용하여 간단한 아코디언 위젯을 만들 수 있다.
import styled from 'styled-components';
const AccordionContainer = styled.div`
margin: 20px;
`;
const Accordion = () => {
return (
<AccordionContainer>
<details>
<summary>Click to expand</summary>
<p>This is the hidden content that appears when the summary is clicked.</p>
</details>
<details>
<summary>Another section</summary>
<p>This is another hidden content.</p>
</details>
</AccordionContainer>
);
};
export default Accordion;
3. 팝업 구현(Dialog)
마찬가지로 각종 디자인 라이브러리의 Dialog
컴포넌트나 React Modal
같은 라이브러리를 사용하지 않고,
HTML의 <dialog>
태그를 사용하여 간단한 팝업을 구현할 수 있다.
import { useRef } from 'react';
import styled from 'styled-components';
const DialogContainer = styled.div`
margin: 20px;
`;
const DialogButton = styled.button`
padding: 10px;
margin: 10px;
`;
const DialogExample = () => {
const dialogRef = useRef<HTMLDialogElement>(null);
const openDialog = () => {
dialogRef.current?.showModal();
};
const closeDialog = () => {
dialogRef.current?.close();
};
return (
<DialogContainer>
<DialogButton onClick={openDialog}>Open Dialog</DialogButton>
<dialog ref={dialogRef}>
<p>This is a simple dialog popup.</p>
<DialogButton onClick={closeDialog}>Close</DialogButton>
</dialog>
</DialogContainer>
);
};
export default DialogExample;
4. 진행 상황(Meter, Progress)
React Progress Bar
나 React Spinners
같은 라이브러리를 사용하지 않고,
HTML 의 <meter>
와 <progress>
태그를 통해 진행 상황을 나타낼 수 있다.
- 차이점:
- Meter (
<meter>
):- 정량적 측정에 사용된다. 예를 들어, 배터리 잔량, 디스크 사용량 등과 같은 특정 범위 내에서 현재 값이 차지하는 비율을 나타낸다.
- 값이 정해진 범위(min, max) 내에 있어야 하며, 그 범위 내에서 현재 값을 시각적으로 표현한다.
- Progress (
<progress>
):- 진행 상태를 나타내는 데 사용된다. 예를 들어, 파일 업로드, 다운로드, 비디오 로딩 등의 작업 진행 상황을 보여준다.
- 일반적으로 사용자는 이 진행 상황이 완료될 때까지 기다려야 하며, 작업의 완료 여부를 나타낸다.
- Meter (
import styled from 'styled-components';
const ProgressContainer = styled.div`
margin: 20px;
`;
const StyledMeter = styled.meter`
width: 100%;
height: 20px;
border: 1px solid #ccc;
border-radius: 4px;
margin-bottom: 10px;
`;
const StyledProgress = styled.progress`
width: 100%;
height: 20px;
`;
const ProgressExample = () => {
return (
<ProgressContainer>
<h3>Meter Example</h3>
<StyledMeter min="0" max="100" value="75" />
<p>75% of the total value (e.g., disk usage, battery level).</p>
<h3>Progress Example</h3>
<StyledProgress value="50" max="100" />
<p>50% progress of an ongoing task (e.g., file upload).</p>
</ProgressContainer>
);
};
export default ProgressExample;
결론
위의 예시들처럼, 기본 HTML 태그와 CSS를 활용하여 다양한 UI 기능을 구현할 수 있다.
기본 HTML과 CSS로 구현할 수 있는 간단한 기능들을 활용하여 더 가볍고 유지보수가 용이한 애플리케이션을 만드는 습관을 들이자.