๐ŸŽจ styled-components ์‚ฌ์šฉ์˜ ์žฅ์  โ€“ ์ „์ฒด ํ”„๋กœ์ ํŠธ์—์„œ ํšจ์œจ์ ์ธ ์Šคํƒ€์ผ๋ง

์กฐ์ค€ํ˜•ยท2025๋…„ 3์›” 21์ผ
0

CHOP!

๋ชฉ๋ก ๋ณด๊ธฐ
3/20
post-thumbnail

๐Ÿ” ์™œ styled-components๋ฅผ ์„ ํƒํ–ˆ๋‚˜?

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ styled-components๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” CSS์™€ JS๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๋” ํšจ์œจ์ ์ธ ์ฝ”๋“œ ๊ด€๋ฆฌ์™€ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์ด๋ฃจ๊ธฐ ์œ„ํ•ด์„œ์˜€๋‹ค. ์ฝ”๋“œ๊ฐ€ ์ ์  ์ปค์ง€๊ณ  ๋ณต์žกํ•ด์ง์— ๋”ฐ๋ผ ์ปดํฌ๋„ŒํŠธํ™”๋œ ์Šคํƒ€์ผ๋ง์ด ํ•„์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์Šคํƒ€์ผ๊ณผ ๊ตฌ์กฐ๊ฐ€ ๋ถ„๋ฆฌ๋œ ์ „ํ†ต์ ์ธ ๋ฐฉ์‹์—์„œ ๋ฒ—์–ด๋‚˜, ๊ฐ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ์ง์ ‘ ์Šคํƒ€์ผ์„ ๊ด€๋ฆฌํ•˜๋ฉด ๋” ์ง๊ด€์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ด์ง„๋‹ค.

๐Ÿ’ป styled-components๋ฅผ ํ™œ์šฉํ•œ ์ฝ”๋“œ ์˜ˆ์‹œ: BottomNav

๋จผ์ €, BottomNav ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž. ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ”์— ๊ฐ ์•„์ด์ฝ˜์˜ ํ™œ์„ฑํ™” ์ƒํƒœ์— ๋”ฐ๋ผ ๋™์  ์Šคํƒ€์ผ์„ ์ ์šฉํ–ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ styled-components๋ฅผ ํ™œ์šฉํ•ด ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์„ ์ •์˜ํ•˜๊ณ  ์ ์šฉํ–ˆ๋‹ค:

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';

import home from '../../assets/home.png';
import community from '../../assets/community.png';
import sell from '../../assets/sell.png';
import chatting from '../../assets/chatting.png';
import profile from '../../assets/profile.png';

const Wrapper = styled.nav`
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    max-height: 5%;
    height: 5%;
    overflow: hidden;
    border-top: 3px solid grey;
    padding-top: 5%;
    padding-bottom: 2%;
    display: flex;
    justify-content: space-between;
`;

const NavLink = styled(Link)`
    text-align: center;
    width: 20%;
    height: 30%;
    display: flex;
    justify-content: center;
    align-items: center;
`;

interface NavItemProps {
    isActive: boolean;
}

const NavItem = styled.img<NavItemProps>`
    width: 30%;
    height: auto;
    filter: ${({ isActive }) => (isActive ? 'grayscale(0%) brightness(0.4)' : 'grayscale(100%) brightness(1)')};
    transition: filter 0.3s;
`;


const BottomNav: React.FC = () => {
    const [activeNav, setActiveNav] = useState<number>(1);

    return (
        <Wrapper>
            <NavLink to="/home" onClick={() => setActiveNav(1)}>
                <NavItem src={home} isActive={activeNav === 1} />
            </NavLink>
            <NavLink to="/community" onClick={() => setActiveNav(2)}>
                <NavItem src={community} isActive={activeNav === 2} />
            </NavLink>
            <NavLink to="/sell" onClick={() => setActiveNav(3)}>
                <NavItem src={sell} isActive={activeNav === 3} />
            </NavLink>
            <NavLink to="/chatting" onClick={() => setActiveNav(4)}>
                <NavItem src={chatting} isActive={activeNav === 4} />
            </NavLink>
            <NavLink to="/profile" onClick={() => setActiveNav(5)}>
                <NavItem src={profile} isActive={activeNav === 5} />
            </NavLink>
        </Wrapper>
    );
};

export default BottomNav;

โœจ styled-components์˜ ์žฅ์ 

styled-components๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žฅ์ ์„ ์ œ๊ณตํ•œ๋‹ค. ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ด์ ์„ ์ตœ๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  • ์ปดํฌ๋„ŒํŠธํ™”๋œ ์Šคํƒ€์ผ๋ง

