λ°μν λ€λΉκ²μ΄μ λ° λ° λλ‘λ€μ΄ λ©λ΄ μ»΄ν¬λνΈ κ΅¬ν
νλ μΉ μ ν리μΌμ΄μ μμλ λ€μν λλ°μ΄μ€ νκ²½μ λ§μΆ° UIλ₯Ό μ΅μ ννλ κ²μ΄ λ§€μ° μ€μν©λλ€. νΉν, λ°μν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄λ μ¬μ©μκ° μΉμ¬μ΄νΈ λ΄μμ μ½κ² νμν μ μλλ‘ λλ ν΅μ¬ μμμ λλ€.
μ΄λ² ν¬μ€ν μμλ λ°μν μΉ λμμΈμ κ³ λ €ν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄μ UI/UX λμμΈ ν¨ν΄κ³Ό ꡬν λ°©λ²μ μμΈν μ΄ν΄λ³΄κ³ , μ€μ μ½λ μμ μ ν¨κ» λ¨κ³λ³ ꡬν μ λ΅μ μκ°νκ² μ΅λλ€.
λ°μν λ€λΉκ²μ΄μ λ°μ νμμ±κ³Ό κΈ°λ³Έ μμΉ
λ°μν μΉ λμμΈμ λ°μ€ν¬ν, νλΈλ¦Ώ, λͺ¨λ°μΌ λ± λ€μν νλ©΄ ν¬κΈ°μ λ°λΌ μ λμ μΈ λ μ΄μμμ μ μ©νλ κ²μ λͺ©νλ‘ ν©λλ€. λ€λΉκ²μ΄μ λ°λ μ¬μ©μκ° μ¬μ΄νΈ μ 체λ₯Ό νμν μ μλλ‘ μ€μν λ©λ΄λ€μ μ 곡νλλ°, λ°μν λ€λΉκ²μ΄μ λ°λ λ€μκ³Ό κ°μ νΉμ§μ κ°μ΅λλ€.
- μ μ°ν λ μ΄μμ: ν° νλ©΄μμλ κ°λ‘λ‘ λ°°μΉλ λ©λ΄κ°, μμ νλ©΄μμλ νλ²κ±° λ©λ΄λ λλ‘λ€μ΄ νμμΌλ‘ μ νλμ΄ μ¬μ©μ±μ κ·Ήλνν©λλ€.
- μ§κ΄μ μΈ μΈν°λμ : μ¬μ©μκ° λ©λ΄λ₯Ό μ½κ² μΈμ§νκ³ μ κ·Όν μ μλλ‘, λͺ νν μμ΄μ½κ³Ό ν μ€νΈ, μ λλ©μ΄μ ν¨κ³Όλ₯Ό ν΅ν΄ μκ°μ νΌλλ°±μ μ 곡ν©λλ€.
- μ κ·Όμ± κ³ λ €: ν€λ³΄λ λ΄λΉκ²μ΄μ , ARIA μμ± λ± μ κ·Όμ± νμ€μ μ μ©νμ¬, λͺ¨λ μ¬μ©μκ° μμ½κ² λ©λ΄μ μ κ·Όν μ μλλ‘ ν©λλ€.
λλ‘λ€μ΄ λ©λ΄μ μν κ³Ό λμμΈ ν¨ν΄
λλ‘λ€μ΄ λ©λ΄λ νμ λ 곡κ°μμ μ¬λ¬ νμ λ©λ΄λ₯Ό ν¨κ³Όμ μΌλ‘ νμν μ μλ UI ν¨ν΄μ λλ€. λ°μν λ€λΉκ²μ΄μ λ°μμ λλ‘λ€μ΄ λ©λ΄λ₯Ό μ¬μ©νλ©΄, μ£Όμ λ©λ΄ μΈμ λΆκ°μ μΈ λ§ν¬λ μ΅μ μ κΉλνκ² μ 리ν μ μμ΅λλ€.
λλ‘λ€μ΄ λ©λ΄ λμμΈ μ κ³ λ €ν΄μΌ ν μμλ λ€μκ³Ό κ°μ΅λλ€.
- μ λλ©μ΄μ ν¨κ³Ό: λ©λ΄κ° λΆλλ½κ² νΌμ³μ§κ³ μ¬λΌμ§λλ‘ μ λλ©μ΄μ μ μ μ©νμ¬ μ¬μ©μκ° λ³ν μνλ₯Ό λͺ ννκ² μΈμν μ μλλ‘ ν©λλ€.
- νΈλ¦¬κ±° λ°©μ: ν΄λ¦ λλ νΈλ²(λ§μ°μ€ μ€λ²)μ κ°μ μ¬μ©μ νλμ λ°λΌ λ©λ΄κ° νμ±νλλλ‘ μ€κ³ν©λλ€. ν°μΉ κΈ°λ° λλ°μ΄μ€μμλ ν΄λ¦ μ΄λ²€νΈλ₯Ό μ£Όλ‘ μ¬μ©ν©λλ€.
- λ μ΄μμκ³Ό μμΉ: λ©λ΄κ° νλ©΄μμ λ²μ΄λμ§ μκ³ , μ¬μ©μμκ² μ½κ² μ κ·Ό κ°λ₯ν μμΉμ λ°°μΉλλλ‘ ν©λλ€.
- λͺ¨λ°μΌ νκ²½ κ³ λ €: λͺ¨λ°μΌμμλ ν°μΉ μμμ λκ² μ‘κ³ , λλ‘λ€μ΄ λ©λ΄μ λμ΄μ μ€ν¬λ‘€ κΈ°λ₯μ μ μ ν μ μ©νμ¬ μ¬μ©μ±μ 보μ₯ν©λλ€.
ꡬν μ λ΅ λ° μ£Όμ κΈ°μ μμ
λ°μν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄λ₯Ό ꡬννκΈ° μν΄μλ HTML, CSS, κ·Έλ¦¬κ³ μλ°μ€ν¬λ¦½νΈλ₯Ό μ‘°ν©ν λ€μν κΈ°μ μ΄ νμν©λλ€. 리μ‘νΈμ CSS-in-JS, νΉμ CSS Modulesμ κ°μ κΈ°μ μ νμ©νλ©΄, μ»΄ν¬λνΈ λ¨μλ‘ UIλ₯Ό λͺ¨λννμ¬ μ¬μ¬μ©μ±μ λμΌ μ μμ΅λλ€.
1. λ μ΄μμκ³Ό λ°μν λμμΈ
- λ―Έλμ΄ μΏΌλ¦¬: CSS λ―Έλμ΄ μΏΌλ¦¬λ₯Ό μ¬μ©νμ¬, νλ©΄ λλΉμ λ°λΌ λ€λΉκ²μ΄μ λ°μ λ μ΄μμμ λμ μΌλ‘ λ³κ²½ν©λλ€. μλ₯Ό λ€μ΄, λ°μ€ν¬νμμλ μ 체 λ©λ΄λ₯Ό κ°λ‘λ‘ λ°°μΉνκ³ , λͺ¨λ°μΌμμλ νλ²κ±° λ©λ΄ μμ΄μ½μ 보μ¬μ£Όλ λ°©μμ λλ€.
- Flexboxμ Grid: Flexbox λλ CSS Gridλ₯Ό μ¬μ©νμ¬, λ©λ΄ νλͺ©λ€μ΄ κ· λ±νκ² λ°°μΉλκ³ , μ¬λ°±κ³Ό μ λ ¬μ΄ μΌκ΄λλλ‘ κ΅¬νν©λλ€.
2. λλ‘λ€μ΄ λ©λ΄ μΈν°λμ
- μ λλ©μ΄μ κ³Ό μ ν ν¨κ³Ό: CSS transitionμ΄λ μ λλ©μ΄μ μ μ μ©νμ¬ λλ‘λ€μ΄ λ©λ΄κ° λΆλλ½κ² νΌμ³μ§λλ‘ ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ¬μ©μμκ² μκ°μ νΌλλ°±μ μ 곡ν©λλ€.
- μλ°μ€ν¬λ¦½νΈ μ΄λ²€νΈ νΈλ€λ§: ν΄λ¦, νΈλ² λ± μ¬μ©μ μ΄λ²€νΈλ₯Ό κ°μ§νμ¬ λ©λ΄μ νμ μνλ₯Ό ν κΈν©λλ€. 리μ‘νΈμμλ useStateμ useEffectλ₯Ό νμ©νμ¬ μν λ³νλ₯Ό κ΄λ¦¬ν μ μμ΅λλ€.
- μ κ·Όμ± κ°ν: ARIA μμ±μ μΆκ°νμ¬, μ€ν¬λ¦° 리λκ° λ©λ΄μ μνλ₯Ό μΈμν μ μλλ‘ νκ³ , ν€λ³΄λ λ΄λΉκ²μ΄μ μ μ§μν©λλ€.
μ½λ μμ : 리μ‘νΈ κΈ°λ° λ°μν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄
μλλ 리μ‘νΈλ₯Ό νμ©ν κ°λ¨ν λ°μν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄ μ»΄ν¬λνΈ κ΅¬ν μμ μ λλ€. μ΄ μμ μμλ useStateλ₯Ό μ¬μ©νμ¬ λ©λ΄μ μ΄λ¦Ό/λ«ν μνλ₯Ό κ΄λ¦¬νλ©°, CSS-in-JS κΈ°λ²(Styled Components)μ νμ©νμ¬ μ€νμΌμ μ μ©ν©λλ€.
// NavBar.jsx
import React, { useState } from 'react';
import styled from 'styled-components';
// λ€λΉκ²μ΄μ
λ° μ»¨ν
μ΄λ μ€νμΌ
const NavContainer = styled.nav`
background-color: #333;
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
`;
// λ‘κ³ μ€νμΌ
const Logo = styled.div`
color: #fff;
font-size: 1.5rem;
font-weight: bold;
`;
// λ©λ΄ 리μ€νΈ μ€νμΌ
const MenuList = styled.ul`
list-style: none;
display: flex;
align-items: center;
@media (max-width: 768px) {
display: ${props => (props.open ? 'block' : 'none')};
position: absolute;
top: 60px;
left: 0;
width: 100%;
background-color: #333;
padding: 10px 0;
}
`;
// λ©λ΄ νλͺ© μ€νμΌ
const MenuItem = styled.li`
margin: 0 15px;
position: relative;
@media (max-width: 768px) {
margin: 10px 0;
text-align: center;
}
`;
// λ©λ΄ λ§ν¬ μ€νμΌ
const MenuLink = styled.a`
color: #fff;
text-decoration: none;
cursor: pointer;
&:hover {
color: #ddd;
}
`;
// λλ‘λ€μ΄ λ©λ΄ μ€νμΌ
const DropdownMenu = styled.ul`
position: absolute;
top: 35px;
left: 0;
background-color: #444;
list-style: none;
padding: 10px 0;
min-width: 150px;
display: ${props => (props.open ? 'block' : 'none')};
z-index: 1000;
@media (max-width: 768px) {
position: static;
}
`;
const DropdownItem = styled.li`
padding: 8px 15px;
&:hover {
background-color: #555;
}
`;
const Hamburger = styled.div`
display: none;
flex-direction: column;
cursor: pointer;
span {
height: 3px;
width: 25px;
background: #fff;
margin: 4px 0;
transition: 0.4s;
}
@media (max-width: 768px) {
display: flex;
}
`;
const NavBar = () => {
const [menuOpen, setMenuOpen] = useState(false);
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggleMenu = () => {
setMenuOpen(prev => !prev);
};
const toggleDropdown = () => {
setDropdownOpen(prev => !prev);
};
return (
<NavContainer>
<Logo>MySite</Logo>
<Hamburger onClick={toggleMenu}>
<span />
<span />
<span />
</Hamburger>
<MenuList open={menuOpen}>
<MenuItem>
<MenuLink href="#home">Home</MenuLink>
</MenuItem>
<MenuItem>
<MenuLink href="#about">About</MenuLink>
</MenuItem>
<MenuItem onClick={toggleDropdown}>
<MenuLink as="div">Services βΎ</MenuLink>
<DropdownMenu open={dropdownOpen}>
<DropdownItem>
<MenuLink href="#design">Design</MenuLink>
</DropdownItem>
<DropdownItem>
<MenuLink href="#development">Development</MenuLink>
</DropdownItem>
<DropdownItem>
<MenuLink href="#marketing">Marketing</MenuLink>
</DropdownItem>
</DropdownMenu>
</MenuItem>
<MenuItem>
<MenuLink href="#contact">Contact</MenuLink>
</MenuItem>
</MenuList>
</NavContainer>
);
};
export default NavBar;
μ½λ μ€λͺ
- λ°μν λμμΈ μ μ©: λ―Έλμ΄ μΏΌλ¦¬λ₯Ό ν΅ν΄ νλ©΄ λλΉκ° 768px μ΄νμΌ κ²½μ°, λ©λ΄ 리μ€νΈλ κΈ°λ³Έμ μΌλ‘ μ¨κΉ μ²λ¦¬λλ©°, νλ²κ±° λ©λ΄κ° νμ±νλ©λλ€. μ¬μ©μκ° νλ²κ±° λ©λ΄λ₯Ό ν΄λ¦νλ©΄ λ©λ΄ 리μ€νΈκ° νΌμ³μ§λλ€.
- λλ‘λ€μ΄ λ©λ΄ ꡬν: "Services" λ©λ΄ νλͺ©μ ν΄λ¦ μ λλ‘λ€μ΄ λ©λ΄κ° ν κΈλ©λλ€. λλ‘λ€μ΄ λ©λ΄λ λ°μ€ν¬ν νκ²½μμλ μ λ μμΉλ₯Ό μ¬μ©ν΄ νμλκ³ , λͺ¨λ°μΌ νκ²½μμλ λ©λ΄ 리μ€νΈμ ν¬ν¨λμ΄ μμ°μ€λ½κ² 보μ¬μ§λλ€.
- μ€νμΌ μΊ‘μν: Styled Componentsλ₯Ό μ¬μ©νμ¬ κ° μ»΄ν¬λνΈλ³ μ€νμΌμ λͺ¨λννμμΌλ©°, μ΄λ₯Ό ν΅ν΄ ν΄λμ€ λ€μ μΆ©λ μμ΄ μ μ§λ³΄μμ±μ΄ λμ μ½λλ₯Ό μμ±νμμ΅λλ€.
μ κ·Όμ±κ³Ό μ±λ₯ μ΅μ ν κ³ λ € μ¬ν
- ν€λ³΄λ λ΄λΉκ²μ΄μ μ§μ: λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄μ ν€λ³΄λ μ΄λ²€νΈ(μ: Tab, Enter)λ₯Ό μΆκ°νμ¬, ν€λ³΄λ μ¬μ©μκ° μμ½κ² λ©λ΄λ₯Ό νμν μ μλλ‘ κ°μ ν μ μμ΅λλ€.
- ARIA μμ± μ μ©: λλ‘λ€μ΄ λ©λ΄μ aria-expanded λ° aria-haspopup λ±μ μμ±μ μΆκ°νμ¬, μ€ν¬λ¦° 리λ μ¬μ©μκ° λ©λ΄μ μνλ₯Ό λͺ ννκ² μΈμν μ μλλ‘ ν©λλ€.
- μ λλ©μ΄μ μ΅μ ν: λ©λ΄ ν κΈ μ CSS transitionμ νμ©νμ¬ λΆλλ¬μ΄ μ ν ν¨κ³Όλ₯Ό μ μ©νλ©΄ μ¬μ©μ κ²½νμ΄ κ°μ λλ©°, κ³Όλν μ λλ©μ΄μ μ μ±λ₯ μ νλ₯Ό μ λ°ν μ μμΌλ―λ‘ μ μ ν λ°Έλ°μ€λ₯Ό μ μ§ν΄μΌ ν©λλ€.
κ²°λ‘
λ°μν λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄λ λ€μν λλ°μ΄μ€ νκ²½μμ μΌκ΄λ μ¬μ©μ κ²½νμ μ 곡νλ ν΅μ¬ UI μμμ λλ€. μ΄λ² ν¬μ€ν μμλ λ―Έλμ΄ μΏΌλ¦¬, Flexbox, CSS-in-JS λ± μ΅μ μΉ κΈ°μ μ νμ©νμ¬, λ°μν μΉ λμμΈμ μ΅μ νλ λ€λΉκ²μ΄μ λ°μ λλ‘λ€μ΄ λ©λ΄λ₯Ό ꡬννλ λ°©λ²μ μ΄ν΄λ³΄μμ΅λλ€. μ€μ΅ μμ μ ν¨κ» κ° μ»΄ν¬λνΈμ μν κ³Ό μ€νμΌλ§ μ λ΅μ μμΈν μ€λͺ νμμΌλ©°, μ κ·Όμ± λ° μ±λ₯ μ΅μ ν μΈ‘λ©΄μμλ κ³ λ €ν΄μΌ ν μ¬νλ€μ ν¨κ» λ Όμνμμ΅λλ€.
μ΄μ κ°μ΄ λͺ¨λνλ μ»΄ν¬λνΈ μ€κ³μ λ°μν UI ꡬνμ μ μ§λ³΄μμ±κ³Ό νμ₯μ±μ΄ λ°μ΄λ μΉ μ ν리μΌμ΄μ κ°λ°μ ν° λμμ΄ λ©λλ€. μμΌλ‘ νλ‘μ νΈμ μ μ©ν λλ, ν λ΄ νμ κ³Ό μ¬μ©μ νΌλλ°±μ μ κ·Ή λ°μνμ¬ μ§μμ μΌλ‘ κ°μ ν΄ λκ°μκΈΈ λ°λλλ€.
λκΈ