Skip to content

Instantly share code, notes, and snippets.

@sandro-pasquali
Created September 1, 2026 17:24
Show Gist options
  • Select an option

  • Save sandro-pasquali/e4826381f84026f6eb71984572978648 to your computer and use it in GitHub Desktop.

Select an option

Save sandro-pasquali/e4826381f84026f6eb71984572978648 to your computer and use it in GitHub Desktop.
Responsive CSS layouts derived from an ascii representation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
padding: 10px;
}
.bulldog-layout {
display: grid;
grid-template-rows: var(--grid-rows);
grid-template-columns: var(--grid-cols);
grid-row-gap: 5px;
grid-column-gap: 5px;
max-width: 1000px;
height: 100vh;
margin: 0 auto;
}
.bulldog-layout div {
grid-area: var(--row) / var(--col) / span var(--height) / span var(--width);
background-color: var(--bg-color);
text-align: center;
line-height: calc(var(--height) / var(--totalRows) * 100vh);
color: #860ef5;
border: 1px black solid;
}
@media (max-width: 600px) {
.bulldog-layout {
grid-template-columns: 1fr;
}
.bulldog-layout div {
grid-area: auto / auto / auto / auto;
}
}
</style>
</head>
<body>
<div id="testblock" class="bulldog-layout"></div>
<script>
// Inspired by: https://github.com/jlogix/text2css-grid
//
const design =`
+---+---+
| | |
+---+---+
| | |
+-+-+-+-+
| | | | |
+-+-+-+-+
| |
+---+---+
`;
const lines = design.split(/[\r\n]/) // Split layout into individual lines.
.map(line => line.match(/\+/) ? // '+' means one or more boxes is closing.
line.split(/[\+\|]/)
.filter(entry => entry) // Filter out zero-length lines.
.map(box => box.match(/^\-+$/) ? // All '-'s mean box is closing here.
-(box.length + 1) : // Indicate close with negative number.
box.length + 1) : // Box still open, use positive length.
line.split(/\|/) // If '+' not found split at '|'.
.filter(entry => entry) // Filter out zero-length lines.
.map(box => box.length + 1)) // Add box width to the array.
.filter(entry => entry.length); // Filter out empty arrays.
const backgroundColors = ["#f7a7a7", "#d0f7a7", "#f7d6a7", "#a7e2f7", "#e7bafb", "#fbbadc", "#def5d1", "#f7f1a7", "#b5fdd6", "#fb9387"];
let currentRow = 0;
const boxes = [];
// 1. Calculate the start column of each box.
// 2. For each row in the array and for each number in the row:
// If the number is positive:
// If an open box already exists at this column offset:
// Increment the row count of the open box at the column offset.
// Else (i.e. no open box found at the column offset):
// Create a new box at this row and column offsets.
// Else (i.e. number is negative):
// Increment the row count of the box at the current column offset and close the box.
//
lines.filter(entry => entry) // Filter out zero length lines
.forEach(line => {
// Starting columns of boxes.
//
const startColumns = line.map((value, index, array) => array.filter((_, filterIndex) => filterIndex < index).reduce((sum, num) => sum + Math.abs(num), 1));
line.forEach((value, index) => {
console.log(value, index);
// Any open boxes at this column offset?
//
const openBoxes = boxes.filter(box => box.col === startColumns[index] && box.isOpen);
if (value > 0) { // A positive number means...
if (openBoxes.length) {
openBoxes.forEach(box => box.height++); // ...add one more row to open boxes at this column offset
} else { // No open boxes exist at this column offset. start a new box.
const newBox = {
row: currentRow,
col: startColumns[index],
width: value,
height: 1,
color: backgroundColors[boxes.length % backgroundColors.length],
isOpen: true
};
boxes.push(newBox);
}
} else {
// Negative number means close open boxes at this column offset.
//
openBoxes.forEach(box => {
box.height++;
box.isOpen = false;
});
}
});
currentRow++;
});
const totalRows = lines.length - 1;
const totalCols = lines[0].reduce((sum, element) => sum + Math.abs(element), 0);
const layoutContainer = document.getElementById('testblock');
layoutContainer.style.setProperty('--grid-rows', `repeat(${totalRows}, 1fr)`);
layoutContainer.style.setProperty('--grid-cols', `repeat(${totalCols}, 1fr)`);
layoutContainer.style.setProperty('--totalRows', totalRows);
boxes.forEach((box, index) => {
const boxDiv = document.createElement('div');
boxDiv.textContent = String(index + 1);
boxDiv.style.setProperty('--row', box.row);
boxDiv.style.setProperty('--col', box.col);
boxDiv.style.setProperty('--width', box.width);
boxDiv.style.setProperty('--height', box.height);
boxDiv.style.setProperty('--bg-color', box.color);
layoutContainer.appendChild(boxDiv);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment