Back
A clean, simple pagination design with just the essential elements for a distraction-free interface.
<div class="minimal-pagination">
<span class="page-item" data-page="1">1</span>
<span class="page-item" data-page="2">2</span>
<span class="page-item active" data-page="3">3</span>
<span class="page-item" data-page="4">4</span>
<span class="page-item" data-page="5">5</span>
</div>
Our HTML structure is intentionally minimal:
- We use a simple container with the class "minimal-pagination"
- Each page number is a span element with the class "page-item"
- We include a data attribute to store the page number for JavaScript
- The active page has an additional "active" class
- No previous/next buttons - just the page numbers themselves
document.addEventListener('DOMContentLoaded', () => {
const pageItems = document.querySelectorAll('.page-item');
let currentPage = 3; // Start with page 3 active
function setActivePage(newPage) {
// Remove active class from current page
const currentActive = document.querySelector('.page-item.active');
if (currentActive) {
currentActive.classList.remove('active');
}
// Add active class to new page
const newActive = document.querySelector(`.page-item[data-page="${newPage}"]`);
if (newActive) {
newActive.classList.add('active');
currentPage = newPage;
}
// In a real app, you would load content for the new page here
console.log(`Changed to page ${newPage}`);
}
// Add click event listeners to all page items
pageItems.forEach(item => {
item.addEventListener('click', () => {
const pageNum = parseInt(item.getAttribute('data-page'));
if (pageNum !== currentPage) {
setActivePage(pageNum);
}
});
});
});
Our JavaScript is simple and focused:
- We track the current active page
- We provide a function to change the active page
- We add click event listeners to all page numbers
- We only update if the user clicks on a different page
/* Container */
.minimal-pagination {
--active-color: #111827;
--text-color: #9ca3af;
--hover-color: #4b5563;
--spacing: 24px;
--text-size: 18px;
display: flex;
align-items: center;
justify-content: center;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
user-select: none;
}
/* Page items */
.page-item {
color: var(--text-color);
font-size: var(--text-size);
margin: 0 calc(var(--spacing) / 2);
cursor: pointer;
position: relative;
transition: color 0.2s ease;
}
Now let's style the different states of our pagination items:
/* Hover state */
.page-item:hover {
color: var(--hover-color);
}
/* Active state */
.page-item.active {
color: var(--active-color);
font-weight: 600;
}
/* Underline indicator for active page */
.page-item.active::after {
content: '';
position: absolute;
bottom: -6px;
left: 0;
right: 0;
height: 2px;
background-color: var(--active-color);
border-radius: 2px;
transform: scaleX(0.8);
transition: transform 0.2s ease;
}
/* Hover effect for active page underline */
.page-item.active:hover::after {
transform: scaleX(1);
}
Finally, let's add accessibility enhancements and dark mode support:
/* Focus indicator for keyboard navigation */
.page-item:focus-visible {
outline: 2px solid var(--active-color);
outline-offset: 2px;
border-radius: 2px;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.minimal-pagination {
--active-color: #f9fafb;
--text-color: #6b7280;
--hover-color: #d1d5db;
}
}
The beauty of this minimalist pagination lies in its simplicity:
- Clean aesthetics: No borders, backgrounds, or unnecessary elements
- Focus on content: The design doesn't compete with your main content
- Subtle interactions: Delicate animations provide feedback without distraction
- Adaptability: Works well in both light and dark interfaces
- Visual hierarchy: The active page is clearly differentiated without being overwhelming
- Reduced cognitive load: Users can focus on the content rather than the navigation
This minimalist pagination is perfect for blogs, portfolios, photography sites, or any design-focused website where the interface should complement the content rather than draw attention to itself.<div class="minimal-pagination">
<span class="page-item" data-page="1">1</span>
<span class="page-item" data-page="2">2</span>
<span class="page-item active" data-page="3">3</span>
<span class="page-item" data-page="4">4</span>
<span class="page-item" data-page="5">5</span>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const pageItems = document.querySelectorAll('.page-item');
let currentPage = 3; // Start with page 3 active
function setActivePage(newPage) {
// Remove active class from current page
const currentActive = document.querySelector('.page-item.active');
if (currentActive) {
currentActive.classList.remove('active');
}
// Add active class to new page
const newActive = document.querySelector(`.page-item[data-page="${newPage}"]`);
if (newActive) {
newActive.classList.add('active');
currentPage = newPage;
}
// In a real app, you would load content for the new page here
console.log(`Changed to page ${newPage}`);
}
// Add click event listeners to all page items
pageItems.forEach(item => {
item.addEventListener('click', () => {
const pageNum = parseInt(item.getAttribute('data-page'));
if (pageNum !== currentPage) {
setActivePage(pageNum);
}
});
});
});
</script>
<style>
/* Container */
.minimal-pagination {
--active-color: #111827;
--text-color: #9ca3af;
--hover-color: #4b5563;
--spacing: 24px;
--text-size: 18px;
display: flex;
align-items: center;
justify-content: center;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
user-select: none;
}
/* Page items */
.page-item {
color: var(--text-color);
font-size: var(--text-size);
margin: 0 calc(var(--spacing) / 2);
cursor: pointer;
position: relative;
transition: color 0.2s ease;
}
/* Hover state */
.page-item:hover {
color: var(--hover-color);
}
/* Active state */
.page-item.active {
color: var(--active-color);
font-weight: 600;
}
/* Underline indicator for active page */
.page-item.active::after {
content: '';
position: absolute;
bottom: -6px;
left: 0;
right: 0;
height: 2px;
background-color: var(--active-color);
border-radius: 2px;
transform: scaleX(0.8);
transition: transform 0.2s ease;
}
/* Hover effect for active page underline */
.page-item.active:hover::after {
transform: scaleX(1);
}
/* Focus indicator for keyboard navigation */
.page-item:focus-visible {
outline: 2px solid var(--active-color);
outline-offset: 2px;
border-radius: 2px;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.minimal-pagination {
--active-color: #f9fafb;
--text-color: #6b7280;
--hover-color: #d1d5db;
}
}
</style>
Thank you for reading this article.
Comments