← Назад к вопросам

Как посчитать 50% от размера блока?

2.3 Middle🔥 132 комментариев
#HTML и CSS

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Вычисление 50% от размера блока: CSS и JavaScript

Получение половины от размера HTML-элемента — частая задача при создании адаптивных дизайнов и динамических макетов. Существует несколько подходов в зависимости от контекста и требований.

1. CSS: Относительные единицы (50vw, 50vh)

Это самый простой способ для первичных размеров:

.half-width {
  width: 50vw; /* 50% от ширины viewport */
  height: 50vh; /* 50% от высоты viewport */
}

/* Для процентов от родителя */
.parent {
  width: 800px;
  height: 600px;
}

.child {
  width: 50%; /* 400px - 50% от parent */
  height: 50%; /* 300px - 50% от parent */
}

2. CSS: calc() для динамических значений

Для более сложных вычислений:

.responsive-box {
  /* 50% ширины минус отступ */
  width: calc(50% - 10px);
  
  /* 50% высоты плюс отступ */
  height: calc(50% + 20px);
  
  /* Комбинированное значение */
  padding: calc(50% / 10); /* 5% */
}

/* Половина minus border */
.box {
  width: calc(50% - 2px); /* 2px на border */
  border: 1px solid black;
  box-sizing: border-box;
}

3. JavaScript: getBoundingClientRect()

Для получения реального размера элемента:

const element = document.getElementById('my-block');
const rect = element.getBoundingClientRect();

// 50% от текущих размеров
const halfWidth = rect.width / 2;    // 50% ширины
const halfHeight = rect.height / 2;  // 50% высоты

console.log(`Половина ширины: ${halfWidth}px`);
console.log(`Половина высоты: ${halfHeight}px`);

4. JavaScript: offsetWidth и offsetHeight

Для целей размещения элементов:

const block = document.querySelector('.block');

// Полный размер включая padding и border
const fullWidth = block.offsetWidth;
const fullHeight = block.offsetHeight;

// Половина
const halfWidth = fullWidth / 2;
const halfHeight = fullHeight / 2;

// Применить как CSS
block.style.width = halfWidth + 'px';
block.style.height = halfHeight + 'px';

5. ResizeObserver для реактивного обновления

Если размер блока может меняться:

const element = document.getElementById('resizable');
const observer = new ResizeObserver(entries => {
  for (const entry of entries) {
    const width = entry.contentRect.width;
    const height = entry.contentRect.height;
    
    const halfWidth = width / 2;
    const halfHeight = height / 2;
    
    console.log(`Новая половина: ${halfWidth}x${halfHeight}`);
  }
});

observer.observe(element);

6. React Hook для вычисления

Удобный хук для React приложений:

import { useRef, useEffect, useState } from 'react';

function useElementHalf() {
  const ref = useRef(null);
  const [half, setHalf] = useState({ width: 0, height: 0 });

  useEffect(() => {
    if (!ref.current) return;

    const updateHalf = () => {
      const rect = ref.current.getBoundingClientRect();
      setHalf({
        width: rect.width / 2,
        height: rect.height / 2
      });
    };

    updateHalf();

    const observer = new ResizeObserver(updateHalf);
    observer.observe(ref.current);

    return () => observer.disconnect();
  }, []);

  return { ref, half };
}

// Использование
function MyComponent() {
  const { ref, half } = useElementHalf();

  return (
    <div ref={ref} style={{ width: '400px', height: '300px' }}>
      <p>50% ширины: {half.width}px</p>
      <p>50% высоты: {half.height}px</p>
    </div>
  );
}

7. Практические примеры

Сплит-экран (half width columns)

.split-container {
  display: flex;
}

.split-left,
.split-right {
  width: 50%;
  min-height: 100vh;
  padding: 20px;
}

.split-left {
  background: #f0f0f0;
}

.split-right {
  background: white;
}

Динамическое позиционирование

function positionAtHalf(element, parentElement) {
  const parentRect = parentElement.getBoundingClientRect();
  
  element.style.position = 'absolute';
  element.style.left = (parentRect.width / 2) + 'px';
  element.style.top = (parentRect.height / 2) + 'px';
  element.style.transform = 'translate(-50%, -50%)'; // Center on the point
}

Responsive layout с 50%

@media (max-width: 768px) {
  .column {
    width: 100%; /* На мобилах 100% */
  }
}

@media (min-width: 769px) {
  .column {
    width: 50%; /* На десктопе 50% */
  }
}

8. Вычисление с учетом padding и margin

function getHalfWithSpacing(element) {
  const style = getComputedStyle(element);
  const padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
  const margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight);
  
  const netWidth = element.offsetWidth - padding - margin;
  return netWidth / 2;
}

9. Важные замечания

clientWidth vs offsetWidth

// clientWidth: width + padding (БЕЗ border)
const contentWidth = element.clientWidth / 2;

// offsetWidth: width + padding + border
const fullWidth = element.offsetWidth / 2;

Viewport vs Element

/* 50% от viewport - может быть больше чем элемент */
.vh-half { height: 50vh; }

/* 50% от родителя - зависит от родителя */
.percentage-half { height: 50%; }

Когда что использовать

СценарийМетодПреимущество
Статический дизайнCSS 50%Простота, производительность
Динамическое смещениеcalc()Гибкость в CSS
Реальные размерыgetBoundingClientRect()Точность, текущие значения
Реактивное изменениеResizeObserverАвтоматическое обновление
React компонентCustom hookИнкапсуляция, переиспользование

Выбор метода зависит от контекста: CSS идеален для статических макетов, JavaScript необходим для динамических расчетов и анимаций в реальном времени.