SnippetUI

Referans Slider

Kullanıcı yorumlarının bir listesini görüntülemek için kaydırıcı bölümü

HTMLCSSJavaScript

CSS ‘kaydırma-snap’ kullanan modern ve pürüzsüz bir atlıkarınca kaydırıcısı. Hızlı tepki verir ve gezinme noktaları ve düğmeleriyle sezgisel kullanıma olanak tanır.

Customer Reviews

Here are some testimonials from people who have used our service.

"

"Thanks to this product, our workflow has completely transformed. Its intuitive interface and great support team make it perfect for our growing business.”

Sarah Jenkins

Aya Sato

Product Manager
"

"I’ve tried many similar tools, but this one stands out. The attention to design details and smooth operability makes daily tasks enjoyable.”

Michael Chen

Kenichi Tanaka

UX Designer
"

"Seamless integration with existing systems saved us weeks of development time. Extremely robust and scales effortlessly with us.”

Elena Rodriguez

Elena Suzuki

CTO
"

"Customer service is exceptional. Whenever I have a question, they reply instantly with helpful solutions. A true partner in our success.”

David Miller

Daisuke Yamada

Operations Director
<div class="testimonial-section">
  <div class="testimonial-header">
    <h2>Customer Reviews</h2>
    <p>Here are some testimonials from people who have used our service.</p>
  </div>
  
  <div class="slider-wrapper">
    <button class="slider-btn prev" aria-label="Previous review">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg>
    </button>
    
    <div class="testimonial-slider" id="testimonial-slider">
      {/* Testimonial 1 */}
      <div class="testimonial-card">
        <div class="quote-icon">"</div>
        <p class="review">"Thanks to this product, our workflow has completely transformed. Its intuitive interface and great support team make it perfect for our growing business."</p>
        <div class="author-info">
          <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=Sarah" alt="Sarah Jenkins" class="avatar" />
          <div>
            <h4 class="author-name">Aya Sato</h4>
            <span class="author-role">Product Manager</span>
          </div>
        </div>
      </div>
      
      {/* Testimonial 2 */}
      <div class="testimonial-card">
        <div class="quote-icon">"</div>
        <p class="review">"I've tried many similar tools, but this one stands out. The attention to design details and smooth operability makes daily tasks enjoyable."</p>
        <div class="author-info">
          <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=Michael" alt="Michael Chen" class="avatar" />
          <div>
            <h4 class="author-name">Kenichi Tanaka</h4>
            <span class="author-role">UX Designer</span>
          </div>
        </div>
      </div>
      
      {/* Testimonial 3 */}
      <div class="testimonial-card">
        <div class="quote-icon">"</div>
        <p class="review">"Seamless integration with existing systems saved us weeks of development time. Extremely robust and scales effortlessly with us."</p>
        <div class="author-info">
          <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=Elena" alt="Elena Rodriguez" class="avatar" />
          <div>
            <h4 class="author-name">Elena Suzuki</h4>
            <span class="author-role">CTO</span>
          </div>
        </div>
      </div>
      
      {/* Testimonial 4 */}
      <div class="testimonial-card">
        <div class="quote-icon">"</div>
        <p class="review">"Customer service is exceptional. Whenever I have a question, they reply instantly with helpful solutions. A true partner in our success."</p>
        <div class="author-info">
          <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=David" alt="David Miller" class="avatar" />
          <div>
            <h4 class="author-name">Daisuke Yamada</h4>
            <span class="author-role">Operations Director</span>
          </div>
        </div>
      </div>
    </div>
    
    <button class="slider-btn next" aria-label="Next review">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
    </button>
  </div>
  
  <div class="slider-dots" id="slider-dots"></div>
</div>
.testimonial-section {
  max-width: 1000px;
  margin: 0 auto;
  padding: 4rem 2rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: #1a1a2e;
}

.testimonial-header {
  text-align: center;
  margin-bottom: 3rem;
}

.testimonial-header h2 {
  font-size: 2.5rem;
  font-weight: 800;
  margin-bottom: 0.5rem;
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.testimonial-header p {
  color: #64748b;
  font-size: 1.1rem;
}

.slider-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.testimonial-slider {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  gap: 2rem;
  padding: 1rem 0;
  /* Hide scrollbar */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE/Edge */
}

.testimonial-slider::-webkit-scrollbar {
  display: none; /* Chrome/Safari */
}

.testimonial-card {
  flex: 0 0 100%;
  scroll-snap-align: center;
  background: #ffffff;
  border-radius: 24px;
  padding: 2.5rem;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.8);
  display: flex;
  flex-direction: column;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

@media (min-width: 768px) {
  .testimonial-card {
    flex: 0 0 calc(50% - 1rem); /* 2-column display */
  }
}

.testimonial-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 25px 50px rgba(0, 0, 0, 0.12);
}

