CodeGym /ํ–‰๋™ /Frontend SELF KO /๊ณ ๊ธ‰ ๊ธฐ์ˆ 

๊ณ ๊ธ‰ ๊ธฐ์ˆ 

Frontend SELF KO
๋ ˆ๋ฒจ 32 , ๋ ˆ์Šจ 4
์‚ฌ์šฉ ๊ฐ€๋Šฅ

10.1 ์ค‘์ฒฉ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜

๋” ๋ณต์žกํ•˜๊ณ  ๋™์ ์ธ ์Šคํƒ€์ผ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด CSS ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜์˜ ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ ๋ณ€์ˆ˜, JavaScript๋ฅผ ํ†ตํ•œ ๋™์  ๊ฐ’ ๋ณ€๊ฒฝ, ๋ณต์žกํ•œ ๊ทธ๋ผ๋ฐ์ด์…˜๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด. ๋” ๋ณต์žกํ•œ ์˜ˆ์ œ์™€ ๊ธฐ์ˆ ์„ ์‚ดํŽด๋ณด์ž.

1. ์ค‘์ฒฉ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜

์ด ์˜ˆ์ œ์—์„œ๋Š” ์š”์†Œ ํฌ๊ธฐ๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜ ์ค‘์ฒฉ์„ ์‚ฌ์šฉํ•ด ๋ดค์–ด:

CSS
    
      :root {
        --base-size: 16px;
        --scale-factor: 1.5;
        --scaled-size: calc(var(--base-size) * var(--scale-factor));
      }

      .container {
        font-size: var(--scaled-size);
        padding: calc(var(--scaled-size) / 2);
        margin: calc(var(--scaled-size) / 4);
      }
    
  

2. ๋™์  ์ƒ‰์กฐ ๋ณ€๊ฒฝ ํ…Œ๋งˆํ™”

CSS ๋ณ€์ˆ˜์™€ JavaScript๋ฅผ ํ†ตํ•ด hsl()์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ๋งˆ๋ฅผ ๋งŒ๋“ค๊ณ  ๋™์ ์œผ๋กœ ์ƒ‰์กฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด.

๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด --base-hue ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด ๋ฐฐ๊ฒฝ์ƒ‰์ด ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋ผ:

CSS
    
      :root {
        --base-hue: 200;
        --saturation: 70%;
        --lightness: 50%;
        --primary-color: hsl(var(--base-hue), var(--saturation), var(--lightness));
      }

      body {
        background-color: var(--primary-color);
        transition: background-color 0.3s;
      }
    
  
HTML
    
      <button id="change-color">Change Color</button>
    
  
JavaScript
    
// "change-color" id๊ฐ€ ์žˆ๋Š” ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด
document.getElementById('change-color').addEventListener('click', () => {
  // ๋ฌธ์„œ์˜ ๋ฃจํŠธ ์š”์†Œ ๊ฐ€์ ธ์˜ด (HTML)
  const root = document.documentElement;

  // HSL ํ˜•์‹์˜ ์ƒ‰์ƒ ์ƒ‰์กฐ๋ฅผ ์œ„ํ•œ 0๋ถ€ํ„ฐ 359๊นŒ์ง€์˜ ๋ฌด์ž‘์œ„ ์ˆซ์ž ์ƒ์„ฑ
  const newHue = Math.floor(Math.random() * 360);

  // ์‚ฌ์šฉ์ž ์ง€์ • CSS ๋ณ€์ˆ˜ --base-hue์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ฐ’ ์„ค์ •
  // ์ด ๋ณ€์ˆ˜๋Š” ์•„๋งˆ๋„ ์Šคํƒ€์ผ์—์„œ ๊ธฐ๋ณธ ์ƒ‰์ƒ์„ ์ •์˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋จ
  root.style.setProperty('--base-hue', newHue);
});
    
  

