λ°μν λμμΈμ μν 리μ‘νΈ κ·Έλ¦¬λ μμ€ν ꡬν
νλ μΉ κ°λ°μμλ λ€μν λλ°μ΄μ€ νκ²½μμ μΌκ΄λ μ¬μ©μ κ²½νμ μ 곡νλ κ²μ΄ λ§€μ° μ€μν©λλ€. μ΄μ λ°λΌ λ°μν λμμΈμ νμ μμλ‘ μ리 μ‘μμΌλ©°, 리μ‘νΈ μ»΄ν¬λνΈλ₯Ό νμ©νμ¬ λ°μν 그리λ μμ€ν μ ꡬννλ©΄ μ μ§λ³΄μμ νμ₯μ±μ΄ λ°μ΄λ UIλ₯Ό ꡬμ±ν μ μμ΅λλ€. λ³Έ ν¬μ€ν μμλ λ―Έλμ΄ μΏΌλ¦¬μ CSS-in-JS κΈ°λ², μ΅μ Flexbox λ° Grid Layout κΈ°μ μ μ λͺ©νμ¬ λ€μν λλ°μ΄μ€μμ μ μ°νκ² λμνλ λ°μν 그리λ μμ€ν μ λ§λλ λ°©λ²μ λν΄ μμΈν λ€λ£¨κ³ μ ν©λλ€.
리μ‘νΈμ λ°μν λμμΈμ μ΄ν΄
리μ‘νΈλ μ»΄ν¬λνΈ κΈ°λ° μν€ν μ²λ₯Ό μ±ννμ¬ UI κ΅¬μ± μμλ€μ λͺ¨λννκ³ μ¬μ¬μ©ν μ μλλ‘ λμ΅λλ€. μ΄λ¬ν νΉμ±μ λ°μν λμμΈμ ꡬνν λ ν° μ₯μ μΌλ‘ μμ©ν©λλ€. μ»΄ν¬λνΈλ₯Ό μ€μ¬μΌλ‘ 그리λ μμ€ν μ μ€κ³νλ©΄, κ°κ°μ μ»΄ν¬λνΈκ° λ 립μ μΌλ‘ μ€νμΌλ§λκ³ , λ€μν νλ©΄ ν¬κΈ°μ λ§μΆ° μλμΌλ‘ μ¬λ°°μΉλ μ μμ΅λλ€.
λ°μν λμμΈμ κΈ°λ³Έ μμΉμ "λͺ¨λ°μΌ νΌμ€νΈ" μ κ·Όλ²μ λ°λ₯΄λ κ²μ λλ€. κΈ°λ³Έμ μΌλ‘ μμ νλ©΄μ μν λ μ΄μμμ λ¨Όμ μ€κ³νκ³ , μ΄ν λ―Έλμ΄ μΏΌλ¦¬λ₯Ό νμ©νμ¬ μ μ§μ μΌλ‘ ν° νλ©΄μ λ§λ μ€νμΌμ μ μ©νλ λ°©μμ λλ€. μ΄λ₯Ό ν΅ν΄ μ΄κΈ° λ‘λ© μλμ μ¬μ©μ κ²½νμ κ·Ήλνν μ μμ΅λλ€.
λ―Έλμ΄ μΏΌλ¦¬μ CSS-in-JS κΈ°λ²
λ―Έλμ΄ μΏΌλ¦¬λ CSSμμ μ 곡νλ κΈ°λ₯μΌλ‘, λ·°ν¬νΈμ ν¬κΈ°μ λ°λΌ μ€νμΌμ 쑰건λΆλ‘ μ μ©ν μ μλλ‘ ν©λλ€. μλ₯Ό λ€μ΄, νλ©΄μ λλΉκ° μΌμ ν¬κΈ° μ΄μμΌ λ λ€λ₯Έ λ μ΄μμμ΄λ ν°νΈ ν¬κΈ°λ₯Ό μ μ©νλ μμΌλ‘ λ°μν λμμΈμ ꡬνν μ μμ΅λλ€. 리μ‘νΈ νλ‘μ νΈμμλ μ ν΅μ μΈ CSS νμΌλΏλ§ μλλΌ, CSS-in-JS κΈ°λ²μ νμ©νμ¬ μ»΄ν¬λνΈ λ΄λΆμμ λμ μΌλ‘ μ€νμΌμ μ μ©νλ λ°©λ²λ μΈκΈ°λ₯Ό λκ³ μμ΅λλ€.
CSS-in-JS λΌμ΄λΈλ¬λ¦¬μΈ Styled Componentsλ Emotionμ μ¬μ©νλ©΄, μλ°μ€ν¬λ¦½νΈ λ³μμ λ Όλ¦¬λ₯Ό κΈ°λ°μΌλ‘ μ‘°κ±΄λΆ μ€νμΌλ§μ ꡬνν μ μμ΄ μ½λμ κ°λ μ±κ³Ό μ μ§λ³΄μμ±μ΄ ν₯μλ©λλ€. λν, μ΄λ¬ν λ°©μμ μ»΄ν¬λνΈ λ¨μλ‘ μ€νμΌμ΄ μΊ‘μνλκΈ° λλ¬Έμ, λ€λ₯Έ μ»΄ν¬λνΈμμ μΆ©λ μμ΄ μμ μ μΈ UIλ₯Ό ꡬμ±ν μ μμ΅λλ€.
μμ μ½λ (Styled Components μ¬μ©):
import styled from 'styled-components';
const GridContainer = styled.div`
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-gap: 16px;
padding: 16px;
@media (min-width: 600px) {
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 900px) {
grid-template-columns: repeat(4, 1fr);
}
`;
const GridItem = styled.div`
background-color: #f5f5f5;
padding: 24px;
border-radius: 8px;
text-align: center;
`;
μ μ½λλ κΈ°λ³Έμ μΌλ‘ νλμ μ΄λ‘ ꡬμ±λ 그리λ λ μ΄μμμ μ€μ ν λ€, νλ©΄ λλΉκ° 600px μ΄μμ΄λ©΄ 2μ΄, 900px μ΄μμ΄λ©΄ 4μ΄ λ μ΄μμμΌλ‘ λ³κ²½νλ μμ μ λλ€. μ΄μ²λΌ λ―Έλμ΄ μΏΌλ¦¬λ₯Ό νμ©νλ©΄ λ€μν λλ°μ΄μ€μ λ§μΆ λ μ΄μμμ μ½κ² ꡬνν μ μμ΅λλ€.
Flexboxμ Grid Layout: μ΅μ κΈ°μ μ λΉκ΅μ νμ©
Flexbox
Flexboxλ 1μ°¨μ λ μ΄μμ μμ€ν μΌλ‘, μ£Όλ‘ νμ΄λ μ΄ λ¨μμ μ λ ¬ λ° λΆλ°°μ μ΅μ νλμ΄ μμ΅λλ€. Flexboxλ₯Ό νμ©νλ©΄, μ»΄ν¬λνΈλ€μ΄ κ°λ³μ μΈ ν¬κΈ°λ₯Ό κ°μ§λ©° κ· λ±νκ² κ³΅κ°μ μ°¨μ§ν μ μλλ‘ μ½κ² μ‘°μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λ΄λΉκ²μ΄μ λ°λ λ²νΌ κ·Έλ£Ή κ°μ κ²½μ°μλ Flexboxκ° λ§€μ° μ μ©ν©λλ€.
Flexboxμ μ£Όμ μμ±:
- display: flex;
- justify-contentμ align-itemsλ₯Ό ν΅ν μ λ ¬
- flex-grow, flex-shrink, flex-basisλ₯Ό ν΅ν μ μ°ν ν¬κΈ° μ‘°μ
Grid Layout
Grid Layoutμ 2μ°¨μ λ μ΄μμ μμ€ν μΌλ‘, νκ³Ό μ΄μ λμμ μ μ΄ν μ μμ΄ λ³΅μ‘ν λ μ΄μμ μ€κ³μ νμν©λλ€. 그리λ μμ€ν μ μ΄μ©νλ©΄, μΉ νμ΄μ§μ μ 체μ μΈ λ μ΄μμλΆν° μμ μΉ΄λ νμμ μ»΄ν¬λνΈ λ°°μ΄κΉμ§ λ€μν ννμ λ μ΄μμμ ꡬμ±ν μ μμ΅λλ€.
Grid Layoutμ μ£Όμ μμ±:
- display: grid;
- grid-template-columnsμ grid-template-rowsλ₯Ό ν΅ν νκ³Ό μ΄ κ΅¬μ±
- grid-gapμ΄λ gapμ ν΅ν κ°κ²© μ€μ
- grid-areaλ₯Ό νμ©ν μμ μ§μ
λ κΈ°μ μ κ°κ°μ μ₯μ μ΄ μμΌλ―λ‘, μν©μ λ°λΌ μ μ νκ² μ ννκ±°λ ν¨κ» μ¬μ©ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ 체 λ μ΄μμμ Grid LayoutμΌλ‘ ꡬμ±νκ³ , λ΄λΆ μμμ μΈλΆ μ λ ¬μ Flexboxλ‘ μ‘°μ νλ λ°©μμΌλ‘ νμ©ν μ μμ΅λλ€.
리μ‘νΈ κ·Έλ¦¬λ μμ€ν ꡬν μμ
μλμμλ 리μ‘νΈ μ»΄ν¬λνΈλ₯Ό νμ©νμ¬ λ°μν 그리λ μμ€ν μ ꡬννλ μ€μ μμ λ₯Ό μκ°ν©λλ€. μ΄ μμ λ κΈ°λ³Έμ μΈ κ·Έλ¦¬λ λ μ΄μμμ μ 곡νλ©°, λ€μν νλ©΄ ν¬κΈ°μ λ°λΌ μλμΌλ‘ μ»¬λΌ μκ° μ‘°μ λ©λλ€.
import React from 'react';
import styled from 'styled-components';
const GridContainer = styled.div`
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-gap: 16px;
padding: 16px;
box-sizing: border-box;
@media (min-width: 600px) {
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 900px) {
grid-template-columns: repeat(4, 1fr);
}
`;
const GridItem = styled.div`
background-color: #e0e0e0;
padding: 20px;
border-radius: 10px;
font-size: 1.2rem;
text-align: center;
transition: background-color 0.3s ease;
&:hover {
background-color: #c0c0c0;
}
`;
const ResponsiveGrid = () => {
const items = Array.from({ length: 12 }, (_, i) => `μμ΄ν
${i + 1}`);
return (
<GridContainer>
{items.map((item, index) => (
<GridItem key={index}>{item}</GridItem>
))}
</GridContainer>
);
};
export default ResponsiveGrid;
μ½λ μ€λͺ
- GridContainer μ»΄ν¬λνΈ
- display: grid;λ₯Ό ν΅ν΄ 그리λ λ μ΄μμμ μ μ©ν©λλ€.
- grid-template-columns: repeat(1, 1fr);λ κΈ°λ³Έμ μΌλ‘ ν μ€μ νλμ μμ΄ν μ λ°°μΉν©λλ€.
- λ―Έλμ΄ μΏΌλ¦¬λ₯Ό μ¬μ©νμ¬ νλ©΄ λλΉκ° 600px μ΄μμΌ λ 2μ΄, 900px μ΄μμΌ λ 4μ΄λ‘ λ³κ²½λ©λλ€.
- grid-gapκ³Ό paddingμ μ¬μ©ν΄ κ° κ·Έλ¦¬λ μμ΄ν μ¬μ΄μ μΌμ ν κ°κ²©κ³Ό μ¬λ°±μ λΆμ¬ν©λλ€.
- GridItem μ»΄ν¬λνΈ
- κ° μμ΄ν μ λ°°κ²½μ, ν¨λ©, ν λ리 λ°κ²½ λ±μ μ μ©λ°μ μ¬λ―Έμ μΌλ‘ ꡬμ±λ©λλ€.
- transition μμ±μ ν΅ν΄ λ§μ°μ€ μ€λ² μ λΆλλ¬μ΄ λ°°κ²½μ λ³νλ₯Ό ꡬνν©λλ€.
- ResponsiveGrid μ»΄ν¬λνΈ
- λ°°μ΄μ μμ±νμ¬ 12κ°μ μμ΄ν μ λμ μΌλ‘ λ λλ§ν©λλ€.
- 그리λ μμ€ν μ ν΅ν΄ μμ΄ν λ€μ΄ μλμΌλ‘ λ°°μΉλλ©°, λ€μν λλ°μ΄μ€ νκ²½μ λ§μΆ° λ μ΄μμμ΄ λ³νλ©λλ€.
μ΄μ κ°μ΄ 리μ‘νΈμ Styled Componentsλ₯Ό νμ©νλ©΄, μ½λμ μ¬μ¬μ©μ±κ³Ό μ μ§λ³΄μμ±μ λμ΄λ©΄μλ λ€μν λλ°μ΄μ€ νκ²½μμ μ΅μ νλ λ°μν UIλ₯Ό ꡬνν μ μμ΅λλ€.
μ±λ₯ μ΅μ ν λ° μ κ·Όμ± κ³ λ €μ¬ν
λ°μν 그리λ μμ€ν μ ꡬνν λλ λ¨μν λ μ΄μμμλ§ μ§μ€ν κ²μ΄ μλλΌ μ±λ₯κ³Ό μ κ·Όμ±λ ν¨κ» κ³ λ €ν΄μΌ ν©λλ€. μλλ λͺ κ°μ§ κ³ λ €μ¬νμ λλ€.
μ±λ₯ μ΅μ ν
- μ½λ μ€ν리ν : 리μ‘νΈμ lazyμ Suspenseλ₯Ό νμ©νμ¬ κ·Έλ¦¬λ μ»΄ν¬λνΈλ₯Ό νμν μμ μ λ‘λ©ν¨μΌλ‘μ¨ μ΄κΈ° λ‘λ© μλλ₯Ό κ°μ ν μ μμ΅λλ€.
- μ΅μνμ 리λ λλ§: 그리λ μμ€ν λ΄μ κ° μμ΄ν μ λΆνμν 리λ λλ§μ λ°©μ§νκΈ° μν΄ React.memo λ±μ νμ©νμ¬ μ΅μ νν μ μμ΅λλ€.
- μ΄λ―Έμ§ μ΅μ ν: 그리λ λ΄μ μ΄λ―Έμ§κ° ν¬ν¨λλ€λ©΄, μ΄λ―Έμ§μ μ¬μ΄μ¦ μ΅μ νμ μ§μ° λ‘λ©(lazy loading)μ μ μ©νμ¬ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
μ κ·Όμ±
- ν€λ³΄λ λ΄λΉκ²μ΄μ : κ° κ·Έλ¦¬λ μμ΄ν μ tabIndexλ₯Ό λΆμ¬νμ¬ ν€λ³΄λ μ¬μ©μκ° μ½κ² μ κ·Όν μ μλλ‘ κ΅¬μ±ν©λλ€.
- μ€ν¬λ¦° 리λ μ§μ: ARIA μμ±μ νμ©νμ¬ κ° μ»΄ν¬λνΈκ° μλ―Έ μλ μν μ λΆμ¬λ°λλ‘ νλ©°, μ€ν¬λ¦° 리λ μ¬μ©μκ° μ½ν μΈ λ₯Ό λͺ ννκ² μ΄ν΄ν μ μλλ‘ ν©λλ€.
- λ°μν λμμΈμ μΌκ΄μ±: λ€μν λλ°μ΄μ€μμ λμΌν μ κ·Όμ±μ 보μ₯νκΈ° μν΄ λ μ΄μμμ΄ νλ©΄ ν¬κΈ°μ λ°λΌ μΌκ΄λκ² λ³ννλλ‘ μ£Όμν©λλ€.
μ€λ¬΄ μ μ© λ° κ²°λ‘
νλ μΉ μ ν리μΌμ΄μ μ λ€μν νκ²½μμμ μ΅μ νλ μ¬μ©μ κ²½νμ΄ μꡬλ©λλ€. 리μ‘νΈλ₯Ό νμ©ν λ°μν 그리λ μμ€ν ꡬνμ κ°λ°μκ° ν¨μ¨μ μΌλ‘ UIλ₯Ό ꡬμ±ν μ μλ κ°λ ₯ν λꡬμ λλ€. λ―Έλμ΄ μΏΌλ¦¬, CSS-in-JS, Flexbox, κ·Έλ¦¬κ³ Grid Layoutμ μ μ ν νμ©νλ©΄, μ μ§λ³΄μκ° μ©μ΄νκ³ νμ₯ κ°λ₯ν UI μ»΄ν¬λνΈλ₯Ό ꡬνν μ μμ΅λλ€.
μ€μ νλ‘μ νΈμ λ°μν 그리λ μμ€ν μ μ μ©ν λλ μ¬μ©μ νλ λ°μ΄ν°λ₯Ό λΆμνμ¬ κ°μ₯ λΉλ²νκ² μ¬μ©λλ λλ°μ΄μ€ νκ²½μ νμ νκ³ , μ΄μ λ§μΆ° λ μ΄μμμ μ΅μ ννλ κ²μ΄ μ€μν©λλ€. λν, μ΅μ μΉ κΈ°μ λν₯μ μ§μμ μΌλ‘ λ°μνμ¬ κΈ°μ μ€νμ μ λ°μ΄νΈνκ³ , μ½λ 리뷰μ ν μ€νΈ μλν λ±μ ν΅ν΄ μμ μ μΈ μλΉμ€λ₯Ό μ 곡νλ κ²μ΄ νμν©λλ€.
λ³Έ ν¬μ€ν μμ μκ°ν ꡬν λ°©λ²κ³Ό μ½λ μμ λ μμμ μ λΆκ³Όν©λλ€. νλ‘μ νΈμ νΉμ±κ³Ό μꡬμ¬νμ λ§μΆμ΄ λ€μν 컀μ€ν°λ§μ΄μ§μ΄ κ°λ₯νλ©°, μ΄λ₯Ό ν΅ν΄ λ μ°½μ μΈ μ¬μ©μ κ²½νμ μ 곡ν μ μμ΅λλ€. μμΌλ‘λ 리μ‘νΈ μνκ³μμ μ 곡νλ λ€μν λꡬμ κΈ°μ μ μ κ·Ή νμ©νμ¬, λ³ννλ μΉ νΈλ λμ λ°λ§μΆ UI/UXλ₯Ό ꡬννμκΈΈ λ°λλλ€.
리μ‘νΈμ μ΅μ CSS κΈ°μ μ κ²°ν©ν λ°μν 그리λ μμ€ν ꡬνμ κ°λ°μμκ² μμ΄ λ§€μ° μ€μν μλμ΄λ©°, μ΄λ¬ν κΈ°μ λ€μ λ§μ€ν°νλ©΄ νλ‘μ νΈμ μ±κ³΅ νλ₯ μ ν¬κ² λμΌ μ μμ΅λλ€. μ€λ¬΄μμμ λ€μν μλ리μ€μ μ¬μ©μ νΌλλ°±μ λ°μνμ¬ μ§μμ μΌλ‘ κ°μ νκ³ , μ½λ μ΅μ νμ μ±λ₯ ν₯μμ μ κ²½ μ΄λ€λ©΄ μ¬μ©μμκ² λ λμ κ²½νμ μ 곡ν μ μμ κ²μ λλ€.
λκΈ