<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
<nav class="navbar">
<div class="nav-content">
<div class="logo">
<ion-icon name="rocket-outline"></ion-icon>
Smooth Scroll
</div>
<div class="nav-links">
<button class="nav-btn" data-scroll="home">
<ion-icon name="home-outline"></ion-icon>
Home
</button>
<button class="nav-btn" data-scroll="features">
<ion-icon name="sparkles-outline"></ion-icon>
Features
</button>
<button class="nav-btn" data-scroll="methods">
<ion-icon name="code-slash-outline"></ion-icon>
Methods
</button>
<button class="nav-btn" data-scroll="examples">
<ion-icon name="bulb-outline"></ion-icon>
Examples
</button>
<button class="nav-btn" data-scroll="contact">
<ion-icon name="mail-outline"></ion-icon>
Contact
</button>
</div>
</div>
</nav>
<div class="content">
<section class="hero" id="home">
<h1>Smooth Scroll to Element</h1>
<p>Learn how to implement smooth scrolling to specific elements on your webpage using JavaScript. Click the navigation buttons above to see smooth scrolling in action!</p>
</section>
<section class="section" id="features">
<h2>
<ion-icon name="star-outline"></ion-icon>
Key Features
</h2>
<p>Smooth scrolling enhances user experience by providing seamless navigation between different sections of your webpage. Here are the main benefits:</p>
<div class="feature-grid">
<div class="feature-card">
<ion-icon name="flash-outline"></ion-icon>
<h3>Instant Navigation</h3>
<p>Jump to any section instantly with smooth animation</p>
</div>
<div class="feature-card">
<ion-icon name="eye-outline"></ion-icon>
<h3>Visual Appeal</h3>
<p>Creates a modern, polished user experience</p>
</div>
<div class="feature-card">
<ion-icon name="layers-outline"></ion-icon>
<h3>Easy Integration</h3>
<p>Simple to implement with vanilla JavaScript</p>
</div>
<div class="feature-card">
<ion-icon name="construct-outline"></ion-icon>
<h3>Customizable</h3>
<p>Full control over scroll behavior and timing</p>
</div>
</div>
<div class="demo-buttons">
<button class="demo-btn" data-scroll="methods">
<ion-icon name="arrow-down-outline"></ion-icon>
Scroll to Methods
</button>
<button class="demo-btn" data-scroll="examples">
<ion-icon name="arrow-down-outline"></ion-icon>
Scroll to Examples
</button>
</div>
</section>
<section class="section" id="methods">
<h2>
<ion-icon name="code-working-outline"></ion-icon>
Implementation Methods
</h2>
<p>There are several ways to implement smooth scrolling to elements. Here are the most common approaches:</p>
<div class="info-box">
<h3>
<ion-icon name="information-circle-outline"></ion-icon>
Method 1: CSS Only
</h3>
<div class="code-block">
<span class="keyword">html</span> {
scroll-behavior: <span class="string">smooth</span>;
}
</div>
<p>The simplest method - just add this to your CSS and all anchor links will scroll smoothly.</p>
</div>
<div class="info-box">
<h3>
<ion-icon name="information-circle-outline"></ion-icon>
Method 2: scrollIntoView()
</h3>
<div class="code-block">
<span class="comment">// Scroll to element smoothly</span>
<span class="keyword">const</span> element = document.<span class="function">getElementById</span>(<span class="string">'section-id'</span>);
element.<span class="function">scrollIntoView</span>({
behavior: <span class="string">'smooth'</span>,
block: <span class="string">'start'</span>
});
</div>
<p>Native JavaScript method with good browser support and customization options.</p>
</div>
<div class="info-box">
<h3>
<ion-icon name="information-circle-outline"></ion-icon>
Method 3: Custom Animation
</h3>
<div class="code-block">
<span class="keyword">function</span> <span class="function">smoothScrollTo</span>(element) {
<span class="keyword">const</span> targetPosition = element.<span class="function">getBoundingClientRect</span>().top;
<span class="keyword">const</span> startPosition = window.pageYOffset;
<span class="keyword">const</span> distance = targetPosition;
<span class="keyword">const</span> duration = <span class="string">1000</span>;
<span class="keyword">let</span> start = <span class="keyword">null</span>;
<span class="keyword">function</span> <span class="function">animation</span>(currentTime) {
<span class="keyword">if</span> (start === <span class="keyword">null</span>) start = currentTime;
<span class="keyword">const</span> timeElapsed = currentTime - start;
<span class="keyword">const</span> run = <span class="function">ease</span>(timeElapsed, startPosition, distance, duration);
window.<span class="function">scrollTo</span>(<span class="string">0</span>, run);
<span class="keyword">if</span> (timeElapsed < duration) <span class="function">requestAnimationFrame</span>(animation);
}
<span class="keyword">function</span> <span class="function">ease</span>(t, b, c, d) {
t /= d / <span class="string">2</span>;
<span class="keyword">if</span> (t < <span class="string">1</span>) <span class="keyword">return</span> c / <span class="string">2</span> * t * t + b;
t--;
<span class="keyword">return</span> -c / <span class="string">2</span> * (t * (t - <span class="string">2</span>) - <span class="string">1</span>) + b;
}
<span class="function">requestAnimationFrame</span>(animation);
}
</div>
<p>Full control with custom easing functions and animation timing.</p>
</div>
</section>
<section class="section" id="examples">
<h2>
<ion-icon name="create-outline"></ion-icon>
Practical Examples
</h2>
<p>Here are some real-world use cases for smooth scrolling:</p>
<div class="highlight-box">
<h3>📱 Single Page Applications</h3>
<p>Perfect for one-page websites with multiple sections like portfolios, landing pages, and product showcases. Users can navigate seamlessly between different sections without page reloads.</p>
</div>
<div class="highlight-box">
<h3>📚 Documentation Sites</h3>
<p>Great for technical documentation and knowledge bases where users need to jump between different topics. Smooth scrolling makes navigation feel natural and intuitive.</p>
</div>
<div class="highlight-box">
<h3>🛒 E-commerce Sites</h3>
<p>Useful for product pages with multiple sections like reviews, specifications, and related products. Smooth scrolling enhances the shopping experience.</p>
</div>
<div class="info-box">
<h3>
<ion-icon name="checkmark-circle-outline"></ion-icon>
Best Practices
</h3>
<ul>
<li>Use <code>scroll-margin-top</code> to account for fixed headers</li>
<li>Keep animation duration between 500-1000ms for optimal UX</li>
<li>Test on mobile devices - touch scrolling behaves differently</li>
<li>Provide fallbacks for older browsers</li>
<li>Consider accessibility - some users prefer reduced motion</li>
<li>Ensure keyboard navigation still works properly</li>
</ul>
</div>
<div class="demo-buttons">
<button class="demo-btn" data-scroll="home">
<ion-icon name="arrow-up-outline"></ion-icon>
Back to Top
</button>
<button class="demo-btn" data-scroll="contact">
<ion-icon name="arrow-down-outline"></ion-icon>
Go to Contact
</button>
</div>
</section>
<section class="section" id="contact">
<h2>
<ion-icon name="chatbubbles-outline"></ion-icon>
Contact Section
</h2>
<p>This is the final section of the page. You've successfully scrolled through all sections using smooth scrolling!</p>
<p>Notice how the navigation buttons in the header and throughout the page all use smooth scrolling to navigate between sections. The scroll animation provides a much better user experience compared to instant jumping.</p>
<div class="info-box">
<h3>
<ion-icon name="globe-outline"></ion-icon>
Browser Support
</h3>
<ul>
<li><strong>CSS scroll-behavior:</strong> Supported in Chrome, Firefox, Edge (90%+ coverage)</li>
<li><strong>scrollIntoView():</strong> Excellent support across all modern browsers</li>
<li><strong>Custom animations:</strong> Universal support with requestAnimationFrame</li>
</ul>
</div>
<div class="demo-buttons">
<button class="demo-btn" data-scroll="home">
<ion-icon name="home-outline"></ion-icon>
Return Home
</button>
</div>
</section>
<footer>
<p style="font-size: 18px; font-weight: 600; color: #ff6b35; margin-bottom: 10px;">
Smooth Scroll Demo
</p>
<p>Built with HTML, CSS & JavaScript • Try clicking any navigation button!</p>
</footer>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: auto;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(to bottom, #ff6b35 0%, #f7931e 50%, #ff8c42 100%);
color: #333;
}
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(10px);
padding: 20px 40px;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.nav-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.logo {
font-size: 24px;
font-weight: 700;
color: #ff6b35;
display: flex;
align-items: center;
gap: 10px;
}
.nav-links {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.nav-btn {
background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
color: white;
border: none;
border-radius: 8px;
padding: 10px 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 6px;
}
.nav-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 107, 53, 0.4);
}
.content {
padding-top: 100px;
max-width: 1000px;
margin: 0 auto;
padding-left: 40px;
padding-right: 40px;
}
.hero {
background: white;
border-radius: 20px;
padding: 60px 40px;
text-align: center;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
margin-bottom: 40px;
}
.hero h1 {
font-size: 48px;
color: #ff6b35;
margin-bottom: 20px;
}
.hero p {
font-size: 18px;
color: #666;
line-height: 1.6;
}
.section {
background: white;
border-radius: 16px;
padding: 50px 40px;
margin-bottom: 40px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
scroll-margin-top: 100px;
}
.section h2 {
font-size: 32px;
color: #ff6b35;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 15px;
}
.section h2 ion-icon {
font-size: 36px;
}
.section p {
font-size: 16px;
color: #555;
line-height: 1.8;
margin-bottom: 15px;
}
.code-block {
background: #2d2d2d;
color: #f8f8f2;
padding: 25px;
border-radius: 12px;
font-family: 'Courier New', monospace;
font-size: 14px;
overflow-x: auto;
margin: 25px 0;
line-height: 1.8;
}
.code-block .keyword {
color: #ff79c6;
}
.code-block .string {
color: #f1fa8c;
}
.code-block .comment {
color: #6272a4;
}
.code-block .function {
color: #50fa7b;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin: 30px 0;
}
.feature-card {
background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
color: white;
padding: 30px;
border-radius: 12px;
text-align: center;
transition: transform 0.3s ease;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card ion-icon {
font-size: 48px;
margin-bottom: 15px;
}
.feature-card h3 {
font-size: 20px;
margin-bottom: 10px;
}
.feature-card p {
font-size: 14px;
color: rgba(255, 255, 255, 0.9);
}
.info-box {
background: #fff4ed;
border-left: 4px solid #ff6b35;
padding: 20px;
border-radius: 8px;
margin: 25px 0;
}
.info-box h3 {
color: #ff6b35;
margin-bottom: 12px;
font-size: 18px;
display: flex;
align-items: center;
gap: 8px;
}
.info-box ul {
margin-left: 20px;
color: #555;
line-height: 1.8;
}
.info-box li {
margin: 8px 0;
}
.demo-buttons {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin: 25px 0;
}
.demo-btn {
background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
color: white;
border: none;
border-radius: 10px;
padding: 12px 24px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
}
.demo-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(255, 107, 53, 0.4);
}
.demo-btn:active {
transform: translateY(0);
}
footer {
background: white;
padding: 40px;
text-align: center;
color: #666;
margin-top: 40px;
border-radius: 16px 16px 0 0;
}
.highlight-box {
background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
color: white;
padding: 30px;
border-radius: 12px;
margin: 25px 0;
}
.highlight-box h3 {
font-size: 22px;
margin-bottom: 15px;
}
@media (max-width: 768px) {
.navbar {
padding: 15px 20px;
}
.content {
padding-left: 20px;
padding-right: 20px;
}
.hero h1 {
font-size: 32px;
}
.section {
padding: 30px 20px;
}
.nav-links {
width: 100%;
}
.nav-btn {
flex: 1;
justify-content: center;
}
}
// Get all navigation buttons
const navButtons = document.querySelectorAll('[data-scroll]');
// Add click event to each button
navButtons.forEach(button => {
button.addEventListener('click', () => {
const targetId = button.getAttribute('data-scroll');
const targetElement = document.getElementById(targetId);
if (targetElement) {
// Use custom smooth scroll for consistent animation
smoothScrollTo(targetElement);
}
});
});
// Custom smooth scroll function (alternative approach)
function smoothScrollTo(element) {
const targetPosition = element.getBoundingClientRect().top + window.pageYOffset - 90;
const startPosition = window.pageYOffset;
const distance = targetPosition - startPosition;
const duration = 1000;
let start = null;
function animation(currentTime) {
if (start === null) start = currentTime;
const timeElapsed = currentTime - start;
const progress = Math.min(timeElapsed / duration, 1);
// Easing function (easeInOutCubic for smoother animation)
const easeProgress = progress < 0.5
? 4 * progress * progress * progress
: 1 - Math.pow(-2 * progress + 2, 3) / 2;
window.scrollTo(0, startPosition + distance * easeProgress);
if (progress < 1) {
requestAnimationFrame(animation);
}
}
requestAnimationFrame(animation);
}
// Optional: Highlight active section on scroll
window.addEventListener('scroll', () => {
const sections = document.querySelectorAll('.section, .hero');
const scrollPosition = window.pageYOffset + 150;
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.offsetHeight;
const sectionId = section.getAttribute('id');
if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) {
// Remove active class from all buttons
navButtons.forEach(btn => {
if (btn.getAttribute('data-scroll') === sectionId) {
btn.style.opacity = '1';
} else {
btn.style.opacity = '0.7';
}
});
}
});
});
Hi, thanks forthe contribution