Issue
So I'm creating a page with tabbed content using Twitter's Bootstrap, yet the content of my starting active div is always different than that of my other tabs. For example, I am putting in charts using highcharts.js in my different tabs, yet the active one always shows correctly while the others have an incorrect width.
Check out the example below:
<div class = "row-fluid">
<div class = "span9">
<div class = "row-fluid">
<h3>Test</h3>
<ul class="nav nav-tabs">
<li class = "active">
<a data-toggle = "tab" href = "#one">One</a>
</li>
<li><a data-toggle = "tab" href = "#two">Two</a></li>
<li><a data-toggle = "tab" href = "#three">Three</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="one" >
<h4>One</h4>
<div id = "container1"></div>
<script type = "text/javascript">
$(function () {
$('#container1').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
<div class="tab-pane" id="two" >
<h4>Two</h4>
<div id = "container2"></div>
<script type = "text/javascript">
$(function () {
$('#container2').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
<div class="tab-pane" id="three" >
<h4>Three</h4>
<div id = "container3"></div>
<script type = "text/javascript">
$(function () {
$('#container3').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
</div>
</div>
</div>
<div class = "span3">
<p>Here is the content on my sidebar</p>
</div>
</div>
In this case, switching the active tab on page load makes that chart look correct for me, but the rest always extend all the way to the edge (In the case of my data, which I want to only fill up the space of the span9 div. I just used dummy charts in this case, but it's the same idea.
Here's a JSFiddle: http://jsfiddle.net/dw9tn/
My questions for you all are:
1.) Is this just me?
2.) What exactly is going on when tabs are made active? Looking at the bootstrap css, this seems to deal with display: none and display: block, but I don't have a good understanding of how that works in this case.
3.) Is this a highcharts issue or a bootstrap issue? I noticed this happened to me with non-highchart elements (like showing tweets in the sidebar), so I'm leaning toward bootstrap.
4.) Is there any solution you can find to make everything consistent?
Thanks guys!
Solution
The Cause
This is not a Highcharts issue, at least not by itself, the problem is caused by the fact that Bootstrap uses display: none
to hide inactive tabs:
.tab-content > .tab-pane /* , .pill-content > .pill-pane */ {
display: none; /* this is the problem */
}
This causes Highcharts unable to get the expected width to initialize the chart, thus defaults to 600
(px). This would also happen to other tools using display: none
to hide an element, as
it has no effect on layout (the document is rendered as though the element did not exist).
A CSS only Solution
Instead of working around the issue with an extra redraw or delayed initialization, we can achieve the hidden effect using height: 0; overflow-y: hidden
, this way the hidden tab panes are still in place and have valid width
:
/* bootstrap hack: fix content width inside hidden tabs */
.tab-content > .tab-pane:not(.active) /* , .pill-content > .pill-pane:not(.active) */ {
display: block;
height: 0;
overflow-y: hidden;
}
/* bootstrap hack end */
Update: now we directly target inactive tabs via :not(.active)
, to avoid possible side effect if any.
This solution is seamless, so you no longer have to worry whether the chart is inside a tab-pane or not. And it's efficient as it fixes the width issue in the first place, thus there's no need to workaround the width issue afterward via resize/redraw/reflow using javascript.
Note about CSS Cascade Order
This patch needs to be loaded after bootstrap css, because of CSS cascade order rules, in short, the latter rule wins.
Demo
Tip: switch to the Profile tab to see the difference.
Answered By - ryenus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.