10.2 ๋ณต์žกํ•œ ๊ทธ๋ผ๋ฐ์ด์…˜

3. ๋ณต์žกํ•œ ๋‹ค๋‹จ๊ณ„ ๊ทธ๋ผ๋ฐ์ด์…˜

์ด ์˜ˆ์ œ์—์„œ๋Š” ์—ฌ๋Ÿฌ ์ƒ‰์ƒ ์Šคํƒ‘์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ๋ฐฐ๊ฒฝ์„ ์ƒ์„ฑํ•˜๋Š” ๋‹ค๋‹จ๊ณ„ ์„ ํ˜• ๊ทธ๋ผ๋ฐ์ด์…˜์„ ์‚ฌ์šฉํ–ˆ์–ด:

CSS
    
      :root {
        --color-stop1: hsla(200, 100%, 50%, 0.8);
        --color-stop2: hsla(340, 100%, 50%, 0.8);
        --color-stop3: hsla(120, 100%, 50%, 0.8);
        --color-stop4: hsla(60, 100%, 50%, 0.8);
      }

      .complex-gradient {
        background: linear-gradient(
          45deg,
          var(--color-stop1) 25%,
          var(--color-stop2) 25%,
          var(--color-stop2) 50%,
          var(--color-stop3) 50%,
          var(--color-stop3) 75%,
          var(--color-stop4) 75%
        );
      }
    
  

4. ๋™์  ์ ์‘ํ˜• ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ

์Šคํฌ๋ฆฐ ํฌ๊ธฐ ๋ฐ ๊ธฐํƒ€ ์š”์ธ์— ๋”ฐ๋ผ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ ์‘ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด CSS ๋ณ€์ˆ˜ ๋ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์•ผ.

์ ์‘ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ์Šคํฌ๋ฆฐ ํฌ๊ธฐ์— ๋”ฐ๋ผ ํŒจ๋”ฉ๊ณผ ๋ฐฐ๊ฒฝ์ƒ‰์„ ๋ณ€๊ฒฝํ•ด:

HTML
    
      <div class="dynamic-component">๋™์  ์ปดํฌ๋„ŒํŠธ</div>
    
  
CSS
    
      :root {
        --base-padding: 20px;
        --scale-factor: 1.5;
        --dynamic-padding: calc(var(--base-padding) * var(--scale-factor));
      }

      @media (max-width: 600px) {
        :root {
          --scale-factor: 1;
        }
      }

      .dynamic-component {
        padding: var(--dynamic-padding);
        background-color: hsl(calc(100 + var(--scale-factor) * 50), 100%, 50%);
      }
    
  

5. JavaScript ๋ฐ CSS ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ๊ทธ๋ผ๋ฐ์ด์…˜ ์ƒ์„ฑ

JavaScript๋กœ ์–ป์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ ์œผ๋กœ ๊ทธ๋ผ๋ฐ์ด์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์•ผ.

๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฌด์ž‘์œ„๋กœ ์ƒˆ๋กœ์šด ์ƒ‰์ƒ๊ณผ ๊ทธ๋ผ๋ฐ์ด์…˜ ๊ฐ๋„๊ฐ€ ์ƒ์„ฑ๋ผ:

CSS
    
      :root {
        --color1: hsl(200, 100%, 50%);
        --color2: hsl(340, 100%, 50%);
        --angle: 45deg;
      }

      .dynamic-gradient {
        background: linear-gradient(var(--angle), var(--color1), var(--color2));
      }
    
  
HTML
    
      <button id="generate-gradient">Generate Gradient</button>
      <div class="dynamic-gradient">Content</div>
    
  
JavaScript
    

