๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Dev/+@

๋ชจ๋ฐ”์ผ UI ๋””์ž์ธ ์‹œ์Šคํ…œ๊ณผ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ ์ ์šฉํ•˜๊ธฐ

by vellahw 2024. 1. 20.

๐Ÿ˜Œ

์š”์ฆ˜ ํœด๋Œ€ํฐ์˜ ํ™”๋ฉด๋น„์œจ์€ ์ •๋ง ๋‹ค์–‘ํ•˜๋‹ค.

๋ฏธ๋‹ˆ ์‚ฌ์ด์ฆˆ์˜ ์„ ํ˜ธ๋„๊ฐ€ ์ค„๊ณ  ํœด๋Œ€ํฐ์˜ ํ‰๊ท  ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์กŒ์–ด๋„ ์ž‘์€ ๊ธฐ์ข…์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์„ ์ˆ˜ ์—†๋‹ค.

์–ด๋–ค ๊ธฐ๊ธฐ๋Š” ์„ธ๋กœ ๊ธธ์ด๊ฐ€ 667px ์ •๋„๋กœ ์ž‘๊ณ , ์–ด๋–ค ๊ธฐ๊ธฐ๋Š” 882px ์ด์ƒ์œผ๋กœ ๊ฝค ํฌ๋‹ค.

๊ทธ๋ž˜์„œ ๋””์ž์ธ ์‹œ์•ˆ์„ ๋ฐ”ํƒ•์œผ๋กœ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์ด๋Ÿฐ ๊ณ ๋ฏผ์ด ์ƒ๊ธด๋‹ค.

UI ์š”์†Œ ํฌ๊ธฐ๋Š” ์ž‘์€ ํ™”๋ฉด ๊ธฐ์ค€์œผ๋กœ ํ•ด์•ผ ํ• ๊นŒ? ํฐ ํ™”๋ฉด ๊ธฐ์ค€์œผ๋กœ ํ•ด์•ผ ํ• ๊นŒ?
์ž‘์€ ์‚ฌ์ด์ฆˆ์—์„œ๋Š” ํŽ˜์ด์ง€ ๋””์ž์ธ์ด "์˜ˆ๋ป"๋ณด์ด๋Š”๋ฐ ํฐ ์‚ฌ์ด์ฆˆ์—์„œ๋Š” ์ ์ ˆํ•˜์ง€ ์•Š์•„๋ณด์ธ๋‹ค๋ฉด.. ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

 

๊ณ ๋ฏผ์„ ๋ฐ”ํƒ•์œผ๋กœ

  • ๋ชจ๋ฐ”์ผ UI๋ฅผ ๋””์ž์ด๋„ˆ ๊ด€์ ์—์„œ ์–ด๋–ป๊ฒŒ ์„ค๊ณ„ํ•˜๋Š”์ง€
  • ๊ทธ๋ฆฌ๊ณ  ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€

๋ฅผ ๊ฐ€๋ณ๊ฒŒ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค.


 

1. ๋ชจ๋ฐ”์ผ UI๋Š” ์–ด๋–ค ํ™”๋ฉด ๊ธฐ์ค€์œผ๋กœ ๋””์ž์ธํ• ๊นŒ?

์›น ๋””์ž์ธ์„ ๋ฐฐ์›Œ๋ณด์งˆ ์•Š์•˜์œผ๋‹ˆ ์ณ‡์ง€ํ”ผํ‹ฐ์—๊ฒŒ ๋ฌผ์–ด๋ณธ ๊ฒฐ๊ณผ

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜๋ฉด ๋ณดํ†ต ์ž‘์€ ํ™”๋ฉด ๊ธฐ์ค€์œผ๋กœ ์„ค๊ณ„ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

๊ทธ ์ด์œ ๋Š”

์ž‘์€ ํ™”๋ฉด์—์„œ UI๊ฐ€ ๊นจ์ง€๋ฉด ๋ณต๊ตฌ๊ฐ€ ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ 

ํฐ ํ™”๋ฉด์€ ์—ฌ๋ฐฑ์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ ํ™•์žฅ์œผ๋กœ ๋Œ€์‘ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

โœ… ๊ณ ์ •๋˜๋Š” UI

๋ฒ„ํŠผ ๋†’์ด, ํ„ฐ์น˜ ์˜์—ญ, ์•„์ด์ฝ˜ ์‚ฌ์ด์ฆˆ, ํ…์ŠคํŠธ ํฌ๊ธฐ ๋“ฑ

์‚ฌ์šฉ์„ฑ์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ์„ ์ฃผ๋Š” ์š”์†Œ๋Š” ๊ณ ์ •๋œ๋‹ค.

button height = 48px
icon = 24px
body text = 16px

 

โœ… ์œ ๋™์ ์œผ๋กœ ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ

