Items floating above another

A really simple problem, a really hard problem. I have these images that, on click, disappear into a div on top of them. On the desktop, they appear independently, but on mobile tablets, they stack on top of each other.

My issue

Things I've tried:

  • Clearfix
  • Table display
  • Network system

Link to script

JS / CSS / HTML / DEMO

(function() {
    
    /* == GLOBAL DECLERATIONS == */
    TouchMouseEvent = {
        DOWN: "touchmousedown",
        UP: "touchmouseup",
        MOVE: "touchmousemove"
    }
   
    /* == EVENT LISTENERS == */
    var onMouseEvent = function(event) {
        var type;
        
        switch (event.type) {
            case "mousedown": type = TouchMouseEvent.DOWN; break;
            case "mouseup":   type = TouchMouseEvent.UP;   break;
            case "mousemove": type = TouchMouseEvent.MOVE; break;
            default: 
                return;
        }
        
        var touchMouseEvent = normalizeEvent(type, event, event.pageX, event.pageY);      
        $(event.target).trigger(touchMouseEvent); 
    }
    
    var onTouchEvent = function(event) {
        var type;
        
        switch (event.type) {
            case "touchstart": type = TouchMouseEvent.DOWN; break;
            case "touchend":   type = TouchMouseEvent.UP;   break;
            case "touchmove":  type = TouchMouseEvent.MOVE; break;
            default: 
                return;
        }
        
        var touch = event.originalEvent.touches[0];
        var touchMouseEvent;
        
        if (type == TouchMouseEvent.UP) 
            touchMouseEvent = normalizeEvent(type, event, null, null);
        else 
            touchMouseEvent = normalizeEvent(type, event, touch.pageX, touch.pageY);
        
        $(event.target).trigger(touchMouseEvent); 
    }
    
    /* == NORMALIZE == */
    var normalizeEvent = function(type, original, x, y) {
        return $.Event(type, {
            pageX: x,
            pageY: y,
            originalEvent: original
        });
    }
    
    /* == LISTEN TO ORIGINAL EVENT == */
    var jQueryDocument = $(document);
   
    if ("ontouchstart" in window) {
        jQueryDocument.on("touchstart", onTouchEvent);
        jQueryDocument.on("touchmove", onTouchEvent);
        jQueryDocument.on("touchend", onTouchEvent); 
    } else {
        jQueryDocument.on("mousedown", onMouseEvent);
        jQueryDocument.on("mouseup", onMouseEvent);
        jQueryDocument.on("mousemove", onMouseEvent);
    }
    
})();


$(document).ready(function () {
	$("#P1").on(TouchMouseEvent.DOWN, function () {
		$("#P1A").fadeToggle();
		$("#P1").fadeToggle();
	});

	$("#P1A").on(TouchMouseEvent.DOWN, function () {
		$("#P1").fadeToggle();
		$("#P1A").fadeToggle();
	});
	
	$("#P2").on(TouchMouseEvent.DOWN, function () {
		$("#P2A").fadeToggle();
		$("#P2").fadeToggle();
	});

	$("#P2A").on(TouchMouseEvent.DOWN, function () {
		$("#P2").fadeToggle();
		$("#P2A").fadeToggle();
	});
	
	$("#P3").on(TouchMouseEvent.DOWN, function () {
		$("#P3A").fadeToggle();
		$("#P3").fadeToggle();
	});

	$("#P3A").on(TouchMouseEvent.DOWN, function () {
		$("#P3").fadeToggle();
		$("#P3A").fadeToggle();
	});

	$("#P4").on(TouchMouseEvent.DOWN, function () {
		$("#P4A").fadeToggle();
		$("#P4").fadeToggle();
	});

	$("#P4A").on(TouchMouseEvent.DOWN, function () {
		$("#P4").fadeToggle();
		$("#P4A").fadeToggle();
	});
	
});
      