// "generate-gradient" id๊ฐ€ ์žˆ๋Š” ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด
document.getElementById('generate-gradient').addEventListener('click', () => {
  // ๋ฌธ์„œ์˜ ๋ฃจํŠธ ์š”์†Œ ๊ฐ€์ ธ์˜ด (HTML)
  const root = document.documentElement;

  // HSL ํ˜•์‹์œผ๋กœ ์ตœ๋Œ€ ์ฑ„๋„ ๋ฐ ์ค‘๊ฐ„ ๋ฐ๊ธฐ์˜ ๋‘ ๊ฐ€์ง€ ๋ฌด์ž‘์œ„ ์ƒ‰์ƒ ์ƒ์„ฑ
  const newColor1 = `hsl(${Math.floor(Math.random() * 360)}, 100%, 50%)`;
  const newColor2 = `hsl(${Math.floor(Math.random() * 360)}, 100%, 50%)`;

  // ๊ทธ๋ผ๋ฐ์ด์…˜์— ๋Œ€ํ•œ ๋ฌด์ž‘์œ„ ๊ฐ๋„ ์ƒ์„ฑ
  const newAngle = `${Math.floor(Math.random() * 360)}deg`;

  // ์‚ฌ์šฉ์ž ์ง€์ • CSS ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ฐ’ ์„ค์ •
  root.style.setProperty('--color1', newColor1);
  root.style.setProperty('--color2', newColor2);
  root.style.setProperty('--angle', newAngle);
});

    
  

10.3 CSS ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ๋™์  ํ…Œ๋งˆ

์˜ˆ์ œ 1: CSS ๋ณ€์ˆ˜์™€ JavaScript๋ฅผ ์‚ฌ์šฉํ•œ ๋™์  ํ…Œ๋งˆ ๋ณ€๊ฒฝ

์„ ํƒํ•œ ํ…Œ๋งˆ์— ๋”ฐ๋ผ CSS ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๋™์  ํ…Œ๋งˆ ์‹œ์Šคํ…œ์„ ์ƒ์„ฑํ•  ๊ฑฐ์•ผ:

CSS
    
      :root {
        --background-color: #ffffff;
        --text-color: #000000;
        --primary-color: #3498db;
        --secondary-color: #2ecc71;
      }

      body {
        background-color: var(--background-color);
        color: var(--text-color);
        transition: background-color 0.3s, color 0.3s;
      }

      .container {
        padding: 20px;
      }

      button {
        background-color: var(--primary-color);
        color: white;
        border: none;
        padding: 10px 20px;
        cursor: pointer;
        transition: background-color 0.3s;
      }

      button:hover {
        background-color: var(--secondary-color);
      }

      .content {
        margin-top: 20px;
      }
    
  
HTML
    
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>๋™์  ํ…Œ๋งˆ ๋ณ€๊ฒฝ</title>
          <link rel="stylesheet" href="styles.css">
        </head>
        <body>
          <div class="container">
            <button onclick="switchTheme()">ํ…Œ๋งˆ ๋ณ€๊ฒฝ</button>
            <div class="content">
              <h1>์ œ๋ชฉ</h1>
              <p>๋™์  ํ…Œ๋งˆ ๋ณ€๊ฒฝ ์˜ˆ์‹œ ํ…์ŠคํŠธ.</p>
            </div>
          </div>
          <script src="script.js"></script>
        </body>
      </html>
    
  
JavaScript
    
     // ํ…Œ๋งˆ ๊ฐ์ฒด๋ฅผ ์ •์˜
const themes = {
  light: {
    // ๋ผ์ดํŠธ ํ…Œ๋งˆ ์ƒ‰์ƒ
    '--background-color': '#ffffff',  // ๋ฐฐ๊ฒฝ์ƒ‰
    '--text-color': '#000000',        // ํ…์ŠคํŠธ ์ƒ‰์ƒ
    '--primary-color': '#3498db',      // ๊ธฐ๋ณธ ์ƒ‰์ƒ
    '--secondary-color': '#2ecc71'    // ๋ณด์กฐ ์ƒ‰์ƒ
  },
  dark: {
    // ๋‹คํฌ ํ…Œ๋งˆ ์ƒ‰์ƒ
    '--background-color': '#2c3e50',  // ๋ฐฐ๊ฒฝ์ƒ‰
    '--text-color': '#ecf0f1',        // ํ…์ŠคํŠธ ์ƒ‰์ƒ
    '--primary-color': '#e74c3c',      // ๊ธฐ๋ณธ ์ƒ‰์ƒ
    '--secondary-color': '#8e44ad'    // ๋ณด์กฐ ์ƒ‰์ƒ
  }
};

