hometools

Fit Blocks in Container

View Code

HTML

<div 
  class="block-wrapper" 
  data-r="blocks" 
  data-min-width="200" 
  data-max-width="260" 
  data-ratio-width="16" 
  data-ratio-height="9"></div>

JavaScript

export const b = { init: "blocks" };

export function blocks(_, __, el) {
  const layout = getBlockLayout(
    el.propAsInt("minWidth"),
    el.propAsInt("maxWidth"),
    parseInt(el.getBoundingClientRect().width),
    parseInt(el.getBoundingClientRect().height),
    el.propAsInt("ratioWidth"),
    el.propAsInt("ratioHeight"),
  );
  for (let i = 0; i < layout.cells; i = i + 1) {
    el.append(b.render("cellTemplate"));
  }
  b.setCSS("--cell-width", `${layout.cellWidth}px`);
  b.setCSS("--cell-height", `${layout.cellHeight}px`);
}

function getBlockLayout(
  minWidth,
  maxWidth,
  containerWidth,
  containerHeight,
  ratioWidth,
  ratioHeight,
) {
  const maxItems = Math.floor(containerWidth / minWidth);
  let cellWidth = Math.floor(containerWidth / maxItems);
  if (cellWidth > maxWidth) {
    cellWidth = maxWidth;
  }
  const cellHeight = cellWidth / ratioWidth * ratioHeight;
  const columns = parseInt(containerWidth / cellWidth, 10);
  const rows = parseInt(containerHeight / cellHeight, 10);
  const cells = columns * rows;
  return {
    cellWidth: cellWidth,
    cellHeight: cellHeight,
    columns: columns,
    rows: rows,
    cells: cells,
  };
}

CSS

* {
  margin: 0;
  box-sizing: border-box;
}

html {
  scrollbar-gutter: stable;
}

body {
  background-color: var(--background-color);
  color: var(--default-color);
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

main {
  display: flex;
  flex-direction: column;
}

.block-wrapper {
  flex: 1;
  background: #333;
  min-height: 600px;
}

.cell {
  display: inline-block;
  width: var(--cell-width);
  height: var(--cell-height);
  background: #345345;
  outline: 1px solid red;
}