Toggle navigation
☰
Home
HTML
CSS
Scripting
Database
<!DOCTYPE html> <title>My Example</title> <!-- ====================================================================== CSS - Place this in your <head> or in an external stylesheet. ====================================================================== --> <style> :root { --cph-padding: 3rem 1.5rem; --cph-bg-color: #f3f4f6; --cph-slide-text-color: #ffffff; --cph-nav-color: #1f2937; --cph-nav-hover-color: #000000; --cph-dots-color: #d1d5db; --cph-dots-active-color: #1f2937; } .carousel-hero { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: var(--cph-bg-color); padding: var(--cph-padding); width: 100%; } .carousel-hero * { box-sizing: border-box; } .carousel-hero-container { max-width: 1100px; margin: 0 auto; position: relative; } .carousel-hero .carousel-track-container { overflow: hidden; border-radius: 8px; } .carousel-hero .carousel-track { display: flex; transition: transform 0.5s ease-in-out; } .carousel-hero .carousel-slide { flex: 0 0 100%; min-height: 450px; width: 100%; position: relative; display: flex; align-items: flex-end; padding: 2.5rem; background-size: cover; background-position: center; color: var(--cph-slide-text-color); } .carousel-hero .carousel-slide::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 60%, rgba(0,0,0,0.0) 100%); } .carousel-hero .slide-content { position: relative; z-index: 2; max-width: 600px; } .carousel-hero .slide-content h2 { font-size: clamp(1.75rem, 5vw, 2.5rem); margin-top: 0; margin-bottom: 0.5rem; font-weight: 700; line-height: 1.2; } .carousel-hero .slide-content p { margin: 0; line-height: 1.5; font-size: 1rem; } /* Buttons */ .carousel-hero .carousel-button { position: absolute; top: 50%; transform: translateY(-50%); background-color: rgba(255,255,255,0.8); border: none; width: 40px; height: 40px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background-color 0.3s ease; z-index: 10; box-shadow: 0 2px 5px rgba(0,0,0,0.2); } .carousel-hero .carousel-button:hover { background-color: #fff; } .carousel-hero .carousel-button.prev { left: 1rem; } .carousel-hero .carousel-button.next { right: 1rem; } .carousel-hero .carousel-button svg { width: 24px; height: 24px; stroke: var(--cph-nav-color); } /* Dots */ .carousel-hero .carousel-nav { display: flex; justify-content: center; gap: 0.75rem; margin-top: 1.5rem; } .carousel-hero .carousel-dot { border: none; background-color: var(--cph-dots-color); width: 12px; height: 12px; border-radius: 50%; padding: 0; cursor: pointer; transition: background-color 0.3s ease; } .carousel-hero .carousel-dot.active { background-color: var(--cph-dots-active-color); } </style> <!-- ====================================================================== HTML - Place this in your <body> where you want the component to appear. ====================================================================== --> <section class="carousel-hero"> <div class="carousel-hero-container" role="region" aria-roledescription="carousel" aria-label="Featured Projects"> <div class="carousel-track-container"> <div class="carousel-track"> <!-- Slide 1 --> <div class="carousel-slide" role="group" aria-roledescription="slide" aria-label="1 of 3" style="background-image:url('https://images.unsplash.com/photo-1555949963-ff9fe0c870eb?q=80&w=1200')"> <div class="slide-content"> <h2>Project Zenith: Enterprise SaaS</h2> <p>A comprehensive cloud-based solution for managing corporate logistics.</p> </div> </div> <!-- Slide 2 --> <div class="carousel-slide" role="group" aria-roledescription="slide" aria-label="2 of 3" style="background-image:url('https://images.unsplash.com/photo-1542744095-291d1f67b221?q=80&w=1200')"> <div class="slide-content"> <h2>Aura Health: Mobile Wellness App</h2> <p>An intuitive mobile app designed for tracking fitness and mental wellbeing.</p> </div> </div> <!-- Slide 3 --> <div class="carousel-slide" role="group" aria-roledescription="slide" aria-label="3 of 3" style="background-image:url('https://images.unsplash.com/photo-1516321497487-e288fb19713f?q=80&w=1200')"> <div class="slide-content"> <h2>Nomad Creative: Brand Website</h2> <p>A portfolio website for a digital creative agency focused on user engagement.</p> </div> </div> </div> </div> <button class="carousel-button prev" aria-label="Previous slide"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 18L9 12L15 6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> </button> <button class="carousel-button next" aria-label="Next slide"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 18L15 12L9 6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> </button> <div class="carousel-nav" aria-label="Slide navigation"> <!-- Dots will be generated by JavaScript --> </div> </div> </section> <!-- ====================================================================== JavaScript - Place this right before your closing </body> tag. ====================================================================== --> <script> (function(){ const carouselContainer = document.querySelector('.carousel-hero-container'); if (!carouselContainer) return; const track = carouselContainer.querySelector('.carousel-track'); const slides = Array.from(track.children); const nextButton = carouselContainer.querySelector('.carousel-button.next'); const prevButton = carouselContainer.querySelector('.carousel-button.prev'); const nav = carouselContainer.querySelector('.carousel-nav'); // Create nav dots slides.forEach((slide, i) => { const dot = document.createElement('button'); dot.classList.add('carousel-dot'); dot.setAttribute('aria-label', `Go to slide ${i + 1}`); if (i === 0) dot.classList.add('active'); nav.appendChild(dot); dot.addEventListener('click', e => { const currentSlide = track.querySelector('.is-selected'); const currentIndex = slides.findIndex(slide => slide === currentSlide); moveToSlide(currentIndex, i); }); }); const dots = Array.from(nav.children); const slideWidth = slides[0].getBoundingClientRect().width; const setSlidePosition = (slide, index) => { slide.style.left = slideWidth * index + 'px'; }; // Initially arrange slides side-by-side, but this is handled by Flexbox // slides.forEach(setSlidePosition); // Initial setup slides[0].classList.add('is-selected'); const moveToSlide = (current, target) => { const targetSlide = slides[target]; const currentSlide = slides[current]; track.style.transform = `translateX(-${targetSlide.style.left || (target * slideWidth)}px)`; currentSlide.classList.remove('is-selected'); targetSlide.classList.add('is-selected'); const currentDot = nav.querySelector('.active'); currentDot.classList.remove('active'); dots[target].classList.add('active'); // Show/hide prev/next buttons at ends if (target === 0) { prevButton.style.display = 'none'; nextButton.style.display = 'block'; } else if (target === slides.length - 1) { prevButton.style.display = 'block'; nextButton.style.display = 'none'; } else { prevButton.style.display = 'block'; nextButton.style.display = 'block'; } }; // Initial button state prevButton.style.display = 'none'; prevButton.addEventListener('click', e => { const currentSlide = track.querySelector('.is-selected'); const currentIndex = slides.findIndex(slide => slide === currentSlide); const prevIndex = currentIndex - 1; moveToSlide(currentIndex, prevIndex); }); nextButton.addEventListener('click', e => { const currentSlide = track.querySelector('.is-selected'); const currentIndex = slides.findIndex(slide => slide === currentSlide); const nextIndex = currentIndex + 1; moveToSlide(currentIndex, nextIndex); }); // Recalculate width on resize to be robust window.addEventListener('resize', () => { const currentSlide = track.querySelector('.is-selected'); const currentIndex = slides.findIndex(slide => slide === currentSlide); const newSlideWidth = slides[0].getBoundingClientRect().width; track.style.transition = 'none'; // Disable transition for instant adjustment track.style.transform = `translateX(-${currentIndex * newSlideWidth}px)`; setTimeout(() => { track.style.transition = 'transform 0.5s ease-in-out'; }, 10); }); })(); </script>