Почему вкладки Bootstrap отображают вкладки с вкладками с неправильной шириной при использовании высоких диаграмм?
Итак, я создаю страницу с вкладками с использованием Twitter Bootstrap, но содержание моего активного активного div всегда отличается от содержимого моих других вкладок. Например, я помещаю в диаграммы с использованием highcharts.js на разных вкладках, но активный всегда отображается правильно, а другие имеют неправильную ширину.
Посмотрите пример ниже:
<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>
В этом случае переключение активной вкладки на загрузку страницы делает эту диаграмму корректной для меня, но все остальное всегда распространяется вплоть до края (в случае моих данных, которые я хочу только заполнить пространство из span9 div. В этом случае я использовал макетные диаграммы, но это та же идея.
Здесь JSFiddle: http://jsfiddle.net/dw9tn/
Мои вопросы для всех вас:
1.) Это только я?
2.) Что именно происходит, когда вкладки активируются? Если посмотреть на загрузку css, это, похоже, касается отображения: none и display: block, но у меня нет хорошего понимания того, как это работает в этом случае.
3.) Является ли это важной проблемой или проблемой начальной загрузки? Я заметил, что это произошло со мной с нехарактерными элементами (например, показ твитов на боковой панели), поэтому я склоняюсь к бутстрапу.
4.) Есть ли какое-либо решение, которое вы можете найти, чтобы все было согласовано?
Спасибо, ребята!
Ответы
Ответ 1
Проблема заключается в том, что Highcharts не может вычислить ширину контейнера с CSS: display:none
, поэтому применяется ширина по умолчанию (600 пикселей). Фактически, браузер не может рассчитать ширину для таких элементов.
Например, когда вы будете использовать разделитель для изменения размера окна результатов, диаграмма изменит размер и будет работать. Таким образом, у вас есть три варианта:
- отобразить график после первого щелчка на этой вкладке
- отобразить график в начале, но после каждого изменения размера клика и окна используйте
chart.setSize(w,h)
с новой шириной и высотой
- в начале диаграммы рендеринга, но после нажатия кнопки click
chart.reflow()
Ответ 2
Причина
Это не проблема Highcharts, по крайней мере сама по себе проблема связана с тем, что Bootstrap использует display: none
для скрытия неактивных вкладок:
.tab-content > .tab-pane, .pill-content > .pill-pane {
display: none; /* this is the problem */
}
Это приводит к тому, что Highcharts не может получить ожидаемую ширину для инициализации диаграммы, поэтому по умолчанию используется 600px
. Это произойдет с другими инструментами, используя тот же подход, чтобы скрыть контент.
Чистое решение для CSS
Вместо того, чтобы обойти проблему с дополнительной перерисованием или задержкой инициализации, мы можем добиться скрытого эффекта с помощью height: 0; overflow-y: hidden
, таким образом, скрытые панели вкладок все еще на месте и имеют действительный 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 */
Обновление. Предыдущее двухэтапное решение сначала скрывает все вкладки, а затем снова активирует активную вкладку. Для сравнения, теперь у нас есть одношаговое решение, которое напрямую нацелено на неактивные вкладки.
Это решение является бесшовным, поэтому вам больше не нужно беспокоиться о том, находится ли диаграмма внутри области вкладок или нет. И это эффективно, поскольку оно устраняет проблему ширины в первую очередь, поэтому нет необходимости обходить проблему ширины после этого путем изменения размера/перерисовки/перемотки с помощью javascript.
Примечание о каскадном порядке
Этот патч должен быть загружен после загрузки css из-за CSS каскадных правил порядка, короче говоря, последнее правило выигрывает.
Demo
До vs После
Совет. Перейдите на вкладку "Профиль", чтобы увидеть разницу.
Ответ 3
На основе ответа на Pawel я рисую диаграмму в начале и затем изменяю размер диаграммы.
Используемый код (с бутстрапом 3.0.3 и HighCharts 3.0.7)
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$('#container').highcharts().setSize($('#container').width(),$('#container').height());
})
Источник: http://getbootstrap.com/javascript/#tabs-usage
Ответ 4
Основываясь на ответе Paweł, я сделал рабочий пример:
http://codepen.io/colinsteinmann/pen/BlGfE
В основном функция .reflow() вызывается на каждой диаграмме при нажатии на вкладку. Таким образом, диаграмма перерисовывается на основе новых измерений, которые применяются к контейнеру, когда он становится видимым.
Это самый важный фрагмент кода:
// fix dimensions of chart that was in a hidden element
jQuery(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function (e) { // on tab selection event
jQuery( ".contains-chart" ).each(function() { // target each element with the .contains-chart class
var chart = jQuery(this).highcharts(); // target the chart itself
chart.reflow() // reflow that chart
});
})
Ответ 5
Я нашел более легкое решение в другом посте. В основном проблема возникает из-за того, что Highcharts не может отображать на div с настройкой "display: none". Решение просто напишет исправление в вашей таблице стилей CSS.
.tab-content > .tab-pane,
.pill-content > .pill-pane {
display: inline;
visibility: hidden;
position: absolute;
width: 930px;
}
.tab-content > .active,
.pill-content > .active {
display: inline;
visibility: visible;
position: absolute;
width: 930px;
}
Это приведет к тому, что вкладки будут работать с атрибутом visibility
вместо display
. Графики будут хорошо отображаться.
Ответ 6
Встрочный стиль "ширина" отличается для диаграмм. Я не уверен, когда и как они вычисляются, но вы можете переопределить их в css, например.