/* line 7, style.scss */
.work {
  padding: 275px 0 550px 0;
}
/* line 11, style.scss */
.work .ic {
  width: 87.5%;
  margin: 0 auto;
}
/* line 15, style.scss */
.work .ic .I1 {
  background: url(../img/hi.png) no-repeat center;
  background-position: 0% 100%;
  content: '';
  display: block;
  float: left;
  height: 35px;
  width: 35px;
  margin-left: 25px;
  margin-right: 5px;
}
@media (min-width: 320px) {
  /* line 15, style.scss */
  .work .ic .I1 {
    margin-left: 0;
  }
}
@media (min-width: 1240px) {
  /* line 15, style.scss */
  .work .ic .I1 {
    margin-left: 25px;
  }
}
/* line 41, style.scss */
.work .ic h1 {
  padding: 25px 0;
}
/* line 45, style.scss */
.work .ic .ih {
  float: left;
  position: relative;
}
@media (min-width: 320px) {
  /* line 45, style.scss */
  .work .ic .ih {
    width: 100%;
    padding: 0 0 10px 0;
  }
}
@media (min-width: 768px) {
  /* line 45, style.scss */
  .work .ic .ih {
    width: 46%;
    padding: 0 25px 10px 0;
  }
}
@media (min-width: 1240px) {
  /* line 45, style.scss */
  .work .ic .ih {
    width: 21.875%;
    padding: 0 0 10px 30px;
  }
}
/* line 69, style.scss */
.work .ic .ih .h1 {
  font-size: 1.15em;
  font-weight: bold;
}
/* line 71, style.scss */
.work .ic .ih .works {
  position: relative;
}
/* line 73, style.scss */
.work .ic .ih img {
  display: block;
  width: 100%;
}
/* line 75, style.scss */
.work .ic .ih div {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  padding: 25px;
  width: 85%;
}
@media (min-width: 320px) {
  /* line 75, style.scss */
  .work .ic .ih div {
    padding: 5px 5px 0 5px;
  }
}
@media (min-width: 768px) {
  /* line 75, style.scss */
  .work .ic .ih div {
    padding: 10px 10px 0 10px;
  }
}
@media (min-width: 1240px) {
  /* line 75, style.scss */
  .work .ic .ih div {
    padding: 10px 0 10px 40px;
  }
}
/* line 100, style.scss */
.work .ic .ih .b1 {
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  background: #2980b9;
  position: absolute;
  padding: 15px 13px;
  -webkit-border-radius: 35px;
  -moz-border-radius: 35px;
  border-radius: 35px;
}

/* line 111, style.scss */
.cf:before,
.cf:after {
  content: " ";
  /* 1 */
  display: table;
  /* 2 */
}

/* line 116, style.scss */
.cf:after {
  clear: both;
}