์„น์…˜ ๊ฐ„๊ฒฉ, hero ์˜์—ญ, ์นด๋“œ ๊ฐ„๊ฒฉ, ์—ฌ๋ฐฑ ๋“ฑ

๋ ˆ์ด์•„์›ƒ ์š”์†Œ๋“ค์€ ๋ณดํ†ต ์œ ๋™์ ์œผ๋กœ ํ™•์žฅ๋œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ด๋Ÿฐ ์‹

// ์ž‘์€ ํ™”๋ฉด
section spacing = 24px
hero height = 220px

// ํฐ ํ™”๋ฉด
section spacing = 40px
hero height = 320px

 

ํ•ต์‹ฌ์€ ์ฝ˜ํ…์ธ ๋Š” ์œ ์ง€ํ•˜๊ณ  ์—ฌ๋ฐฑ์„ ํ™•์žฅํ•œ๋‹ค๋Š” ๊ฒƒ

 

 

2. ๋ชจ๋ฐ”์ผ ๋””์ž์ธ์—์„œ ๋งŽ์ด ์“ฐ๋Š” ๊ธฐ๋ณธ ๊ทœ์น™

โœ… 8pt Spacing System

๋ชจ๋ฐ”์ผ UI์—์„œ๋Š” ๋ณดํ†ต 8pt ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•œ๋‹ค.

4
8
16
24
32
40
48
64

์˜ˆ์‹œ

icon ↔ text = 8
card padding = 16
section gap = 24

 

 

โœ… ํ„ฐ์น˜ ์˜์—ญ ๊ทœ์น™

ํ„ฐ์น˜ ์˜์—ญ ๊ทœ์น™์€ ๋ชจ๋ฐ”์ผ UX์—์„œ ์ค‘์š”ํ•œ ๊ทœ์น™์ด๋‹ค.

์ตœ์†Œ ํ„ฐ์น˜ ์˜์—ญ = 44px
๋ฒ„ํŠผ ๋†’์ด = 48~56px
์•„์ด์ฝ˜ = 24px

 

 

3. ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ ์ ์šฉํ•˜๊ธฐ

์ผ๋ฐ˜ CSS ๊ธฐ์ค€์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ์€

๋””์ž์ธ ํ† ํฐ → ๊ณตํ†ต ์Šคํƒ€์ผ → ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ๊ตฌ์กฐ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

ํ•ต์‹ฌ ๋ชฉ์ ์€ ์ผ๊ด€์„ฑ ์žˆ๋Š” UI ์Šคํƒ€์ผ์„ ์œ ์ง€ํ•˜๊ณ  ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๋Š” ๊ฒƒ์ด๋‹ค.

 

1) ๋””์ž์ธ ํ† ํฐ ์ •์˜

๋””์ž์ธ ์‹œ์Šคํ…œ์˜ ๊ฐ€์žฅ ๊ธฐ์ดˆ ๋‹จ๊ณ„๋Š” ๋””์ž์ธ ํ† ํฐ์ด๋‹ค.
์ƒ‰์ƒ, ๊ฐ„๊ฒฉ, ํฐํŠธ ๊ฐ™์€ ๊ธฐ๋ณธ ์Šคํƒ€์ผ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

CSS์—์„œ๋Š” ๋ณดํ†ต CSS Custom Properties (CSS ๋ณ€์ˆ˜)๋กœ ์ •์˜ํ•œ๋‹ค.

:root {
  /* color */
  --color-primary: #111111;
  --color-secondary: #666666;
  --color-background: #ffffff;

  /* spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;

  /* radius */
  --radius-sm: 4px;
  --radius-md: 8px;

  /* font */
  --font-body: 16px;
  --font-title: 24px;
}
 

์ด๋ ‡๊ฒŒ ์ •์˜ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ์ „์ฒด์—์„œ ๋™์ผํ•œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2) ๋ฆฌ์…‹ ๋ฐ ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ ์ •์˜

๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™์„ ์„ค์ •ํ•œ๋‹ค.

๋ชจ๋“  UI ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋ณธ ์Šคํƒ€์ผ ํ™˜๊ฒฝ์„ ํ†ต์ผ์‹œํ‚จ๋‹ค.

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: system-ui, sans-serif;
  font-size: var(--font-body);
  color: var(--color-primary);
}
 

 

3) ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์‹œ์Šคํ…œ ์ •์˜

.text-body {
  font-size: 16px;
  line-height: 1.5;
}

.text-title {
  font-size: 24px;
  font-weight: 600;
}

.text-caption {
  font-size: 12px;
  color: var(--color-secondary);
}
 

๋ณธ๋ฌธ, ์ œ๋ชฉ, ์„ค๋ช…๊ธ€ ๋“ฑ

ํ…์ŠคํŠธ ์Šคํƒ€์ผ์„ ๊ณตํ†ต ํด๋ž˜์Šค๋กœ ์ •์˜ํ•œ๋‹ค.

 

