본문 바로가기
JavaScript

JavaScript] Document Styles and classes

by Fastlane 2022. 11. 14.
728x90
반응형

출처 : https://javascript.info/styles-and-classes

element를 style하는 방법은 2가지가 있다. 

1. CSS에 class를 생성하고 추가하는 방법 : <div class="...">

2. 직접 style에 properties를 입력하는 방법 : <div style="...">

 

JavaScript는 classes와 style properties 모두 수정이 가능하다. 우리는 1번을 선호해야 하며, 2번은 class로 다룰 수 없는 경우에만 사용해야 한다. 예를들어 element 좌표를 계산해서 JavaScript로 설정해야 하는 경우이다. 

let top = /* complex calculations */;
let left = /* complex calculations */;

elem.style.left = left; // e.g '123px', calculated at run-time
elem.style.top = top; // e.g '456px'

이외에, text color 수정 등은 CSS에서 정의하고 class를 추가하는 것이 좋다. 

 

className and classList

class변경은 script에서 가장 자주 일어나는 action이다. 

오래전에는 JavaScript에 제약이 있었다. : class와 같은 예약어는 object property(elem.class)가 될 수 없었다. 하지만 현재는 그 제약이 없어졌다. 

 

그리고 class를 위해서 className이라는 property가 소개되었다. elem.className은 class attribute에 해당된다. 

<body class="main page">
  <script>
    alert(document.body.className); // main page
  </script>
</body>

elem.className에 값을 할당하면, class 전체문자열을 replace한다. 때때로 우리는 하나의 class를 추가하거나 삭제할 때가 있다. 이를 위해 elem.classList라는 property가 있다. 

 

elem.classList는 add/remove/toggle a single class 함수를 갖고있다. 

<body class="main page">
  <script>
    // add a class
    document.body.classList.add('article');

    alert(document.body.className); // main page article
  </script>
</body>
  • elem.classList.add/remove("class") – adds/removes the class.
  • elem.classList.toggle("class") – adds the class if it doesn’t exist, otherwise removes it.
  • elem.classList.contains("class") – checks for the given class, returns true/false.

classList는 iterable하여, for...of를 사용할 수 있다. 

<body class="main page">
  <script>
    for (let name of document.body.classList) {
      alert(name); // main, and then page
    }
  </script>
</body>

Element style

elem.style object는 style attribute에 해당된다. 

multi-word property는 camelCase를 사용한다. 

background-color  => elem.style.backgroundColor
z-index           => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth

Resetting the style property

때때로 우리는 style property를 지정했다가 나중에 삭제하기 원한다. 

예를들어 element를 숨기기 위해 우리는 elem.style.display = "none"으로 설정한다. 

그 다음, style.display를 삭제하고 싶을 때 delete elem.style.display를 하는 대신 elem.style.display = ""를 설정한다. 

// if we run this code, the <body> will blink
document.body.style.display = "none"; // hide

setTimeout(() => document.body.style.display = "", 1000); // back to normal

만약 우리가 style.display를 empty string으로 설정하면, 브라우저는 마치, style.display property가 없었던 것처럼, CSS classes를 적용하고 built-in style을 정상으로 적용한다. 

 

이를 위한 전용함수도 존재한다. elem.style.removeProperty('style property') 

document.body.style.background = 'red'; //set background to red

setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second

style.cssText로 전체 재작성하기

style.*를 사용하여 개별 style properties를 설정할 수 있다. 하지만 div.style="color:red; width:100px;"처럼 style전체를 설정할 수는 없다. div.style은 object이고 read-only이다. 

 

문자열로 전체 style을 설정하기 위해서, style.cssText 라는 특별한 property가 있다. 

<div id="div">Button</div>

<script>
  // we can set special style flags like "important" here
  div.style.cssText=`color: red !important;
    background-color: yellow;
    width: 100px;
    text-align: center;
  `;

  alert(div.style.cssText);
</script>

해당 property는 모든 존재하는 style을 대체하므로 드물게 사용된다. 안전하게 새로운 element를 위해 사용할 수 있다. 

div.setAttribute('style', 'color:red...')를 사용하여 attribute를 set할 수 있다. 

Mind the units

값에 CSS units을 추가하는 것을 잊지 말자.

예를들어 elem.style.top을 10이 아닌 10px로 설정한다. 

<body>
  <script>
    // doesn't work!
    document.body.style.margin = 20;
    alert(document.body.style.margin); // '' (empty string, the assignment is ignored)

    // now add the CSS unit (px) - and it works
    document.body.style.margin = '20px';
    alert(document.body.style.margin); // 20px

    alert(document.body.style.marginTop); // 20px
    alert(document.body.style.marginLeft); // 20px
  </script>
</body>

Computed styles: getComputedStyle

style을 수정하는 것은 쉽다. 하지만 읽는 것은 어떤가?

예를들어 element의 size, margins, color를 알고 싶을때 어떻게 해야할까?

 

style property는 CSS cascade없이 오직 style attribute의 값으로 동작한다. 따라서 elem.style을 사용해서 CSS classes에서 나온 어떤 것도 읽을 수 없다. 

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  The red text
  <script>
    alert(document.body.style.color); // empty
    alert(document.body.style.marginTop); // empty
  </script>
</body>
getComputedStyle(element, [pseudo])

element : value를 읽기위한 Element

pseudo : pseudo-element 예를들면 ::before. empty string 또는 no argument는 element그 자체를 의미한다. 

 

결과값은 elem.style과 같은 style object이다. 하지만 모든  CSS classes를 사용할 수 있다. 

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // now we can read the margin and the color from it

    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>

</body>

Computed and resolved values

CSS에는 2가지 컨셉이 있다. 

  1. computed value는 CSS 규칙과 CSS 상속이 적용된 이후의 값이다. 
  2. resolved value는 getComputedStyle()에 의해 return된 값이다. 

Summary

class를 관리하기 위해, DOM properties는 아래 2개가 있다. 

  • className
  • classList

style을 변경하기 위해서

  • style property는 camelCased styles의 object이다. 
  • style.cssText property는 style attribute에 해당된다. 

resolved styles을 읽기 위해서는 

  • getComputedStyle(elem, [pseudo]) 결과값을 사용한다. 

 

728x90
반응형

댓글