/* line 120, style.scss */
.cf {
  *zoom: 1;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="work cf" id="W">
    <div class="ic cf">
        	<h1><span class="I1"></span><span>Work</span></h1>

        <div class="works">
            <div class="ih">
                <img src="img/p1.png" id="P1" style="display: block;">
                <div id="P1A" style="display: none;">	<span class="h1"> 3-2-1 Bread </span>

                    <p>3-2-1 Bread is a national relief program which fights hunger and poverty through generosity and love.</p>	<a href="piece1/index.html" target="_blank" class="b1"> Go </a>

                </div>
            </div>
            <div class="ih">
                <img src="img/h.png" id="P2" style="display: block;">
                <div id="P2A" style="display: none;">	<span class="h1"> Radarda </span>

                    <p>Such a beautiful title.</p>	<a href="piece2/index.html" target="_blank" class="b1"> Go </a>

                </div>
            </div>
            <div class="ih">
                <img src="img/h.png" id="P3">
                <div id="P3A">	<span class="h1"> Radarda </span>

                    <p>Such a beautiful title.</p>	<a href="piece3/index.html" target="_blank" class="b1"> Go </a>

                </div>
            </div>
            <div class="ih">
                <img src="img/h.png" id="P4">
                <div id="P4A">	<span class="h1"> Radarda </span>

                    <p>Such a beautiful title.</p>	<a href="piece4/index.html" target="_blank" class="b1"> Go </a>

                </div>
            </div>
        </div>
    </div>
</div>
      

Run codeHide result


Solution: 1: It seems that when the images are moved to fade away the height of the parent divs is removed, so when the div holding the text disappears, it is not even recognized as the height is not added until the effect, so other IH ( or columns) make the styling decision. Trying to set a constant height of the parent div.

Fixing solution 2: It seems like adding a fixed height to the parent div, and height: 100% to those children will remove the overlap, however now the image will not stay proportional.

+3


source to share


1 answer


So the main problem is that the way your elements are set up containing a div with class ih is reset when the image it contains is set to: none. This is what you expect. A block level element has 0 height when it contains no elements unless you explicitly give it height. The result is other ih elements that have float: left apply, do just that: they float to the left.

There are two ways to handle this without completely eviscerating your css. The first is to use opacity: 0 to shrink the image so that it is hidden but still in the document flow. The second is to give the .ih div some height.

DEMO 1

Use opacity and CSS transitions

The advantage here is that you use CSS to handle the transitions. This improves separation of concerns a little, but the downside is that IE8 and IE9 do not support transitions, so in older browsers, content will simply "jump" between opacity states rather than fade out.

The only changes to your markup are adding two classes to the div that contains your text (the ones with PxA IDs). I named them .works-text and .hide:

        <div class="ih">
            <img src="img/p1.png" id="P1" />
            <div id="P1A" class="works-text hide">  
                <span class="h1"> 3-2-1 Bread </span>
                <p>3-2-1 Bread is a national relief program which fights hunger and poverty through generosity and love.</p>    
                <a href="piece1/index.html" target="_blank" class="b1"> Go </a>
            </div>
        </div>

      

Then you need to add two helper classes, show and hide, to your CSS, and add transitions to the existing rules for your image and text div:

.work .ic .ih img {
    display:block;
    width:100%;
    -webkit-transition: opacity .5s ease; /*Add this*/
    transition: opacity .5s ease; /*Add this*/
}
.work .ic .ih div {
    position:absolute;
    top:0;
    left:0;
    margin:0;
    padding:25px;
    width:85%;
    -webkit-transition: opacity .5s ease; /*Add this*/
    transition: opacity .5s ease; /*Add this*/
}
/*Create these new classes*/
.show {
    opacity: 1;
}
.hide {
    opacity: 0;
}

      

Now for Javascript you don't need to customize elements through their IDs. You can replace ALL of these event handlers with one! By using $(this)

, you can only target the element that dispatched the event. Then you can use the method find()

to target only the children of that element. A method toggleClass()

can take a string with two values โ€‹โ€‹separated by commas that tell it to switch between classes with those names. CSS handles fading in / out.



$('.ih').on(TouchMouseEvent.DOWN, function () {
    $(this).find('img').toggleClass('show, hide');
    $(this).find('.works-text').toggleClass('show, hide');
});

      

DEMO 2

Use Min-Height

This approach may be easier to do given the current markup and styles, but it has a drawback that is not very sensitive. Of course, you can tweak the minimum height values โ€‹โ€‹in your media queries to get closer to responsiveness.

The markup here is identical to the first option, except that we no longer need the hide class. Just add the work-text class to the text divs.

<div id="P1A" class="works-text">

      

Then in css add your minimum height values โ€‹โ€‹and work-text class rule:

.work .ic .ih {
    float:left;
    position:relative;
    min-height: 350px; /*give your div some min-height that is going to be large enough so that the floats are maintained*/
}
.works-text {
    display: none; /*so we don't use inline styles*/
}

      

Finally, to simplify the javascript, follow the same pattern as in the first demo, creating a single handler for all elements.

$('.ih').on(TouchMouseEvent.DOWN, function () {
    $(this).find('img').fadeToggle();
    $(this).find('.works-text').fadeToggle();
});

      

+1


source







All Articles