.quote-icon {
  font-size: 4rem;
  line-height: 1;
  color: #e2e8f0;
  margin-bottom: -1rem;
  font-family: serif;
}

.review {
  font-size: 1.125rem;
  line-height: 1.7;
  color: #334155;
  flex-grow: 1;
  margin-bottom: 2rem;
  font-style: italic;
}

.author-info {
  display: flex;
  align-items: center;
  gap: 1rem;
  border-top: 1px solid #f1f5f9;
  padding-top: 1.5rem;
}

.avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid #e2e8f0;
}

.author-name {
  margin: 0 0 0.25rem 0;
  font-weight: 700;
  font-size: 1.1rem;
}

.author-role {
  color: #64748b;
  font-size: 0.9rem;
}

.slider-btn {
  background: #ffffff;
  border: none;
  border-radius: 50%;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  color: #4facfe;
  transition: all 0.2s ease;
  flex-shrink: 0;
  z-index: 10;
}

.slider-btn:hover {
  background: #4facfe;
  color: #ffffff;
  transform: scale(1.05);
}

.slider-btn:active {
  transform: scale(0.95);
}

.slider-dots {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 2rem;
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #cbd5e1;
  border: none;
  cursor: pointer;
  padding: 0;
  transition: all 0.3s ease;
}

.dot.active {
  background: #4facfe;
  width: 24px;
  border-radius: 12px;
}

/* Karanlık mod uyumlu */
@media (prefers-color-scheme: dark) {
  .testimonial-section {
    color: #f8fafc;
  }
  
  .testimonial-header p {
    color: #94a3b8;
  }
  
  .testimonial-card {
    background: #1e293b;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
    border-color: rgba(255, 255, 255, 0.05);
  }
  
  .quote-icon {
    color: #334155;
  }
  
  .review {
    color: #cbd5e1;
  }
  
  .author-info {
    border-top-color: #334155;
  }
  
  .slider-btn {
    background: #1e293b;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  }
  
  .slider-btn:hover {
    background: #4facfe;
  }
  
  .dot {
    background: #475569;
  }
}
document.addEventListener('DOMContentLoaded', () => {
  const slider = document.getElementById('testimonial-slider');
  const dotsContainer = document.getElementById('slider-dots');
  const prevBtn = document.querySelector('.slider-btn.prev');
  const nextBtn = document.querySelector('.slider-btn.next');
  
  if (!slider) return;

  const cards = slider.querySelectorAll('.testimonial-card');
  const cardCount = cards.length;
  
  // Get the number of visible cards based on screen width
  const getVisibleCards = () => window.innerWidth >= 768 ? 2 : 1;
  
  // Generate and update dots
  const updateDots = () => {
    dotsContainer.innerHTML = '';
    const visibleCards = getVisibleCards();
    const dotCount = Math.max(1, cardCount - visibleCards + 1);
    
    for (let i = 0; i < dotCount; i++) {
      const dot = document.createElement('button');
      dot.classList.add('dot');
      if (i === 0) dot.classList.add('active');
      dot.setAttribute('aria-label', `Go to slide ${i + 1}`);
      dot.addEventListener('click', () => scrollToSlide(i));
      dotsContainer.appendChild(dot);
    }
  };

  updateDots();
  
  // Recalculate on resize
  window.addEventListener('resize', () => {
    updateDots();
    updateActiveDot();
  });

  // Scroll to specified slide
  const scrollToSlide = (index) => {
    const cardWidth = cards[0].offsetWidth;
    const gap = parseFloat(window.getComputedStyle(slider).gap) || 0;
    slider.scrollTo({
      left: index * (cardWidth + gap),
      behavior: 'smooth'
    });
  };

  // Update active dot based on scroll position
  const updateActiveDot = () => {
    const dots = dotsContainer.querySelectorAll('.dot');
    if (!dots.length) return;
    
    const cardWidth = cards[0].offsetWidth;
    const gap = parseFloat(window.getComputedStyle(slider).gap) || 0;
    const scrollPosition = slider.scrollLeft;
    
    // Calculate current index
    const activeIndex = Math.round(scrollPosition / (cardWidth + gap));
    
    dots.forEach((dot, index) => {
      dot.classList.toggle('active', index === activeIndex);
    });
  };

  // Link to scroll event
  slider.addEventListener('scroll', updateActiveDot);

  // Scroll control with buttons
  prevBtn.addEventListener('click', () => {
    const cardWidth = cards[0].offsetWidth;
    const gap = parseFloat(window.getComputedStyle(slider).gap) || 0;
    slider.scrollBy({ left: -(cardWidth + gap), behavior: 'smooth' });
  });

  nextBtn.addEventListener('click', () => {
    const cardWidth = cards[0].offsetWidth;
    const gap = parseFloat(window.getComputedStyle(slider).gap) || 0;
    slider.scrollBy({ left: (cardWidth + gap), behavior: 'smooth' });
  });
});