Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Pure CSS Expand/Collapse - Constant Speed</title>
- <style>
- * {
- box-sizing: border-box;
- }
- body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
- line-height: 1.6;
- margin: 0;
- padding: 40px 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- min-height: 100vh;
- }
- .container {
- max-width: 600px;
- margin: 0 auto;
- background: white;
- border-radius: 12px;
- box-shadow: 0 20px 40px rgba(0,0,0,0.1);
- overflow: hidden;
- }
- .accordion-item {
- border-bottom: 1px solid #e2e8f0;
- }
- .accordion-item:last-child {
- border-bottom: none;
- }
- /* Hide the checkbox */
- .accordion-checkbox {
- display: none;
- }
- /* Style the label as the header */
- .accordion-header {
- background: #f8fafc;
- padding: 20px 24px;
- cursor: pointer;
- user-select: none;
- display: flex;
- justify-content: space-between;
- align-items: center;
- transition: all 0.3s ease;
- position: relative;
- }
- .accordion-header:hover {
- background: #f1f5f9;
- }
- /* Active state when checkbox is checked */
- .accordion-checkbox:checked + .accordion-header {
- background: #3b82f6;
- color: white;
- }
- .accordion-title {
- font-size: 18px;
- font-weight: 600;
- margin: 0;
- }
- .accordion-icon {
- width: 24px;
- height: 24px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: transform 0.3s ease;
- }
- .accordion-icon::before {
- content: '+';
- font-size: 20px;
- font-weight: bold;
- line-height: 1;
- }
- /* Rotate icon when expanded */
- .accordion-checkbox:checked + .accordion-header .accordion-icon {
- transform: rotate(45deg);
- }
- /* CONSTANT SPEED ANIMATION - CSS Grid Technique */
- .accordion-content {
- display: grid;
- grid-template-rows: 0fr;
- transition: grid-template-rows 0.4s cubic-bezier(0.4, 0, 0.2, 1);
- }
- /* Expanded state - 1fr means "take available space" */
- .accordion-checkbox:checked ~ .accordion-content {
- grid-template-rows: 1fr;
- }
- /* The wrapper inside grid must have overflow hidden */
- .accordion-body-wrapper {
- overflow: hidden;
- }
- .accordion-body {
- padding: 24px;
- color: #4a5568;
- line-height: 1.7;
- }
- .accordion-body h3 {
- color: #2d3748;
- margin-top: 0;
- margin-bottom: 16px;
- }
- .accordion-body p {
- margin-bottom: 16px;
- }
- .accordion-body ul {
- margin-bottom: 16px;
- padding-left: 20px;
- }
- .accordion-body li {
- margin-bottom: 8px;
- }
- .code-block {
- background: #1a202c;
- color: #e2e8f0;
- padding: 16px;
- border-radius: 8px;
- font-family: 'Courier New', monospace;
- font-size: 14px;
- overflow-x: auto;
- margin: 16px 0;
- }
- /* Demo styles */
- .demo-section {
- margin: 40px 0;
- }
- .demo-title {
- text-align: center;
- color: white;
- font-size: 24px;
- font-weight: 600;
- margin-bottom: 20px;
- }
- /* Single-open accordion using radio buttons */
- .single-accordion {
- margin-top: 40px;
- }
- .single-accordion .accordion-radio {
- display: none;
- }
- .single-accordion .accordion-radio:checked + .accordion-header {
- background: #10b981;
- color: white;
- }
- .single-accordion .accordion-radio:checked + .accordion-header .accordion-icon {
- transform: rotate(45deg);
- }
- .single-accordion .accordion-radio:checked ~ .accordion-content {
- grid-template-rows: 1fr;
- }
- .single-accordion .accordion-header {
- background: #f0fdf4;
- }
- .single-accordion .accordion-header:hover {
- background: #dcfce7;
- }
- /* Accessibility improvements */
- .accordion-header:focus-within {
- outline: 2px solid #3b82f6;
- outline-offset: 2px;
- }
- /* Demo content styles for visual comparison */
- .short-content {
- background: #fef3c7;
- padding: 16px;
- border-radius: 8px;
- margin: 16px 0;
- border-left: 4px solid #f59e0b;
- }
- .long-content {
- background: #dbeafe;
- padding: 16px;
- border-radius: 8px;
- margin: 16px 0;
- border-left: 4px solid #3b82f6;
- }
- </style>
- </head>
- <body>
- <div class="demo-section">
- <h1 class="demo-title">Constant Speed Expand/Collapse</h1>
- <p style="text-align: center; color: white; opacity: 0.9;">All panels open at the same rate regardless of content height</p>
- </div>
- <!-- Multi-open accordion demonstrating constant speed -->
- <div class="container">
- <div class="accordion-item">
- <input type="checkbox" id="accordion1" class="accordion-checkbox">
- <label for="accordion1" class="accordion-header">
- <h3 class="accordion-title">Short Content Panel</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <div class="short-content">
- <p><strong>This panel has minimal content.</strong></p>
- <p>Notice how it opens at the same speed as the longer panels below!</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="accordion-item">
- <input type="checkbox" id="accordion2" class="accordion-checkbox">
- <label for="accordion2" class="accordion-header">
- <h3 class="accordion-title">CSS Grid Solution</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <h3>The Grid Template Rows Technique</h3>
- <p>This solution uses CSS Grid's fractional units to achieve constant animation speed:</p>
- <div class="code-block">
- .accordion-content {
- display: grid;
- grid-template-rows: 0fr;
- transition: grid-template-rows 0.4s ease;
- }
- .accordion-checkbox:checked ~ .accordion-content {
- grid-template-rows: 1fr;
- }
- .accordion-body-wrapper {
- overflow: hidden;
- }
- </div>
- <p>The <code>fr</code> unit represents a fraction of available space. Transitioning from <code>0fr</code> to <code>1fr</code> creates a proportional animation that adapts to any content height.</p>
- <p>This means short content and tall content both animate for the same duration, creating a consistent user experience.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="accordion-item">
- <input type="checkbox" id="accordion3" class="accordion-checkbox">
- <label for="accordion3" class="accordion-header">
- <h3 class="accordion-title">Medium Length Content</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <h3>Why Constant Speed Matters</h3>
- <p>When using the max-height technique with a fixed value like 1000px:</p>
- <ul>
- <li>Short content (100px) reaches full height quickly, then sits idle</li>
- <li>Medium content (400px) takes longer to reach full expansion</li>
- <li>Tall content (800px) uses almost the full animation duration</li>
- </ul>
- <p>This creates an inconsistent and jarring user experience where panels seem to animate at different speeds.</p>
- <div class="long-content">
- <p><strong>The CSS Grid approach solves this by:</strong></p>
- <ul>
- <li>Using fractional units that scale proportionally</li>
- <li>Always using the full animation duration regardless of content height</li>
- <li>Creating smooth, predictable animations</li>
- <li>Eliminating the need to guess maximum content heights</li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="accordion-item">
- <input type="checkbox" id="accordion4" class="accordion-checkbox">
- <label for="accordion4" class="accordion-header">
- <h3 class="accordion-title">Very Long Content Panel</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <h3>Extended Content Example</h3>
- <p>This panel contains significantly more content to demonstrate how the CSS Grid technique maintains consistent animation timing.</p>
- <h3>Technical Details</h3>
- <p>The grid approach works because:</p>
- <ul>
- <li><strong>0fr</strong> means "allocate zero fractions of available space" (collapsed)</li>
- <li><strong>1fr</strong> means "allocate one fraction of available space" (expanded to fit content)</li>
- <li>The transition animates the fractional value, not a fixed pixel value</li>
- <li>CSS automatically calculates the proper pixel heights during animation</li>
- </ul>
- <div class="long-content">
- <h3>Browser Support</h3>
- <p>This technique works in all modern browsers that support CSS Grid (which is virtually all browsers in use today):</p>
- <ul>
- <li>Chrome 57+ (March 2017)</li>
- <li>Firefox 52+ (March 2017)</li>
- <li>Safari 10.1+ (March 2017)</li>
- <li>Edge 16+ (October 2017)</li>
- </ul>
- </div>
- <h3>Performance Benefits</h3>
- <p>Unlike JavaScript-based solutions that calculate heights and manually animate values, this pure CSS approach:</p>
- <ul>
- <li>Runs on the GPU for smooth 60fps animations</li>
- <li>Doesn't block the main thread</li>
- <li>Works even if JavaScript is disabled</li>
- <li>Has no runtime overhead or memory leaks</li>
- <li>Maintains smooth scrolling during animations</li>
- </ul>
- <p>Notice how this lengthy panel opens at exactly the same rate as the short panel above, creating a consistent and professional user experience!</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- Single-open version -->
- <div class="container single-accordion">
- <h2 style="padding: 20px 24px; margin: 0; background: #f0fdf4; font-size: 16px; color: #065f46; border-bottom: 1px solid #e2e8f0;">Single-Open Accordion (Radio Buttons)</h2>
- <div class="accordion-item">
- <input type="radio" name="single-accordion" id="single1" class="accordion-radio">
- <label for="single1" class="accordion-header">
- <h3 class="accordion-title">Brief Content</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <p>Short content that opens at a consistent speed.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="accordion-item">
- <input type="radio" name="single-accordion" id="single2" class="accordion-radio">
- <label for="single2" class="accordion-header">
- <h3 class="accordion-title">Extensive Documentation</h3>
- <div class="accordion-icon"></div>
- </label>
- <div class="accordion-content">
- <div class="accordion-body-wrapper">
- <div class="accordion-body">
- <h3>Comprehensive Guide</h3>
- <p>This section contains much more detailed information to demonstrate the consistent animation timing.</p>
- <p>Key advantages of this approach:</p>
- <ul>
- <li>Pure HTML/CSS implementation</li>
- <li>Constant animation speed regardless of content height</li>
- <li>No JavaScript dependencies</li>
- <li>Excellent browser support</li>
- <li>GPU-accelerated animations</li>
- <li>Accessible by default</li>
- </ul>
- <p>The animation duration remains exactly 0.4 seconds whether the content is 50 pixels tall or 500 pixels tall.</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement