Tabbed interface optimized for small screens

Loading

A well-designed tabbed interface is a clean and efficient way to organize content. However, on small screens like mobile devices, standard tabs can quickly become cluttered or unreadable. Optimizing a tabbed layout for responsiveness ensures a seamless experience across all devices.

Here’s a step-by-step guide (1000 words approx) to build and optimize a responsive tabbed interface in Power Pages, with a focus on mobile-friendliness.


1. Understand the Use Case for Tabs

Tabbed interfaces are useful when:

  • You want to separate related content categories without overwhelming users.
  • You want to conserve vertical space.
  • You’re showing content that’s mutually exclusive in context.

2. Basic Tab Layout (HTML + CSS + JavaScript)

Start by defining your tab structure using HTML. In Power Pages, this can be added via Web Templates or within Web Files using Liquid.

HTML:

<div class="tab-container">
<ul class="tab-nav">
<li class="tab-link active" data-tab="tab1">Overview</li>
<li class="tab-link" data-tab="tab2">Details</li>
<li class="tab-link" data-tab="tab3">Contact</li>
</ul>

<div id="tab1" class="tab-content active">This is the overview section.</div>
<div id="tab2" class="tab-content">This is the details section.</div>
<div id="tab3" class="tab-content">This is the contact section.</div>
</div>

CSS:

.tab-container {
margin: 1rem;
}

.tab-nav {
display: flex;
overflow-x: auto;
border-bottom: 1px solid #ccc;
list-style: none;
padding-left: 0;
}

.tab-link {
padding: 10px 16px;
cursor: pointer;
white-space: nowrap;
flex-shrink: 0;
border-bottom: 2px solid transparent;
}

.tab-link.active {
border-bottom-color: #0078d4;
font-weight: bold;
}

.tab-content {
display: none;
padding: 1rem 0;
}

.tab-content.active {
display: block;
}

JavaScript:

document.querySelectorAll('.tab-link').forEach(tab => {
tab.addEventListener('click', function () {
const tabId = this.getAttribute('data-tab');

document.querySelectorAll('.tab-link').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));

this.classList.add('active');
document.getElementById(tabId).classList.add('active');
});
});

3. Mobile Optimization: Make Tabs Scrollable

On small screens, tabs can wrap or overflow, making them hard to use. Use horizontal scrolling for tabs:

.tab-nav {
flex-wrap: nowrap;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}

.tab-nav::-webkit-scrollbar {
display: none;
}

4. Responsive Behavior with Media Queries

Adjust padding and text size for better mobile UX:

@media (max-width: 600px) {
.tab-link {
padding: 8px 12px;
font-size: 14px;
}
}

5. Option: Collapse Tabs into Accordion on Mobile

For better accessibility and touch UX on mobile, you can switch to an accordion layout.

JavaScript Approach:

Detect screen width and toggle classes:

function handleResponsiveTabs() {
const isMobile = window.innerWidth <= 600;
const container = document.querySelector('.tab-container');

if (isMobile) {
container.classList.add('accordion-mode');
} else {
container.classList.remove('accordion-mode');
}
}

window.addEventListener('resize', handleResponsiveTabs);
window.addEventListener('load', handleResponsiveTabs);

CSS for Accordion Style:

.accordion-mode .tab-nav {
display: none;
}

.accordion-mode .tab-content {
display: block;
border-bottom: 1px solid #ccc;
}

.accordion-mode .tab-content:not(.active) {
display: none;
}

6. Accessibility Enhancements

Make the tab system screen reader-friendly:

Add ARIA attributes:

<ul class="tab-nav" role="tablist">
<li class="tab-link" role="tab" aria-selected="true" aria-controls="tab1" id="tab1-tab">Overview</li>
...
</ul>

<div id="tab1" role="tabpanel" aria-labelledby="tab1-tab" class="tab-content active">...</div>

Update JavaScript to reflect aria-selected state dynamically.


7. Optional: Load Tab Content Dynamically

For performance, load content on demand using AJAX or Liquid:

document.querySelector('.tab-link[data-tab="tab2"]').addEventListener('click', function () {
fetch('/custom-endpoint')
.then(response => response.text())
.then(html => {
document.getElementById('tab2').innerHTML = html;
});
});

8. Use Bootstrap Components (If Preferred)

If Bootstrap is enabled in your portal, leverage its tab features:

<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-bs-toggle="tab" href="#home" role="tab">Home</a>
</li>
...
</ul>

<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel">...</div>
</div>

Use Bootstrap’s flex-wrap: nowrap; overflow-x: auto utility classes for responsiveness.


9. Testing and Validation

  • Test on actual devices, not just browser resizes.
  • Use tools like Google Lighthouse, axe DevTools, and VoiceOver to check accessibility.
  • Ensure that the tab interface works with keyboard navigation (Tab, Arrow keys, Enter).

10. Real-World Power Pages Integration

Use Liquid for data binding in each tab:

<div id="tab1" class="tab-content active">
{% fetchxml contacts %}
<fetch top="5">
<entity name="contact">
<attribute name="fullname" />
</entity>
</fetch>
{% endfetchxml %}

{% for contact in contacts.results %}
<p>{{ contact.fullname }}</p>
{% endfor %}
</div>

For secure content, use web roles and conditional visibility inside tabs.

Leave a Reply

Your email address will not be published. Required fields are marked *