У меня была такая же проблема, и я не мог найти решение своей проблемы. После многих часов попыток решить ее легко, я наконец создаю решение для себя. Это сделано в основном в JQuery, но я думаю, вы можете легко изменить его на другой JS Framework. Я не специалист по javascript, поэтому код, вероятно, не будет оптимизирован.
HTML (только для иллюстрации)
<ul id="nav">
<li class="level-top">
<a href="#"><span>Item 1</span></a>
<ul class="level0">
<li class="level1">
<a href="#"><span>Item 2</span></a>
</li>
<li class="level1">
<a href="#"><span>Item 3</span></a>
</li>
</ul>
</li>
</ul>
CSS (только для иллюстрации)
ul#nav { display:block; }
li.level-top { position:relative; float:left; width:120px; height:50px; }
li.level-top a { display:block; height:50px; line-height:50px; }
ul.level0 {
position:absolute;
top:50px;
left:0;
padding:9px 0;
border:3px solid #CCC;
width:240px;
display:none;
}
li.level-top:hover ul.level0 { display:block; }
li.level1 { position:absolute; width:120px; }
li.level1.odd { left:0; }
li.level1.even { right:0; }
JS
Моя главная проблема решена здесь. Элемент UL с классом level0 обычно скрыт. Нам нужно вывести его за пределы экрана и установить верхнее позиционирование обоих столбцов, а затем вернуть его обратно.
(function($){ // start jquery
$(document).ready(function(){ // domready
$("#nav > li > ul > li:nth-child(odd)").addClass('odd'); // This add class="odd" to every odd li in ul.level0
$("#nav > li > ul > li:nth-child(even)").addClass('even'); // This add class="even" to every even li in ul.level0
$('ul.level0').each(function(index) { // get all ul elements with level0 class
$(this).css('top', '-5000px').css('display', 'block'); // hide out of screen before changes and make display:block to possiblity of get heights of elements
var topPadding = parseInt($(this).css('padding-top')); // get padding-top (only numeric value) of ul element
var leftHeight = 0; // start left column from 0 (top position)
$(this).children('li.level1.odd').each(function(index) { // get odd elements
var $liOuterHeight = $(this).outerHeight(true); // get height of li element (height with padding, border and margin)
$(this).css('top', (leftHeight+topPadding)+'px'); // set top position of li element
leftHeight += $liOuterHeight; // modify height of left column
});
var rightHeight = 0; // start right column from 0 (top position)
$(this).children('li.level1.even').each(function(index) { // get even elements
var $liOuterHeight = $(this).outerHeight(true); // get height of li element (height with padding, border and margin)
$(this).css('top', (rightHeight+topPadding)+'px'); // set top position of li element
rightHeight += $liOuterHeight; // modify height of right column
});
$(this).height(rightHeight > leftHeight ? rightHeight : leftHeight).css('top', '').css('display', ''); // set height to ul element and change back all css changes (positioning + display)
});
}); // end of domready
})(jQuery); // end of jquery
Надеюсь, это кому-нибудь поможет. Это было сделано для меню, которое обычно было скрыто. Я думаю, вы можете изменить это для чего-то еще. Это не так сложно.