Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> CSS

วิธีสร้าง Expanding Grid (Grid ขยายตัว) ด้วย CSS และ JavaScript

Expanding Grid คือ UI Pattern ที่คลิกที่ Item ใน Grid แล้ว Panel ขยายแสดงรายละเอียดเต็มความกว้าง (Full-width) ใต้ Item นั้นๆ ตัวอย่างนี้สร้าง 3 คอลัมน์ คลิกแล้วแสดง Tab Content ด้านล่าง

ตัวอย่างโค้ด

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <style>
    body { padding: 1%; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
    * { box-sizing: border-box; }
    .left, .right, .center {
      float: left; width: 33%; color: white; padding: 10px; height: 200px; text-align: center;
    }
    .left { background-color: tomato; }
    .right { background-color: teal; }
    .center { background-color: rgb(166, 71, 255); }
    .container:after { clear: both; }
    .closebtn {
      float: right; color: white; font-size: 35px; cursor: pointer;
    }
    .closebtn:hover { transform: scale(1.5); }
    .containerTab {
      padding: 20px; width: 99%; color: white; display: none;
    }
  </style>
</head>
<body>
  <h1 style="text-align: center;">Three Column grid example</h1>
  <div class="container">
    <div class="left" onclick="openTab('tab1');"><h1>Some text on the left</h1></div>
    <div class="center" onclick="openTab('tab2');"><h1>Some text in center</h1></div>
    <div class="right" onclick="openTab('tab3');"><h1>Some text on the right</h1></div>
  </div>
  <div id="tab1" class="containerTab" style="display:none;background:tomato">
    <span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
    <h2>Tab 1</h2><p>Lorem ipsum...</p>
  </div>
  <div id="tab2" class="containerTab" style="display:none;background:rgb(166, 71, 255)">
    <span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
    <h2>Tab 2</h2><p>Lorem ipsum...</p>
  </div>
  <div id="tab3" class="containerTab" style="display:none;background:teal">
    <span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
    <h2>Tab 3</h2><p>Lorem ipsum...</p>
  </div>
  <script>
    function openTab(tabName) {
      var i, x;
      x = document.querySelectorAll(".containerTab");
      Array.from(x).forEach(item => { item.style.display = "none"; });
      document.getElementById(tabName).style.display = "block";
    }
  </script>
</body>
</html>

หลักการทำงาน

  1. Grid Items: 3 คอลัมน์ (.left, .center, .right) Float ซ้าย Width 33%
  2. Hidden Panels: 3 Panel (.containerTab) ซ่อนอยู่ (display: none) ใต้ Grid
  3. Click Handler: onclick เรียก openTab('tabId')
  4. openTab(): ซ่อน Panel ทั้งหมด แล้วแสดง Panel ที่ตรงกับ ID
  5. Close Button: กด × เพื่อซ่อน Panel นั้นๆ

Modern Approach: CSS Grid + Details/Summary (No JS)

<div class="expanding-grid">
  <details class="grid-item">
    <summary><h2>Item 1</h2></summary>
    <div class="expanded-content">Detail content...</div>
  </details>
  <details class="grid-item">...</details>
  <details class="grid-item">...</details>
</div>

JavaScript Version ที่ปรับปรุง (Accessible + Animated)

const items = document.querySelectorAll('.grid-item');
const panels = document.querySelectorAll('.expanded-panel');

items.forEach((item, index) => {
  item.addEventListener('click', () => togglePanel(index));
  item.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') togglePanel(index);
  });
});

function togglePanel(index) {
  const isOpen = panels[index].hidden === false;
  panels.forEach(p => p.hidden = true);
  items.forEach(i => i.setAttribute('aria-expanded', 'false'));
  
  if (!isOpen) {
    panels[index].hidden = false;
    items[index].setAttribute('aria-expanded', 'true');
    panels[index].style.animation = 'slideDown 0.3s ease';
  }
}

// CSS Animation
@keyframes slideDown {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

Use Cases

  • Product Features Grid
  • Team Members + Bio
  • FAQ Sections
  • Portfolio Projects + Details
  • Service Offerings