I was wondering if there is anyway to create scrolling tabs without using JavaScript. I've been assigned a task to strictly use HTML and CSS, that's it. The code below is the best solution I could find to create tabs without using anything else besides HTML and CSS. I've found some code for scrolling tabs online, but again it uses JavaScript. So, is it possible to do scrolling tabs with just HTML and CSS? Anything helps, thanks!
.tabs
{position: relative;
min-height: 200px;
clear: both;
margin: 25px 0;}
.tab
{float: left;}
.tab label
{background: #eee;
padding: 10px;
border: 1px solid #ccc;
margin-left: -1px;
cursor:pointer;
position: relative;
left: 1px; }
.tab [type=radio]
{display: none;}
.content {position: absolute;
top: 28px;
left: 0;
background: white;
height:100px;
right: 0;
bottom: 0;
padding: 20px;
border: 1px solid #ccc;}
[type=radio]:checked ~ label
{background: white;
border-bottom: 1px solid white;
z-index: 2;}
[type=radio]:checked ~ label ~ .content
{z-index: 1;}
<div class="tabs">
<div class="tab">
<input name="tab-group-1" id="tab-1" type="radio"/>
<label for="tab-1">Tab One</label>
<div class="content">
Content 1
</div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-2" type="radio"/>
<label for="tab-2">Tab Two</label>
<div class="content"> Content 2 </div>
</div>
</div>
So this would probably be better done using JavaScript, but a solution does exist in CSS, if you're willing to allow certain constraints on widths and heights and where the scrollbar ends up.
The basic idea is to make the tabs themselves be inline-block
, and have their container have overflow-x: auto
. That will put a horizontal scrollbar on the container when the tabs get too big.
That said, that requires the container to have a fixed size, and you have to force the content to have a fixed size too if you're going to keep the content elements inside each of the tabs' div
s. I wouldn't want to build it this way if I could avoid it, but this is a pure HTML-and-CSS solution.
A runnable snippet, derived from your original, is below. I set the width on the container specifically to 300px
so you can see what the horizontal overflow looks like.
.tabs {
position: relative;
min-height: 200px;
clear: both;
margin: 0;
padding-top: 15px;
width: 300px;
white-space: nowrap;
overflow-x: auto;
}
.tab {
display: inline-block;
vertical-align: top;
}
.tab label {
background: #eee;
padding: 10px;
border: 1px solid #ccc;
margin-left: -1px;
cursor:pointer;
position: relative;
left: 1px;
}
.tab [type=radio] {
display: none;
}
.tab .content {
position: fixed;
white-space: normal;
top: 50px;
left: 0;
background: white;
height: 100px;
right: 0;
bottom: 0;
padding: 20px;
width: 266px;
border: 1px solid #ccc;
}
.tab [type=radio]:checked ~ label {
background: white;
border-bottom: 1px solid white;
z-index: 2;
}
.tab [type=radio]:checked ~ label ~ .content {
z-index: 1;
}
<div class="tabs">
<div class="tab">
<input name="tab-group-1" id="tab-1" type="radio"/>
<label for="tab-1">Tab One</label>
<div class="content">
Content 1
</div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-2" type="radio"/>
<label for="tab-2">Tab Two</label>
<div class="content"> Content 2 </div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-3" type="radio"/>
<label for="tab-3">Tab Three</label>
<div class="content"> Content 3 </div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-4" type="radio"/>
<label for="tab-4">Tab Four</label>
<div class="content"> Content 4 </div>
</div>
</div>
Update: Per request, here's a way to have the horizontal scrollbar sandwiched between the tabs and the content. Bear in mind that this is even hackier than the above solution, really abusing overflow and height control, but it's doable. Just don't try to put anything below the content divs, because that definitely won't work well.
.tabs {
position: relative;
clear: both;
margin: 0;
padding-top: 15px;
width: 300px;
height: 45px;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.tab {
display: inline-block;
vertical-align: top;
}
.tab label {
background: #eee;
padding: 10px;
border: 1px solid #ccc;
margin-left: -1px;
cursor:pointer;
position: relative;
left: 1px;
}
.tab [type=radio] {
display: none;
}
.tab .content {
position: fixed;
white-space: normal;
top: 70px;
left: 0;
background: white;
height:100px;
right: 0;
bottom: 0;
padding: 20px;
width: 266px;
border: 1px solid #ccc;
}
.tab [type=radio]:checked ~ label {
background: white;
border-bottom: 1px solid white;
z-index: 2;
}
.tab [type=radio]:checked ~ label ~ .content {
z-index: 1;
}
<div class="tabs">
<div class="tab">
<input name="tab-group-1" id="tab-1" type="radio"/>
<label for="tab-1">Tab One</label>
<div class="content">
Content 1
</div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-2" type="radio"/>
<label for="tab-2">Tab Two</label>
<div class="content"> Content 2 </div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-3" type="radio"/>
<label for="tab-3">Tab Three</label>
<div class="content"> Content 3 </div>
</div>
<div class="tab">
<input name="tab-group-1" id="tab-4" type="radio"/>
<label for="tab-4">Tab Four</label>
<div class="content"> Content 4 </div>
</div>
</div>
This can be done by moving the labels into a separate div
and using the focus
hack to highlight the tabs. Here is a working JSFiddle.
<head>
<title>Test Page</title>
<style>
.wrapper
{
width:800px;
margin-left:auto;
margin-right:auto;
}
.tab-radio
{
display:none;
}
.tabs
{
font-size: 0;
margin: 0;
}
.labels
{
overflow-y: auto;
white-space: nowrap;
}
.labels .tab-label
{
background: #eee;
border: 1px solid #ccc;
display: inline-block;
font-size: 1rem;
left: 1px;
margin-left: -1px;
padding: 5px;
position: relative;
vertical-align: bottom;
}
.tabs .tab-panel
{
position: fixed;
display: inline-block;
overflow: hidden;
position: relative;
height: 0;
width: 0;
}
.tabs .tab-content
{
display: block;
float: left;
font-size: 1rem;
width: 100%;
white-space: normal;
}
span:focus
{
outline: none;
}
span:focus > .tab-label
{
background: white;
}
.tabs .tab [type="radio"]:checked ~ .tab-panel
{
display: inline;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="labels">
<span tabindex="0">
<label class="tab-label" for="tab-tab1">Tab Caption 1</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-0">Tab Caption 2</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-1">Tab Caption 3</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-2">Tab Caption 4</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-3">Tab Caption 5</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-4">Tab Caption 6</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-5">Tab Caption 7</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-6">Tab Caption 8</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-7">Tab Caption 9</label>
</span>
<span tabindex="0">
<label class="tab-label" for="tab-tab2-8">Tab Caption 10</label>
</span>
</div>
<div class="tabs">
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab1" name="tabs-main" checked>
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 1</h2>
<p>A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text. A long piece of text.</p>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-0" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 2</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-1" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 3</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-2" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 4</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-3" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 5</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-4" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 6</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-5" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 7</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-6" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 8</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-7" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 9</h2>
</div>
</div>
</div>
<div class="tab">
<input class="tab-radio" type="radio" id="tab-tab2-8" name="tabs-main">
<div class="tab-panel">
<div class="tab-content">
<h2>Tab 10</h2>
</div>
</div>
</div>
</div>
</div>
</body>
HTML and CSS can not scrolling. Only JavaScript. If you want scrolling in DIV: HTML: How to create a DIV with only vertical scroll-bars for long paragraphs?