์Šคํƒ€์ผ๊ณผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ๋ฐฉ์‹์„ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์ง๊ด€์„ฑ์ด ๋†’์•„์กŒ๋‹ค. ๊ฐ UI ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์— ์ •์˜ํ•˜๋ฏ€๋กœ, ํ•œ ํŒŒ์ผ์—์„œ ์Šคํƒ€์ผ๊ณผ ๋กœ์ง์„ ๋ชจ๋‘ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋†’์•„์กŒ๊ณ , ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์›Œ์กŒ๋‹ค.

  • ๋™์  ์Šคํƒ€์ผ๋ง

styled-components๋Š” props๋ฅผ ํ†ตํ•œ ๋™์  ์Šคํƒ€์ผ๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, NavItem ์ปดํฌ๋„ŒํŠธ๋Š” isActive๋ผ๋Š” props๋ฅผ ๋ฐ›์•„์„œ, ์•„์ด์ฝ˜์˜ ํ™œ์„ฑํ™” ์ƒํƒœ์— ๋”ฐ๋ผ grayscale๊ณผ brightness๋ฅผ ์กฐ์ •ํ–ˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์ฆ‰๊ฐ์ ์œผ๋กœ ์Šคํƒ€์ผ์„ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  • ์ฝ”๋“œ ์ค‘๋ณต ์ตœ์†Œํ™”

์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฝ”๋“œ ์ค‘๋ณต์„ ์ตœ์†Œํ™”ํ–ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, NavLink์™€ NavItem ๊ฐ™์€ ๊ณตํ†ต์ ์ธ ์Šคํƒ€์ผ์€ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ์ •์˜ํ•˜์—ฌ ๋‹ค๋ฅธ ๋„ค๋น„๊ฒŒ์ด์…˜ ํ•ญ๋ชฉ์—๋„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋•๋ถ„์— ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ , ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•  ๋•Œ ํ•œ ๊ณณ๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ด์กŒ๋‹ค.

  • CSS ํด๋ž˜์Šค ๋„ค์ด๋ฐ ์ถฉ๋Œ ๋ฐฉ์ง€

styled-components๋Š” ๊ณ ์œ ํ•œ ํด๋ž˜์Šค๋ช…์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค. ๋”ฐ๋ผ์„œ CSS ํด๋ž˜์Šค ๋„ค์ด๋ฐ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ถฉ๋Œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ ๊ฒน์น˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ–ˆ๋‹ค.

  • ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ

์Šคํƒ€์ผ์ด ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด๊ณ  ์Šคํƒ€์ผ์„ ์ฆ‰์‹œ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํ˜‘์—… ํ™˜๊ฒฝ์—์„œ ๊ฐ€๋…์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค๊ณ , ์ดํ•ด๋„๋ฅผ ๋†’์ด๋Š” ๋ฐ ๊ธฐ์—ฌํ•œ๋‹ค.

๐Ÿ”„ ์ง€๊ธˆ ์ƒ๊ฐํ–ˆ์„ ๋•Œ ๊ฐœ์„ ํ•  ์ 

์Šคํƒ€์ผ ์žฌ์‚ฌ์šฉ์„ฑ: ์ฝ”๋“œ ์ค‘๋ณต์„ ์ค„์˜€์ง€๋งŒ, ์•„์ง ๋ช‡๋ช‡ ์Šคํƒ€์ผ์„ ์ƒ์ˆ˜ํ™”ํ•˜์—ฌ ์ „์—ญ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์ด ๋ถ€์กฑํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„์ด์ฝ˜ ํฌ๊ธฐ๋‚˜ ์ƒ‰์ƒ, ๊ธ€์ž ํฌ๊ธฐ๋“ฑ์„ ์ƒ์ˆ˜๋กœ ์ •์˜ํ•ด๋‘๋ฉด ๋” ํšจ์œจ์ ์ผ ๊ฒƒ์ด๋‹ค.

โšก ๊ฒฐ๋ก 

์ „์ฒด ํ”„๋กœ์ ํŠธ์—์„œ styled-components๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ด์กŒ๋‹ค. ์ปดํฌ๋„ŒํŠธํ™”๋œ ์Šคํƒ€์ผ๋ง๊ณผ ๋™์  ์Šคํƒ€์ผ ์ ์šฉ ๋•๋ถ„์— ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๋„ ํ–ฅ์ƒ๋˜์—ˆ์œผ๋ฉฐ, UI ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๊ฐ„ํŽธํ•˜๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์•ž์œผ๋กœ๋„ ์ด ๋ฐฉ์‹์„ ํ™œ์šฉํ•ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋“ค์—๋„ ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉํ•˜๊ณ , ๋” ํšจ์œจ์ ์ธ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚˜๊ฐˆ ๊ฒƒ์ด๋‹ค.

profile
์ฝ”๋ฆฐ์ด

0๊ฐœ์˜ ๋Œ“๊ธ€