4) ๋ ˆ์ด์•„์›ƒ ์‹œ์Šคํ…œ ์ •์˜

ํŽ˜์ด์ง€์˜ ๊ณตํ†ต ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™์„ ๋งŒ๋“ ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๊ฐ€ container์™€ spacing ์‹œ์Šคํ…œ์ด๋‹ค.

โœ… container

.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

container๋Š” ๋ ˆ์ด์•„์›ƒ์—์„œ ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ํŒจํ„ด์ด๋‹ค.

container๋Š” ํŽ˜์ด์ง€ ์ฝ˜ํ…์ธ ์˜ ๊ฐ€๋กœ ํญ๊ณผ ์ขŒ์šฐ ์—ฌ๋ฐฑ์„ ํ†ต์ œํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ํ™”๋ฉด์ด ๋„ˆ๋ฌด ๋„“์œผ๋ฉด ์—”ํ„ฐ ์—†์ด ์ž‘์„ฑ๋œ ๊ธ€์ฒ˜๋Ÿผ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

๊ทธ๋ž˜์„œ max-width๊ฐ€ ์ง€์ •๋œ container๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ!

 

โœ… stack (vertical layout)

.stack > * + * {
  margin-top: var(--space-md);
}
 

์ด๋Ÿฐ ํŒจํ„ด์€ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด ๊ฐ„๊ฒฉ์„ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

5) ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ์ •์˜

UI ์š”์†Œ๋ฅผ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋กœ ์ •์˜ํ•œ๋‹ค.

โœ… ๋ฒ„ํŠผ ์˜ˆ์‹œ

 
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  height: 40px;
  padding: 0 var(--space-md);

  border-radius: var(--radius-md);
  border: none;
  cursor: pointer;
}
 

variant๋Š” modifier ํด๋ž˜์Šค๋กœ ์ •์˜ํ•œ๋‹ค.

.button--primary {
  background: var(--color-primary);
  color: white;
}

.button--secondary {
  background: transparent;
  border: 1px solid var(--color-primary);
}

 

์‚ฌ์šฉ ์˜ˆ

<button class="button button--primary">
  ํ™•์ธ
</button>

์ด ๊ตฌ์กฐ๋Š” ๋ณดํ†ต BEM ๋ฐฉ์‹์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 

6) ์ƒํƒœ ์Šคํƒ€์ผ ์ •์˜

.button:hover {
  opacity: 0.9;
}

.button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

์ƒํƒœ ์Šคํƒ€์ผ์€ pseudo class(์˜์‚ฌ/๊ฐ€์ƒ ํด๋ž˜์Šค)๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ 

 

7) ๋ฐ˜์‘ํ˜• ๊ทœ์น™ ์ •์˜

๋ฐ˜์‘ํ˜• ์Šคํƒ€์ผ์€ breakpoint ๊ธฐ์ค€์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

.container {
  padding: 0 var(--space-sm);
}

@media (min-width: 768px) {
  .container {
    padding: 0 var(--space-lg);
  }
}
 

๋Œ€๋ถ€๋ถ„ ๋ชจ๋ฐ”์ผ ํผ์ŠคํŠธ ๋ฐฉ์‹์œผ๋กœ

๋ชจ๋ฐ”์ผ(max-width: 767px)์ด ๊ธฐ๋ณธ๊ฐ’ → min-width๋กœ ํ™•์žฅํ•˜๋Š” ํŒจํ„ด์„ ์“ด๋‹ค.

 

8) ํŒŒ์ผ ๊ตฌ์กฐ

์œ„ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ์ •์˜ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ํŒŒ์ผ ๊ตฌ์กฐ๊ฐ€ ์™„์„ฑ๋œ๋‹ค.

styles
 โ”œ reset.css
 โ”œ tokens.css
 โ”œ typography.css
 โ”œ layout.css
 โ”” components
  โ”œ button.css
  โ”œ card.css
  โ”” input.css

 

 

 

๐Ÿ’ญ ์ •๋ฆฌ

๋””์ž์ด๋„ˆ๊ฐ€ ๋งŒ๋“  ๊ทœ์น™์„ ํ† ํฐ์œผ๋กœ ๊ฐ•์ œํ•˜๋ฉด

  • UI ์ผ๊ด€์„ฑ์ด ์œ ์ง€๋˜๊ณ 
  • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง€๊ณ 
  • ํŒ€ ํ˜‘์—…์ด ํ›จ์”ฌ ํŽธํ•ด์ง„๋‹ค.

ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ์ž˜ ๋งŒ๋“ค์–ด ๋‘๋ฉด UI ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ์ •๋ง ๋งŽ์ด ๋นจ๋ผ์งˆ ๊ฒƒ์ด๋‹ค.

์œ„์ฒ˜๋Ÿผ ์ •๋ฆฌํ•œ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋ฉด ๋””์ž์ธ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ CSS ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค!

 

 

๋Œ“๊ธ€