JAVASCRIPT • LEVEL 2 • LESSON 4 OF 9
0% Complete
← Back to Learning Path

🎮 Lesson 4: Dynamic Grids

Build grids that change based on data, state, and user interaction.

What are Dynamic Grids?

Dynamic grids adapt to your data. Instead of hardcoding 3 columns, you calculate columns based on array length, user preferences, or application state. This is where JavaScript Grid shines!

💡 Key Concept:

Dynamic means "calculated at runtime." Your grid layout isn't fixed in CSS - it's determined by JavaScript based on current conditions.

Grid Based on Data Length

Create columns based on how much data you have:

const products = [
  { name: 'Laptop', price: 999 },
  { name: 'Mouse', price: 29 },
  { name: 'Keyboard', price: 79 }
];

const container = document.getElementById('grid');
const numColumns = products.length;

container.style.display = 'grid';
container.style.gridTemplateColumns = `repeat(${numColumns}, 1fr)`;
container.style.gap = '1rem';

// Add items to grid
products.forEach(product => {
  const div = document.createElement('div');
  div.textContent = product.name;
  container.appendChild(div);
});

User-Controlled Layouts

Let users choose their view:

function setGridLayout(layout) {
  const container = document.getElementById('gallery');
  
  const layouts = {
    'list': '1fr',
    'two': 'repeat(2, 1fr)',
    'three': 'repeat(3, 1fr)',
    'four': 'repeat(4, 1fr)'
  };
  
  container.style.gridTemplateColumns = layouts[layout];
}

// Buttons trigger layout changes
document.getElementById('btn-list').onclick = () => setGridLayout('list');
document.getElementById('btn-two').onclick = () => setGridLayout('two');
document.getElementById('btn-three').onclick = () => setGridLayout('three');
document.getElementById('btn-four').onclick = () => setGridLayout('four');

State-Based Grids

Change grid based on application state:

let viewMode = 'compact'; // or 'comfortable' or 'spacious'

function updateGrid() {
  const container = document.getElementById('grid');
  
  if (viewMode === 'compact') {
    container.style.gridTemplateColumns = 'repeat(6, 1fr)';
    container.style.gap = '0.5rem';
  } else if (viewMode === 'comfortable') {
    container.style.gridTemplateColumns = 'repeat(4, 1fr)';
    container.style.gap = '1rem';
  } else if (viewMode === 'spacious') {
    container.style.gridTemplateColumns = 'repeat(2, 1fr)';
    container.style.gap = '2rem';
  }
}

// Change state
viewMode = 'comfortable';
updateGrid();

Adaptive Column Count

Calculate optimal columns based on item count:

function getOptimalColumns(itemCount) {
  if (itemCount <= 2) return 1;
  if (itemCount <= 4) return 2;
  if (itemCount <= 9) return 3;
  return 4;
}

const items = [...]; // your data
const cols = getOptimalColumns(items.length);

container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;

⚡ Performance Tip:

Avoid changing grid styles on every scroll or mousemove event. Use debouncing or throttling for performance!

Building a Dashboard Builder

Let users drag widgets and the grid adapts:

const widgets = [
  { id: 1, span: 2 }, // takes 2 columns
  { id: 2, span: 1 },
  { id: 3, span: 1 },
  { id: 4, span: 3 }
];

// Calculate total columns needed
const totalSpan = widgets.reduce((sum, w) => sum + w.span, 0);
const cols = Math.min(totalSpan, 12); // max 12 columns

container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;

// Set each widget's span
widgets.forEach(widget => {
  const element = document.getElementById(`widget-${widget.id}`);
  element.style.gridColumn = `span ${widget.span}`;
});

React Dynamic Grid Example

In React, state drives grid layout:

function Gallery({ images }) {
  const [columns, setColumns] = useState(3);
  
  return (
    <>
      
{images.map(img => ( ))}
); }

Filtering and Grid Updates

Update grid when filtered data changes:

let allProducts = [...]; // all products
let filteredProducts = [];

function filterProducts(category) {
  if (category === 'all') {
    filteredProducts = allProducts;
  } else {
    filteredProducts = allProducts.filter(p => p.category === category);
  }
  
  renderGrid();
}

function renderGrid() {
  const container = document.getElementById('grid');
  
  // Clear existing
  container.innerHTML = '';
  
  // Update columns based on filtered count
  const cols = Math.min(filteredProducts.length, 4);
  container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
  
  // Add filtered items
  filteredProducts.forEach(product => {
    const div = document.createElement('div');
    div.textContent = product.name;
    container.appendChild(div);
  });
}

✅ Best Practice:

Store layout preferences in localStorage so users' choices persist across sessions!

Saving User Preferences

function saveLayout(layout) {
  localStorage.setItem('preferred-layout', layout);
  setGridLayout(layout);
}

function loadLayout() {
  const saved = localStorage.getItem('preferred-layout') || 'three';
  setGridLayout(saved);
}

// On page load
window.addEventListener('DOMContentLoaded', loadLayout);

Animation Between Layouts

Smooth transitions when grid changes:

container.style.transition = 'grid-template-columns 0.3s ease';
container.style.gridTemplateColumns = 'repeat(4, 1fr)';

The grid will smoothly animate to the new column count!

🎯 Practice Challenge!

Build a photo gallery where users can switch between 2, 3, or 4 column layouts with buttons.

📝 Quick Check (3 Questions)

1. How do you create columns based on array length?

2. What's the benefit of storing layout preferences in localStorage?

3. How do you animate grid layout changes?

← Back to Learning Path