DOM стили и размеры

JavaScript позволяет читать и изменять CSS-стили элементов через свойство style и getComputedStyle, а также получать точные размеры и позиции через геометрические API.

Зачем нужно

Динамическое управление стилями нужно для анимаций, адаптивных компонентов, позиционирования всплывающих окон и любых эффектов, которые зависят от текущего состояния. Геометрические методы позволяют узнать реальный размер и положение элемента — что невозможно сделать только через CSS.

Где используется

  • Позиционирование tooltip-ов и выпадающих меню
  • Плавные анимации через style.transform, style.opacity
  • Проверка видимости элемента при прокрутке (Intersection)
  • Адаптивные компоненты на основе реального размера контейнера
  • Вычисление позиции для drag-and-drop

Основной контент

Изменение инлайн-стилей

const el = document.querySelector('.box');

el.style.color = 'red';
el.style.backgroundColor = '#f0f0f0';  // camelCase, не kebab-case
el.style.width = '200px';              // значение — строка с единицами
el.style.transform = 'translateX(50px)';

// Удалить инлайн-стиль
el.style.color = '';

cssText — несколько свойств за раз

el.style.cssText = 'color: red; background: blue; font-size: 16px;';
// Внимание: это перезаписывает все инлайн-стили!

Управление через классы (предпочтительно)

// Лучше переключать классы, а стили держать в CSS
el.classList.add('visible');
el.classList.remove('hidden');
el.classList.toggle('active');
el.classList.replace('loading', 'loaded');

getComputedStyle — реальные вычисленные стили

const styles = getComputedStyle(el);

styles.color;            // 'rgb(255, 0, 0)' — итоговое значение
styles.fontSize;         // '16px'
styles.display;          // 'flex'
styles.getPropertyValue('--custom-color'); // CSS-переменные

getComputedStyle возвращает реальные применённые значения из всего каскада CSS, не только инлайн.

Размеры элемента

const el = document.querySelector('.card');

// clientWidth/Height — контент + padding (без border, scrollbar)
el.clientWidth;
el.clientHeight;

// offsetWidth/Height — контент + padding + border
el.offsetWidth;
el.offsetHeight;

// scrollWidth/Height — полный размер включая скрытый контент
el.scrollWidth;
el.scrollHeight;

// scrollTop/Left — текущая прокрутка внутри элемента
el.scrollTop;
el.scrollLeft = 0;  // прокрутить в начало

getBoundingClientRect — позиция и размер

const rect = el.getBoundingClientRect();

rect.top;     // от верхнего края viewport
rect.left;    // от левого края viewport
rect.right;   // left + width
rect.bottom;  // top + height
rect.width;
rect.height;

// Позиция с учётом прокрутки страницы
const absTop = rect.top + window.scrollY;
const absLeft = rect.left + window.scrollX;

CSS Custom Properties через JS

// Чтение
getComputedStyle(document.documentElement)
  .getPropertyValue('--primary-color').trim(); // '#3498db'

// Запись
document.documentElement.style.setProperty('--primary-color', '#e74c3c');
el.style.setProperty('--spacing', '16px');

Частые ошибки

  • Используют el.style.fontSize вместо getComputedStyleel.style показывает только инлайн-стили; если стиль задан через CSS-класс, значение будет пустой строкой.
  • Забывают единицы при записиel.style.width = 200 не работает, нужно el.style.width = '200px'.
  • Используют style для каждого изменения анимации — манипуляции в JS блокируют поток. Используйте CSS transition/animation и только переключайте класс.
  • Читают getBoundingClientRect в цикле — каждый вызов вызывает layout. Кешируйте результат вне цикла.

Связанные темы

Ресурсы