// ํ˜„์žฌ ์„ ํƒ๋œ ํ…Œ๋งˆ
let currentTheme = 'light';

// ํ…Œ๋งˆ๋ฅผ ์ „ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
function switchTheme() {
  // currentTheme์˜ ๊ฐ’์„ ๋ฐ˜์ „ํ•จ (๋ผ์ดํŠธ -> ๋‹คํฌ, ๋‹คํฌ -> ๋ผ์ดํŠธ)
  currentTheme = currentTheme === 'light' ? 'dark' : 'light';

  // ํ˜„์žฌ ํ…Œ๋งˆ์˜ ์ƒ‰์ƒ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ด
  const theme = themes[currentTheme];

  // ํ…Œ๋งˆ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ‚ค-๊ฐ’ ์Œ์„ ์ˆœํšŒ
  for (let [variable, value] of Object.entries(theme)) {
    // CSS ๋ณ€์ˆ˜ ๊ฐ’ ์„ค์ •
    document.documentElement.style.setProperty(variable, value);
  }
}
    
  

์˜ˆ์ œ 2: calc(), min(), max() ๋ฐ clamp()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฐํŠธ ํฌ๊ธฐ์™€ ํŒจ๋”ฉ์„ ์กฐ์ ˆํ•˜๋Š” ๋ฐ˜์‘ํ˜• ๋””์ž์ธ

๋ณด๊ธฐ ์ฐฝ ๋„ˆ๋น„์— ๋”ฐ๋ผ ํฐํŠธ ํฌ๊ธฐ ๋ฐ ํŒจ๋”ฉ์ด ๋ณ€๊ฒฝ๋˜๋Š” ๋ฐ˜์‘ํ˜• ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค์–ด๋ณผ ๊ฑฐ์•ผ:

CSS
    
      :root {
        --base-font-size: 16px;
        --base-padding: 10px;
        --min-font-size: 14px;
        --max-font-size: 24px;
        --preferred-font-size: 2vw;
        --min-padding: 8px;
        --max-padding: 20px;
        --preferred-padding: 1.5vw;
      }

      body {
        font-size: clamp(var(--min-font-size), var(--preferred-font-size), var(--max-font-size));
        padding: clamp(var(--min-padding), var(--preferred-padding), var(--max-padding));
        transition: font-size 0.3s, padding 0.3s;
      }

      .responsive-container {
        margin: 0 auto;
        max-width: 800px;
        padding: calc(var(--base-padding) * 2);
        text-align: center;
      }

      h1 {
        font-size: clamp(calc(var(--base-font-size) * 1.5), 3vw, 36px);
      }

      p {
        font-size: clamp(var(--base-font-size), 2vw, 24px);
      }
    
  
HTML
    
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>๋™์  ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง„ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ</title>
          <link rel="stylesheet" href="styles.css">
        </head>
        <body>
          <div class="responsive-container">
            <h1>๋ฐ˜์‘ํ˜• ์ œ๋ชฉ</h1>
            <p>์ด ํ…์ŠคํŠธ๋Š” ๋ณด๊ธฐ ์ฐฝ ํฌ๊ธฐ์— ๋งž์ถฐ ํฐํŠธ ํฌ๊ธฐ์™€ ํŒจ๋”ฉ์„ ์กฐ์ •ํ•ด.</p>
          </div>
        </body>
      </html>
    
  
์ฝ”๋ฉ˜ํŠธ
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION