So I have multiple elements with class name ml, all different widths because of different text contents (not set in CSS).
for example:
<li><a class="depth ml" title="">Login</a></li>
I would like to append a new width to all of them, +=5px of the element's inner width
I've tried doing this, using jQuery:
var elems = document.getElementsByClassName('ml');
for ( var i = 0; i < elems.length; i++ ) {
var num = 5;
var curr_width = elems[i].width();
elems[i].style.width=(curr_width+num)+'px';
}
Nothing happened.
I tried using offsetWidth and clientWidth
var curr_width = parseInt(elems[i].offsetWidth);
but it added almost 40px, which I don't know where those came from. There isn't even padding or margins on those elements.
I just want the element's inner width appended.
Can anyone suggest a solution, or see why the jQuery isn't working?
EDIT:
Here is the markup:
<body>
<div id="master_container">
<div class="container">
<div id="body">
<header>
<div id="homelink"></div>
<div id="links" class="topmenulist">
<ul id="nav" class="title">
<li><a class="depth ml" title="home">Home</a></li>
<li><a class="depth ml" title="BBTV1">BBTV1</a></li>
<li><a class="depth ml" title="BBTV">BBTV</a></li>
<li><a class="depth ml" title="About us" style="">About us</a></li>
</ul>
</div>
</header>
and the relevant CSS:
.depth {
position: relative;
font-size:25px;
text-decoration:none;
letter-spacing:2px;
text-transform:uppercase;
color: rgba(42,41,36,1.00);
}
.depth:before, .depth:after {
content: attr(title);
color: rgba(255,255,255,.1);
font-size:25px;
text-decoration:none;
letter-spacing:2px;
position: absolute;
}
.depth:before { top: 1px; left: 1px }
.depth:after { top: 2px; left: 2px }
/*_______________ NAVIGATOR _________________*/
#links {
position:relative;
left:469px;
top:80px;
width: 489px;
height:53px;
padding:0px;
padding-left:0px;
z-index:9999;
}
.topmenulist #nav {
list-style:none;
padding:0;
padding-top:10px;
}
.topmenulist #nav li {
float:left;
display:block;
position:relative;
text-indent:0px;
margin-left:0px;
}
.topmenulist #nav li a {
margin:0px;
padding:0px;
display:block;
font-size:25px;
text-decoration:none;
letter-spacing:2px;
text-transform:uppercase;
color:rgba(41,17,3,0.60);
text-wrap:suppress;
}
note: .ml has no css
Just to point out, you're using pure JS -which is very brave of you ;) anyway, with jQuery, you could try something like below:
$(window).load(function() {
$(".ml").each(function() { // this is kindof sugary way of doing for loop over array of elements - which is $(".ml")
var $this = $(this); // the current jQueried .ml element
var currentWidth = $this.width(); // get width of current element, width is a jQuery method: https://api.jquery.com/width/
var newWidth = currentWidth + 5; // increment the width
$this.width(newWidth); // pass in the new width as the parameter.
});
});
In your code:
var curr_width = elems[i].width();
resolve to an undefined value, because DOM object doesn't have width property (only jQuery object have this one).
So the next statement (curr_width+num) is incorrect because you want to add an undefined value with a number.
Related
I have a horizontally scrolling element containing images that is situated out of view down the page.
To start with, I have the following markup and styles. I've used overflow:hidden because I don't want scrollbars. For the sake of simplicity, I have also removed some less-important styles:
<ul id="players-horizontal">
<li class="player-box"><img src="..."></li>
<li class="player-box"><img src="..."></li>
...
</ul>
#players-horizontal {
overflow: hidden;
height: 340px;
width: 100%;
}
#players-horizontal .player-box {
display: inline-block;
width: 300px;
height: 340px;
}
#players-horizontal .player-box:first-child {
margin-left: 90%;
}
Which gives me the following view:
When this element scrolls into view, I want to scroll its entire contents horizontally until it's about to go out of view, so the user gets to see its entire contents whilst scrolling down.
The desired look when the element is about to leave the viewport would be:
And vice-versa, the reverse action should happen when the user scroll upwards.
To know when the element has entered the viewport I have use the Waypoints plugin:
var waypoints = $('#players-horizontal').waypoint(
function(direction) {
if (direction === 'down') {
//console.log("Into view");
$window.scroll(function () {
var s = $(this).scrollTop();
});
} else {
//console.log("Out of view");
$window.scroll(function () {
var s = $(this).scrollTop();
});
}
}, { offset: '90%' }
);
But I'm stuck understanding what to do next, more specifically, how to work out how much to scroll (alter the margin of) the element in the short timeframe it has before leaves the viewport, ensuring all elements inside of it are shown before it does.
I would appreciate a help over the finishing line. I don't expect working code, although I'd be grateful, I really just need an easy to understand explanation of what is required.
UPDATE:
I have just tried using an alternative method which doesn't use the Waypoints plugin but instead uses ScrollMagic. This has definitely lifted a lot of the work required.
var scene = new ScrollMagic.Scene({triggerElement: "#players-horizontal", duration: 200})
.addTo(controller)
.on("progress", function (e) {
console.log((e.progress * 100));
});
The above snippet detects when the element #players-horizontal enters and leaves the viewport.
When the element enters the bottom of viewport when scrolling down, the value returned starts at 0 and stops at 100 just before leaving the top of the viewport. When I scroll back up, the value starts at 100 and stops at 0 when the element is about to leave the bottom of the viewport. So, I'm definitely a lot closer.
I would think about this differently. First I would consider using translation to make it easier to handle. You also need a little JS code to handle this
I will have the main container that I will translate by 90% to have your margin effect, then I will translate the content inside it from 0% to 100%. The translation will consider the scroll and screen height. Basically when the element enter the sreen I will start translating consider the difference between the offset top and the screen height.
Here is a first example.
var h =document.querySelector('#players-horizontal');
document.body.onscroll = function(e) {
var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight) {
h.style.setProperty('--x',(top - window.innerHeight)+'%');
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(var(--x,0%));
border:5px solid;
}
#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
}
#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:0;
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>
This above will create the scrolling effect but now we need to define the correct values.
It's clear that we need the scroll to start at top = window.innerHeight (translate(0%)) and when top = 0 we want our element to be fully shown and the last item at the right edge which means that we need to have translate(-100% + width of screen) but since the width of screen is also the same as the container width and we already translated the container by 90% then we can only reach translate(-100%) (we can add negative margin to last element to rectify the position).
We simply need to convert the difference (top - window.innerHeight) to a percentage value considering window.innerHeight as 100% (when top=0).
var h =document.querySelector('#players-horizontal');
document.body.onscroll = function(e) {
var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight && top >=0) {
h.style.setProperty('--x',(top - window.innerHeight)*(100/window.innerHeight)+'%');
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(var(--x,0%));
border:5px solid;
}
#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
vertical-align:top;
}
#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:-10vw; /*the missing 10%*/
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>
I have used CSS variable (a personnal preference) but it's not really mandatory and you can simply set transform with the JS code:
var h =document.querySelector('#players-horizontal');
document.body.onscroll = function(e) {
var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight && top >=0) {
h.style.transform="translateX("+(top - window.innerHeight)*(100/window.innerHeight)+'%)';
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(0%);
border:5px solid;
}
#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
vertical-align:top;
}
#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:-10vw;
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>
I'm trying to check to see if an overflow exists in a div element, but I cannot get it to work. Below is my JavaScript and a link to a jsfiddle with the whole thing. Any help would be appreciated!
var el = $('.container_element');
if(el.scrollWidth < el.offsetWidth){
// your element have overflow
$("nav#sub").css("background-color","red")
}
else if (el.scrollWidth > el.offsetWidth)
{ $("nav#sub").css("background-color","grey")
//your element don't have overflow
}
.box
{
height:55px;
width:280px;
padding:13px;
line-height: 57px;
color:#fff;
display:inline;
text-decoration:none;
text-align:center;
white-space:no-wrap;
border-right:1px solid white
}
.box:hover {
background:#007FEB;
}
.container_element
{
white-space:nowrap;
margin-left: 10px;
overflow:hidden;
display:block;
}
.inner_container
{
width:100%;
}
#lefty,#righty {
width: 35px;
display: none;
height: 57px;
text-align: center;
color: #fff;
line-height: 57px;
cursor: pointer;
font-size: 24px;
}
#lefty {
float:left;
}
#righty {
float:right;
}
nav#sub {
background:#4C75C6
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="sub" class="clearfix">
<div id="lefty"><</div>
<div class="container_element">
<div class="inner_container">
<div class="box">One</div>
<div class="box">Two</div>
<div class="box">Three</div>
<div class="box">Four</div>
<div class="box">Fiveddddddfivefive</div>
<div class="box">Six really lreerere</div>
<div class="box">Seven really really long</div>
</div>
</div>
<div id="righty">></div>
</nav>
jfiddle example
First, You declare a JQuery object and you are using it like a regular javascript object.
If you want to use regular javascript in your IF statements you need to declare your el object like this :
var el = document.getElementsByClassName("container_element")[0];
and your IF statements like this :
if(el.offsetWidth < el.scrollWidth){
// your element have overflow
$("nav#sub").css("background-color","red");
}
else {
//your element don't have overflow
$("nav#sub").css("background-color","grey");
}
But if you want to use a JQuery object, you need to declare your el object like this :
var el = $('.container_element');
and your IF statements like this :
if($(el).prop("offsetWidth") < $(el).prop("scrollWidth")){
// your element have overflow
$("nav#sub").css("background-color","red");
}
else {
//your element don't have overflow
$("nav#sub").css("background-color","grey");
}
Also in your IF statements, you have to test if offsetWidth < scrollWidth not scrollWidth < offsetWidth to know if your element have overflow.
You're trying to access native DOM API methods through the jQuery API.
The jQuery API is an unnecessary abstraction of the DOM API, if you can use the DOM API then there's no need for jQuery. See: http://youmightnotneedjquery.com
Element.clientHeight and Element.clientWidth are much more reliable than Element.offsetHeight and Element.offsetWidth.
Here's a simple example using just the DOM API, no sugar necessary.
var wrps = document.querySelectorAll('.wrp');
for(var i in Object.keys(wrps)) (function(wrp, inr, ovr){
if(wrp.scrollWidth > wrp.clientWidth) ovr.push('x');
if(wrp.scrollHeight > wrp.clientHeight) ovr.push('y');
inr.textContent = ovr.join(' and ') +
['no overflow',' overflows',' overflow'][ovr.length];
})(wrps[i], wrps[i].firstElementChild, []);
body { font-size:0; margin:0 }
.wrp { width:25%; height:38px; overflow:auto; display:inline-block; font-size:16px; text-indent:5px }
#inr1 { width:100%; height:100% } #inr2 { width:200%; height:100% }
#inr3 { width:100%; height:200% } #inr4 { width:200%; height:200% }
<div class="wrp"><div id="inr1"></div></div>
<div class="wrp"><div id="inr2"></div></div>
<div class="wrp"><div id="inr3"></div></div>
<div class="wrp"><div id="inr4"></div></div>
I would like to have some help about the transition of a div in CSS or JavaScript.
I have a <div> with dispay:none;.
With some JS, i change the display option on display:block.
All is working correctly.
But i would like to know how to make a transition when the <div> appear on the screen.
Like the player Spotify when you want to search something.
Thanks for you help.
And really sorry for my BAD english !
You can do it with a JQuery like this:
$(function() {
var open=false;
$('.menubar span').click(function(){
if(open==false){
$('.search').css('left','50px');
open=true;
}
else{
$('.search').css('left','-100px');
open=false;
}
});
});
.menu{
position:fixed;
left:0;
top:0;
width:50px;
height:100%;
background:#222021;
z-index:4;
}
.menubar{
width:50px;
height:100%;
color:white;
font-family:arial;
}
.search{
position:absolute;
left:-100px;
top:0;
width:100px;
background:lightgrey;
height:100%;
-o-transition:.3s;
-ms-transition:.3s;
-moz-transition:.3s ;
-webkit-transition:.3s;
transition:.3s ;
}
.search input{
margin:0;
width:75px;
border:1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="menu">
<div class="menubar">
<span>Home</span>
</div>
</div> <div class="search"><input type="search"></div>
Click "Menu" in the menu bar, and the search bar slides out, click again to hide it.
To use JQuery, you have to include the jquery library:
include this in <head>:
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
Or download it from:http://jquery.com/download/
Then, just use the script like normal JS, in a <script> tag.
EDIT:
With your problem in the comments below, #navbar had a static position, which means z-index will not work for it:
#nav-bar {
background-color: #23232C;
bottom: 0px;
left: 0px;
top: 0px;
width: 220px;
height: 100%;
margin-top: -17px;
z-index: 99;
position: absolute;
}
The following answers uses CSS Style Declarations to accomplish the transition effect.
if you declare the transition: all 1s style on an element. If the style property changes on that element your browser's (user-agent's) graphic device will calculate and update the frames (or visual changes) that occur between the two states (initial state, and end state). However, the property that is being changed must be scalar; that is, both the initial value and new value are scalar (like 0% being set to 100%). Additionally, if you're changing a property that is not scalar, but affects the rendering of other properties.. they will skip the transition effect (aka display:none being set to display:block).
Note: Instead of changing the inline style on the elements using Javascript, we're going to instead change the class of those elements; meaning, the following styles represent visual states, which we'll toggle between..
Again, the transition style declaration (or rather, the graphic device) will handle the incremental rendering of the frames between these two states.
Code Sample of changing 4 style properties (explicitly)
var str = 'hide';
var btn = document.querySelector("button#toggler").addEventListener('click', function(ev)
{
var elms = document.querySelectorAll('div.block');
for (var i = 0, lng = elms.length; i < lng; i++)
{
elms[i].className = elms[i].className.replace("hide", "").replace("show", "").replace(" ", "");
elms[i].className = elms[i].className + ' ' + str;
}
str = (str === 'show') ? str = 'hide' : 'show';
});
.block {
display:block; position:absolute;
top:0;
left:0;right:80%;
bottom:0;
background-color: rgba(0,0,0);
border:0.1em solid black;
min-width:5em;
transition: left 2s, opacity 2s, right 2s, background-color 1s;
}
.wrapper
{
display:block;position:relative;background-color:whitesmoke;
min-height:10em;
width:auto;
}
.show {opacity:1;left:0%;right:80%;background-color:rgb(255,0,0);}
.hide {opacity:0;left:80%;right:0%;background-color:rgb(0,0,255);}
<button id="toggler">Toggle Block</button>
<div class="wrapper">
<div class="block"></div>
</div>
The following is a fairly more complex slider, which ulitmately uses the same principal for rendering the transitions.
$("div.slide > button.show" ).on('click', function (ev)
{
var slide = $(ev.target).closest(".slide");
slide.toggleClass("hide").toggleClass("show");
var slidePrev = slide.prev();
slidePrev.toggleClass("hide").toggleClass("show");
slidePrev = slidePrev.prev();
slidePrev.toggleClass("hide").toggleClass("show");
slidePrev = slidePrev.prev();
slidePrev.toggleClass("hide").toggleClass("show");
slidePrev = slidePrev.prev();
slidePrev.toggleClass("hide").toggleClass("show");
})
$("div.slide > button.hide" ).on('click', function (ev)
{
var slide = $(ev.target).closest(".slide");
slide.toggleClass("hide").toggleClass("show");
var slideNext = slide.next();
slideNext.toggleClass("hide").toggleClass("show");
slideNext = slideNext.next();
slideNext.toggleClass("hide").toggleClass("show");
slideNext = slideNext.next();
slideNext.toggleClass("hide").toggleClass("show");
slideNext = slideNext.next();
slidePrev.toggleClass("hide").toggleClass("show");
})
html, body {display:block;position:relative;margin:0 auto;padding:0;height:100%}
div.wrapper {position:relative;
left:0;right:0;top:0;bottom:0;
width:auto;
background-color:whitesmoke;
display:block;
overflow:hidden; height:100%;
}
button {line-height:2em;padding:0.2em;display:block;}
div.slide {
display:block;
position:absolute;
border:0.2em solid black;
background-color:white;
top:0;
bottom:0;
right:0;
left:0;
opacity:1;
transition: left 1s, opacity 0.5s;
}
div.slide:nth-child(1) {
left: 1em;
z-index: 1;
}
div.slide:nth-child(2) {
left: 3.5em;
z-index: 2;
}
div.slide:nth-child(3) {
left: 6em;
z-index: 3;
}
div.slide:nth-child(4){
left: 8.5em;
z-index: 4;
}
div.slide.hide {
opacity:0.3;
left: 59%;
}
div.slide.show {
opacity:1;
}
div.show > button.show {display:none;}
div.hide > button.hide {display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="slide show">
<button class="show">show</button>
<button class="hide">hide</button>
</div>
<div class="slide show">
<button class="show">show</button>
<button class="hide">hide</button>
</div>
<div class="slide show">
<button class="show">show</button>
<button class="hide">hide</button>
</div>
<div class="slide show">
<button class="show">show</button>
<button class="hide">hide</button>
</div>
</div>
I'm trying out a vertical ticker that displays a few text list items one after the other, but I need some help in positioning them.
You'll see a web ticker with two items. To display only one item at a time, I have to set 'overflow:hidden' in #tickerContainer.
However, the text in the ticker is not being positioned at the center of the ticker(As you see it is sitting at the bottom).
Also, when I remove 'overflow:hidden' from #tickerContainer, which is the whole ticker moving away from the top of the page?
Please help me fix this.
http://jsfiddle.net/nodovitt/NYhY4/2/
<div id="tickerContainer">
<ul id="ticker" class="js-hidden">
<li class="news-item">Item Number 1</li>
<li class="news-item">Item Number 2</li>
</ul>
</div>
The jQuery function:
<script>
function tick() {
$('#ticker li:first').slideUp(1000, function () {
$(this).appendTo($('#ticker')).slideDown(1000);
});
}
setInterval(function () {
tick()
}, 2000);
</script>
The CSS:
#tickerContainer {
background-color:white;
border-radius:15px;
text-align:center;
margin:10px;
box-shadow:0 0 8px black;
color:#2B7CD8;
font-size:50px;
width:500px;
height:100px;
overflow:hidden;
}
.news-item {
font-family:Times New Roman;
font-style:oblique;
}
#ticker li {
list-style-type:none;
}
You haven't put any specifications on your ticker id. So something like this http://jsfiddle.net/NYhY4/10/
#ticker {
padding:0px;
margin:0px;
padding-top:20px;
height:55px;
overflow:hidden;
}
Here is my answer as requested by OP
Add this css to your #ticker
#ticker {
margin: 0;
padding: 0;
line-height: 100px;
}
NOTE The line-height will always have to be the height of the #tickerContainer
You can see it here http://jsfiddle.net/NYhY4/3/
#ticker li {
list-style-type:none;
position: relative;
bottom:20px;
}
I didn't like the current item being hidden by seemingly "nothing" (the blank part of li box above the text) so I used this approach:
Remove the margins from the '#ticker'
set '#ticker' padding-top (.5em worked best for me)
set '#ticker li' padding-bottom to push the next item out of view (I used '1em' to be safe but '.5em' worked too)
The words didn't look perfectly centered so
set '#ticker li' line-height to '1em'
#ticker {
margin: 0;
padding-top: .5em;
}
#ticker li{
line-height: 1em;
padding-bottom: 1em;
list-style-type: none;
}
http://jsfiddle.net/JvuKU/2/
Note This depends on the font-size of the '#tickerContainer'. If you change the height or font-size of the '#tickerContainer', just adjust the values of '#ticker' padding-top and '#ticker li' padding-bottom.
Here's my situation. I have a sliding jquery menu like this: http://tympanus.net/codrops/2011/07/03/sliding-background-image-menu.
The code of menu is:
<div id="sbi_container" class="sbi_container">
<div class="sbi_panel" data-bg="images/1.jpg">
About
<div class="sbi_content">
<ul>
<li>Subitem</li>
<li>Subitem</li>
<li>Subitem</li>
</ul>
</div>
</div>
<div class="sbi_panel" data-bg="images/2.jpg">
...
</div>
CSS:
.sbi_content{
position:absolute;
border-top:2px solid #000;
bottom:90px;
left:0px;
width:100%;
background:transparent url(../images/pattern.png) repeat top left;
display:none;
overflow:hidden;
}
.sbi_content ul{
padding:10px;
}
.sbi_content ul a{
display:block;
color:#f0f0f0;
font-size:16px;
padding:4px 6px 4px 14px;
background:transparent url(../images/triangle.png) no-repeat 3px 50%;
opacity:0.9;
}
.sbi_content ul a:hover{
background-color:#000;
color:#fff;
-moz-box-shadow:1px 1px 5px #000;
-webkit-box-shadow:1px 1px 5px #000;
box-shadow:1px 1px 5px #000;
}
And here's a JavaScript piece I have a problem with:
$content.each(function(i) {
var $el = $(this);
// save each content's height (where the menu items are)
// and hide them by setting the height to 0px
var num = $el.find('ul li').size();
$el.data( 'height', num * 35 + 10 ).css( 'height', '0px' ).show();
});
I need to count a height of these <ul>.
That I'm doing now is counting how many there are <li> items, then multiply it by number of one's height (35) and adding a 10px for margin..
Everything would be ok, but when there is a realy long <li> item, it jumps to second row and problem is that this code doesn't count that second row height.
Any ideas how can I solve this problem?
Thank you.
You can use the scrollHeight property:
$("ul")[0].scrollHeight
For your specific case -
$content.find('ul')[0].scrollHeight
You can count the height of all the lis in the content using this:
var totalLiHeight = 0;
$el.find('ul li').each(function() {
var currentLiHeight = $(this).height();
totalLiHeight += currentLiHeight;
});
Then you can add the margin to that.