From 382799078e998eb67952dd9db7bd3d54e6a54213 Mon Sep 17 00:00:00 2001 From: fkakatie Date: Fri, 12 Jun 2026 14:40:41 -0600 Subject: [PATCH] fix: align columns with other block implementation --- blocks/columns/columns.css | 53 +++++++++++++++++++++++++++++++------- blocks/columns/columns.js | 49 ++++++++++++++++++++++++++--------- 2 files changed, 81 insertions(+), 21 deletions(-) diff --git a/blocks/columns/columns.css b/blocks/columns/columns.css index 04cc39a..0afa54f 100644 --- a/blocks/columns/columns.css +++ b/blocks/columns/columns.css @@ -1,33 +1,68 @@ .columns > div { display: flex; flex-direction: column; + gap: var(--space-m); } -.columns img { - width: 100%; +.columns .media-wrapper { + order: 0; } -.columns > div > div { +.columns .body-wrapper { order: 1; } -.columns > div > .columns-img-col { - order: 0; +.columns .media-wrapper img { + object-fit: contain; } -.columns > div > .columns-img-col img { - display: block; +.columns .media-wrapper[data-orientation="landscape"] img { + max-height: 300px; + width: 100%; + aspect-ratio: 16 / 9; +} + +.columns .media-wrapper[data-orientation="portrait"] img { + height: 100%; + max-width: 300px; + aspect-ratio: 3 / 4; +} + +@media (width >= 600px) { + .columns.cols-even > div { + flex-direction: unset; + align-items: center; + } + + .columns.cols-even > div > div { + flex: 1; + order: unset; + min-width: 0; + } } @media (width >= 900px) { - .columns > div { + .columns.cols-3 > div { + flex-direction: unset; align-items: center; + } + + .columns.cols-3 > div > div { + flex: 1; + order: unset; + min-width: 0; + } +} + +@media (width >= 1200px) { + .columns > div { flex-direction: unset; - gap: var(--space-m); + align-items: center; } .columns > div > div { flex: 1; order: unset; + min-width: 0; } } diff --git a/blocks/columns/columns.js b/blocks/columns/columns.js index 9b78c81..fcc7d43 100644 --- a/blocks/columns/columns.js +++ b/blocks/columns/columns.js @@ -1,18 +1,43 @@ -export default function decorate(block) { - const cols = [...block.firstElementChild.children]; - block.classList.add(`columns-${cols.length}-cols`); +/** + * Returns the shared column count if every row has the same number of columns, otherwise null. + * @param {Element} block The block element + * @returns {number|null} Column count, or null if rows differ + */ +function getColCount(block) { + const rows = [...block.children]; + if (rows.length === 0) return null; + const n = rows[0].children.length; + return rows.every((row) => row.children.length === n) ? n : null; +} + +/** + * Sets data-orientation to 'portrait' or 'landscape' from the first img's width/height attributes. + * @param {Element} col The column element to tag + */ +function setImageOrientation(col) { + const img = col.querySelector('img'); + if (img) { + const w = parseInt(img.getAttribute('width'), 10); + const h = parseInt(img.getAttribute('height'), 10); + if (w && h && h > w) { + col.dataset.orientation = 'portrait'; + } else col.dataset.orientation = 'landscape'; + } +} - // setup image columns +export default function decorate(block) { [...block.children].forEach((row) => { [...row.children].forEach((col) => { - const pic = col.querySelector('picture'); - if (pic) { - const picWrapper = pic.closest('div'); - if (picWrapper && picWrapper.children.length === 1) { - // picture is only content in column - picWrapper.classList.add('columns-img-col'); - } - } + const els = [...col.children]; + const isMedia = els.length > 0 && els.every((el) => el.tagName === 'PICTURE' || el.tagName === 'VIDEO'); + col.classList.add(isMedia ? 'media-wrapper' : 'body-wrapper'); + if (isMedia) setImageOrientation(col); }); }); + + const colCount = getColCount(block); + if (colCount && ![...block.classList].some((c) => c.startsWith('cols-'))) { + block.classList.add(`cols-${colCount}`); + if (colCount % 2 === 0) block.classList.add('cols-even'); + } }