0

I'm building a shopify theme. I have an instance where one div overlaps another. In the instance that the left div is shorter than the right div (positioned absolutely), the right div overlaps the div below it as expected.

To get round this issue I've tried writing some js which works in this jsFiddle but in my actual site the divs height is outputting as 0 so the function isn't working. For the life of me I can't figure out why the height for both left and right divs would be 0 and wondered if someone might be able to shed some light?

JS

var productImgHeight = $('.left').outerHeight(),
productInfoHeight = $('.right').outerHeight(),
gap = productInfoHeight - productImgHeight;

if (productImgHeight < productInfoHeight) {
    alert(productImgHeight);
    $('.left').css({"margin-bottom":gap+"px"});
} else {
    $('.left').css({"margin-bottom":"0"});
}

Thanks in advance!

user2498890
  • 1,528
  • 4
  • 25
  • 58
  • Have you wrapped this code in `ready()` – Tushar Sep 11 '15 at 09:49
  • Yeah I've tried both `$(document).ready` and `$(window).load` but not having any luck. – user2498890 Sep 11 '15 at 09:51
  • 1
    tried this http://stackoverflow.com/questions/4119078/jquery-outer-height-is-zero? – potatopeelings Sep 11 '15 at 09:52
  • Thanks for that I hadn't seen that, as I've said I tried window.load could it be that there is a div wrapping the entire site being told to fade in on page load thats conflicting? – user2498890 Sep 11 '15 at 09:55
  • I removed the fade in on page load and the heights seem to be outputting now. How would I get around that being able to have both fade in on load and still be able to calculate the heights of the divs? – user2498890 Sep 11 '15 at 09:57
  • You can avoid this by using a different approach. [**jsFiddle**](https://jsfiddle.net/ay28bgyu/). – DavidDomain Sep 11 '15 at 10:10
  • @DavidDomain your fiddle link just seems to have removed all the js. What is the approach (use no js! ;p) – Pete Sep 11 '15 at 10:31
  • @Pete - yup. No need to use js, i have just changed your css, which will avoid the divs from overlapping. Oh, and moved the footer outside of the container. This is just an option. – DavidDomain Sep 11 '15 at 10:36
  • @DavidDomain, Ah I see you're fixing the overlapping problem - I was looking at the height problem! – Pete Sep 11 '15 at 10:43
  • 1
    @Pete - Just thought that would be an option. Just saw that you are not the OP. So it's not your css, but the css. ;-) – DavidDomain Sep 11 '15 at 10:50

2 Answers2

1

If your content is in a hidden element (with display none or visibility hidden), then your height will always be 0, the only way I have found to get around it is:

  • hide element off the page with a class that has the styles - position:fixed; left:100%
  • get the height on load
  • hide element with js and remove the class
  • do your fade in

var productImgHeight = $('.left').outerHeight(),
  productInfoHeight = $('.right').outerHeight(),
  gap = productInfoHeight - productImgHeight;

if (productImgHeight < productInfoHeight) {
  console.log(productImgHeight);
  $('.left').css({
    "margin-bottom": gap + "px"
  });
} else {
  $('.left').css({
    "margin-bottom": "0"
  });
}


$('.container').hide().removeClass('fixed').fadeIn()
.fixed {
  position: fixed;
  left: 100%;
  top: 100%;
}
.container {
  position: relative;
}
.left {
  width: 400px;
  height: 400px;
  background-color: blue;
  opacity: 0.5;
}
.right {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 15;
  width: 300px;
  height: 500px;
  background-color: green;
  opacity: 0.5;
}
footer {
  width: 100%;
  height: 200px;
  background-color: pink;
  opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container fixed">
  <div class="left">Left
  </div>
  <div class="right">Right
  </div>
  <footer>Footer</footer>
</div>

Updated fiddle

Pete
  • 57,112
  • 28
  • 117
  • 166
  • Thanks for your suggestion, I'm going to have to play around with it to see what works best in my case but definitely understand where I'm going wrong now. – user2498890 Sep 11 '15 at 10:19
  • This seems to be working except for one thing. I have a fixed title that is positioned dead centre in the page with css transform: translate 50% 50%. Because of this the title is visible before the rest of the page fades in. Any ideas why this might be? – user2498890 Sep 11 '15 at 13:14
  • Ignore my last comment i fixed it! – user2498890 Sep 11 '15 at 13:20
0

Your DOM has to be fully loaded for these functions to work. Wrap it in the ready function also provided by jQuery:

$(document).ready(function () {
    var productImgHeight = $('.left').outerHeight(),
        productInfoHeight = $('.right').outerHeight(),
        gap = productInfoHeight - productImgHeight;

    if (productImgHeight < productInfoHeight) {
        alert(productImgHeight);
        $('.left').css({"margin-bottom":gap+"px"});
    } else {
        $('.left').css({"margin-bottom":"0"});
    }
});

Also: Make sure the element is not hidden with display: none; because then - it doesn't have height. You can work around this setting it to show (invisible), get the height, and then hide it again.

$('.left').css({
    display: "block",
    opacity: 0 //Invisible to user
});
var productImgHeight = $('.left').outerHeight();
$('.left').css({
    display: "none",
    opacity: 1
});
Roboroads
  • 1,602
  • 1
  • 13
  • 24
  • Thanks for your answer, I can't seem to get this to work. I think that my function for fading in on page load is conflicting as a div that wraps the entire site is being told to be display:none and then on page load display:block; Having trouble getting them both to work consecutively. – user2498890 Sep 11 '15 at 10:04