Div hidden behind another div, how to get same height

I have an outer div with 2 divs inside.
The first inner div contains an image. The second contains some text but has opacity 0.
What I want to happen is when someone hovers over the image it fades, and the text is displayed within the same space.

I am giving the text div a negative margin-top so it ‘moves up’ to the same place as the image and I’ve got the opacities changing on the outer div hover.

Problem I am having is if the text block is shorter than the size of the image, the image is being chopped off at the point the text finishes.
First question is why would it do that? I don’t understand how one div can determine the height of a completely separate one…
Second question is how to fix it? I could probably work it out with js, but would prefer css only.

Demo is at http://www.sandwoodmountaineering.co.uk/demo/sw.htm#Portfolio. The first three have longish text so are ok, but the fourth one is the problem.

Any advice appreciated.
Thanks

Can’t open your demo as it gives timeout error, but maybe this example will help:

That’s just what I want it to look like
But I want it to be responsive, not set width and height.
I have a full-width row, divided into 4 columns, each one 25% width, floated left and containing a .block. I want the image to resize accordingly.

something like http://codepen.io/treacle0996/pen/wKYzoo

HI,

You can’t stretch your images to height:100% as that makes them lose their aspect ratio and they all look squished and ugly. To maintain the aspect ratio of the image you need to set width:100% but height:auto.

Of course that means that for image that have different intrinsic aspect ratios then they will not all be the same height.

Assuming the images you are using are the same aspect ratio then you could do it like this.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.row {
	margin:auto;
	max-width:1000px;
}
.row:after {
	content:"";
	display:table;
	clear:both;
}
.col4 {
	float:left;
	width:25%;
}
.block {
	position:relative;
	margin:0 10px 10px 0;
}
.image {
	width:100%;
	height:auto;
	display:block;
}
.text {
	position:absolute;
	width:100%;
	height:100%;
	left:0;
	top: 0;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
	overflow:auto;
	padding:10px;
	background:rgba(0,0,0,0.85);
	color:#FFF;
	opacity:0;
	transition: opacity 0.5s;
}
.block:hover .text {
	opacity:1;
}
</style>
</head>

<body>
<div class="row">
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
</div>
<div class="row">
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
</div>
</body>
</html>

If the images are not the same height then your options are limited if you want to maintain aspect ratio (and get images all to the same height). You can use object fit but it is only supported in these browsers. Alternatively you would have to use background images and background-size:cover instead.

I updated the pen in post #2 to make it responsive
Try to change .wrap width to see it in action

Perfect! Thank you
I was so tied up with floating everything, and then using a -ve margin I’d not considered absolute positioning.

Just one question, why use

.row:after {
content:"";
display:table;
clear:both;

}
rather than

.row {
    clear: both;
}

?

If you just use clear:both then that leaves .row without any height at all because it contains only floats and floats are removed from the flow.

If you apply a background color to .row then nothing will show because it has no height. The :after rule ensures that the floats are contained within .row and any backgrounds or margins on. row will work as expected. Without it a margin-bottom on .row would have no effect unless the margin was greater than the height of its floated content.

I tried it on ipad and windows phone, both failed to apply the hover effect (on touch).
I tried applying it also on :active and :focus but neither helped. A bit of googling led me to

onclick=""

to make it work on ipad and

aria-haspopup="true"

to work on windows phone.
Looks like it works fine now (but I have run out of devices to test) Just wondered if there was any problem with this approach, or any more accepted way of doing it?

You answered your own question :). Touch devices don’t really have hover and you shouldn’t add hover effects for critical information but more for decoration so that if devices don’t display the effect then nothing is lost.

As you found some devices will treat a ‘first touch’ as a kind of hover assuming the element concerned is a clickable element like an anchor (or has an anchor close by). You can make the element clickable by adding an empty onclick attribute which messes up the html a bit so you would be better off doing it from an external js file.

There are some other methods using tabindex and focus that also have partial success.

Note that some devices won’t even show anything even when an anchor is used unless cursor:pointer is added on hover as well.

In most of the above cases you end up with an effect that won’t disappear unlike hover and the item stays in its hover state until somewhere else is clicked.

If the hover information is critical then it may be better to detect touch and apply a class to the element on touch and remove it on touchend. This also means that the hover rule needs to be sent only non touch devices otherwise you get a mixture of both.

I have used the following to create a better hover effect for mobiles.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.row {
	margin:auto;
	max-width:1000px;
}
.row:after {
	content:"";
	display:table;
	clear:both;
}
.col4 {
	float:left;
	width:25%;
}
.block {
	position:relative;
	margin:0 10px 10px 0;
}
.image {
	width:100%;
	height:auto;
	display:block;
}
.text {
	position:absolute;
	width:100%;
	height:100%;
	left:0;
	top: 0;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
	overflow:auto;
	padding:10px;
	background:rgba(0,0,0,0.85);
	color:#FFF;
	opacity:0;
	transition: opacity 0.5s;
}
.no-touch .block:hover .text,
.block.over .text {
	opacity:1;
	cursor:pointer;
}

</style>
</head>

<body>
<div class="row">
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image</div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
</div>
<div class="row">
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
		<div class="col4">
				<div class="block"> <img  class="image" src="http://windows10wallpaper.net/wp-content/uploads/2015/07/free-nature-wallpaper-150x150.jpg">
						<div class="text"> This is some text to show over the image </div>
				</div>
		</div>
</div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
// detect touch 
	if (!("ontouchstart" in document.documentElement)) {
  	document.documentElement.className += " no-touch";
	}
$('.block').on('touchstart touchend', function(e) {
    $(this).toggleClass('over');         
});
</script>

</body>
</html>

The above will allow mobiles to show the message only while the touch is held down and then disappear when the touch has ended much the same as hover.

Of course this leads to the question of what happens on devices that support touch and hover? Hopefully the above routine would still work which brings me around to my first point of not ever showing critical information on hover only.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.