Vertical Centering some Text over an Image with Dynamic Height - html

For whatever reason I am really beating myself up with this... No doubt because of the lack of support for a real "proper" way of vertically centering anything.
The Goal:
Is to have a set of four images, each inside their own responsive columns. Each image has a white overlay, that when hovered reveals more of the image, as well as a title for each of the 4 images that is horizontally and vertically centered inside the image.
I could easily achieve this if I set specific width/heights and stuck the image inside CSS rather than the HTML. For SEO reasons I want the image to be present in the HTML.
Additionally because of the responsive nature, the images must scale to 100% of the width of the column they reside in. Consequently, because the width scales, the height scales as well.
So the first issue is getting the "caption" as I am calling it in my classes, to appear over the top of the image. Easily done with a simple position: absolute; as well as top: 0; and left: 0; on the caption and position: relative; on the container.
The big problem and second issue, is vertically centering the "Gallery 1" text over the top of the image. I have to use the position: absolute; bit as I mentioned above just to get the text over-top of the image. From there I can't manage to get a display: table; solution to work, nor a -50% margin solution to work.
Here is a JS Fiddle
My HTML:
<div class="container">
<img src="http://lorempixel.com/output/city-q-c-640-480-8.jpg" />
<div class="caption">
Gallery 1
</div>
</div>
Any ideas on how to achieve this? I would like to stay at least IE8 supported, and I am using selectivizr already, so pseudo-classes don't bother me.

First, I wasn't sure about what you mean exactly. But as you mentioned:
The issue is centering the text Gallery 1 vertically over the top of the image. Centering it horizontally is easy with a simple text-align but centering it vertically is what is eluding me.
Here is my attempt to align the text vertically over the image. Actually the concept comes from this approach of a similar topic on SO:
.container { position: relative; }
.container img {
vertical-align: bottom; /* Remove the gap at the bottom of inline image */
max-width: 100%;
}
.caption {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
font: 0/0 a; /* Remove the gap between inline(-block) elements */
}
.caption:before {
content: ' ';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.caption a {
font: 16px/1 Arial, sans-serif; /* Reset the font property */
display: inline-block;
vertical-align: middle;
text-align:center;
background: rgba(255, 255, 255, 0.75);
width: 100%;
padding: 1% 0; /* Added a relative padding for the demo */
}
WORKING DEMO.
This relies on CSS2.1 and it will definitely work on IE8+ (excluding rgba()).

If I understand your issue correctly, this may work for you:
Working Demo
If you need the image to scale when hovered over, then simply adding a :hover on the container and changing it's width should work.
CSS:
.container {
// existing styles
-webkit-transition: all .2s; // needs prefixes for other browsers.
}
.container:hover {
width: 500px;
}
The only issue is that transition has no support for IE9 or earlier. So you'd need to go a JS route if that is an issue.

Related

CSS: Text beneath image does not break to new line

I have an absolute positioned div. Inside this div there is an image and underneath it, a caption. Now I want the caption to break to new a line if it reaches 95% width of the image.
But I can't get it to work. The text (no matter what width I say), always moves the image to the left like it would have no breaks.
I made a fiddle for this:
http://jsfiddle.net/hw7t7xyn/1/
The image is set to
right: 0;
top: 10px;
But since the text is too long it moves to the left.
Also the div.caption does not seem to adopt the parents div width.
Can anybody help me out here? Maybe it's a problem of the HTML setup or the CSS, I have no idea anymore, but it's driving me crazy.
Update: Sorry, I did forget to mention that I don't know the dimensions of the image. Is there a possible way to do this without javascript?
I think you just need to add a width to the main div (the one that's absolute positioned).
I added a width of 260px (same as the image)
When I did this, it aligned the div to the far right as you have right:0px is this correct?
http://jsfiddle.net/hw7t7xyn/5/
div.photo-wrap {
overflow: hidden;
position: absolute;
text-align: left;
width:260px;
}
img.photo {
position: relative;
display: block;
}
div.caption {
margin-top: 7px;
width: 95%;
position: relative;
display: inline-bock;
}
give width to photo-wrap

Absolute position text over image using CSS3 not working on Safari

I am trying to center a element with text over an image and my code works fine everywhere, except on Safari (for windows, if that means anything), it even works on Internet Explorer 9!
Here is a fiddle: http://jsfiddle.net/keleturner/b7DeH/
The only way I have found is to give the .main a set height, but I can't do this for various reasons. Is there a way to get it the text to overlay in the middle of the image with a height: auto;?
I'm not sure if you have a specific reason for the heavy div nesting, but I've cleaned it up here: http://jsfiddle.net/b7DeH/3/
HTML:
<div class="main">
<span>Text</span>
<img src="http://placekitten.com/300/200?image=3" />
</div>
CSS:
span {
position: absolute;
width: 100%; top: 50%;
/* and other prefixes */
transform: translateY(-50%);
font-size: 20px; font-weight: 700;
color: red; text-align: center; }
The problem, as you noticed, seems to stem from a height issue. You have height: 100% for .in and .out but without any parent/ancestors to tell it what that height is 100% of, it'll just keep going, and I imagine it's basically taking the 100% height of the document, hence why it centers to the page and not the divs.
Try using absolute positioning for your span too.
span {
position: absolute;
}

Text vertically and horizontally centered over a responsive image

I'm looking to center text both vertically and horizontally over an image that grows when the page gets wider.
I originally had the image set as the background for a div of fixed height, in which case it was relatively easy to center it, but because background images aren't structural, I couldn't set the height to be an automatic function of the width, and I had to toss this option out when I went for a more responsive design.
So I've currently got a div with two elements in it, img and overlay text. The image width is set to 100% of the width of its container, and the height varies accordingly. As a consequence, though, I can't set the overlay text to be postion:absolute and top:80px or something, because the distance from the top will have to vary. And even doing top:25% or whatever doesn't work, because a) if that page width shrinks to squeeze the text, or if there's just more text, the vertical centering is thrown off when there are more/less lines, and b) the percentage is arbitrary -- it's not 50 or something, because that would put the top of the text overlay 50% down the image, when I want the center of the overlay to be there.
I've looked, among other things, at this post, which is definitely close -- but in both solutions, the image height is incapable of resizing, and in the former, the JS loads at page load, but then freezes, so that if I change page width/height, things get out of whack. Ideally, this solution wouldn't involve JS for just that reason (even if it reloaded on every resize, that feels non-ideal), but if that's the only solution, I'll take it.
Also, just for added details/fun, I've set a max-height on the image, because I don't want it to exceed roughly 300px height, even on a cinema display.
Basic fiddle of current attempt here, and identical code below. Any ideas? Thanks!
html
<div class='quotation_div'>
<img src='http://www.mountainprofessor.com/images/mount-ranier-mount-features-2.jpg'>
<div class='overlay'>
<p>Any reasonable amount of text should be able to go here. I want it to be able to center vertically even if it takes up 2 or 3 lines.</p>
</div>
</div>
css
.quotation_div {
position: relative;
display: table;
}
img {
width: 100%;
max-height: 300px;
}
.overlay {
z-index: 99;
width: 70%;
margin-left: 15%;
vertical-align: middle;
position: absolute;
top: 25%; /* Obvious problem, cause it's arbitrary */
}
p {
text-align: center;
color: red;
font-size: 165%;
font-weight: lighter;
line-height: 2;
}
You can use CSS background-size to set the width to 100% and the height will be calculated to maintain aspect ratio.
Here's a fiddle using that technique.
If you want the image as an HTML element then I suggest you set it's position to absolute and use the same method of disply:table-cell to center the overlay:
Here's a fiddle using that method, this one stretches the image because of the max-height.
Please Try the below css for .overlay as in your fiddle
.overlay {
z-index: 99;
width: 70%;
/* height: 100%; */
/* margin-left: 15%; */
/* vertical-align: middle; */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
or this is the updated fiddle link http://jsfiddle.net/hLdbZ/284/
I use this combination:
.CONTAINER {
position: relative;
text-align: center;
}
.TEXT {
text-align: center;
position: absolute;
top: 50%;
left: 0;
right: 0;
}
.IMG {
//for responsive image
width: 100%;
height: auto;
}
I just added to the html
<div align="center"></div>
to surround your existing code to get the image to center
hope that helps

Positioning text relative to an image when the image size changes

I'm trying to think of a clever way to deal with a part of a webpage where the image is going to be swapped out with different images (of varying widths, max being 620px wide), and a text caption is absolutely positioned over it. I want the text to absolutely position based on the width of the image rather than the width of the relatively positioned container.
I was thinking maybe something with background-image, rather than an image itself, but then I have to deal with the fact that it's an empty div with a background image, so I'd have to hardcode a height, which wouldn't work since some of these images would be taller than others.
Any solutions you guys can think of would be greatly appreciated. Thanks!
I'm not sure if I'm following 100%, but here's how to do what I think you're trying to do.
Create your container with position relative, set your widths and heights, and set overflow to hidden:
.container-outer {
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
Next, create an inner container inside of it that simply has position: absolute
.container-inner {
position: absolute;
}
Finally, create your overlay text style to be 100% width and center horizontally (or however you want it to be positioned)
.overlay {
position: absolute;
text-align: center;
width: 100%;
margin: 0;
}
Here's the jsfiddle with an example: http://jsfiddle.net/BGvca/1/
Good luck!
I raise the previous answer with some more CSS
<div class="imageholder">
<div class="caption">Simon & Garfunkel</div>
<img src="http://greenobles.com/data_images/simon-and-garfunkel/simon-and-garfunkel-03.jpg">
</div>​
.imageholder{
position: relative;
float: left;
}
.caption{
position: absolute;
top: 0;
left: 0;
right: 0;
font-family: Helvetica,sans-serif;
font-size: 1em;
background: rgba(0,0,0,0.5);
color: #fff;
padding: 1em 2em;
}
​
See the jsFiddle for reference.
If you make the div containing the image inline-block, its width will scale to the size of its content, ie your image.
Once the container is sizing correctly, you can center other child elements, like your caption, inside it using a wrapper with text-align: center, or no wrapper and value of auto for the left and right margins.
Here's an example: http://jsbin.com/uyajaw/3/edit (with ugly borders and backgrounds to show where stuff is)
Click the image to resize it and see the caption still centered.
Note that if your caption is likely to be larger than your image, it will probably expand the width of the container div, throwing off the center alignment. You can avoid this by making the setting position: absolute; left: 0; right: 0; on the caption, or by giving it a width that you know will always be smaller than your image.
I don't know if I'm over-thinking this, but here's a way to do it. If you specifically don't want to align the caption with the wrapper div, then you'll need to also account for the imagesLoaded event (jQuery plugin). Otherwise, you will either have an img width of 0 if not loaded, or you'll have the previously loaded img width in there (unless you go back to it).
Take a look at this Fiddle that shows a fixed width wrapper div and the caption centered on it.

Different Images for top and bottom of DIV's border

I have a site that I'm working on, and one of the requirements is that it cannot use any client side scripting (jQuery/JavaScript). And since I'm not that great with CSS, I'm a little stuck here.
I have a simple div, which should have a "border image". But I can't use the CSS border-image since it doesn't work with IE (already tested), and I can't get two different images for top and bottom to work with background-image: - so now I'm left wondering what I can do...
Below is what it should look like, both the arrow-looking things are 2 png files:
Is there any way to accomplish this? By using just 1 div, and 2 images? Without JavaScript, and also maintaining cross-browser compatibility (with some exceptions, like ie6<)?
This works in: IE9, Firefox, Chrome, Opera and Safari
CODE:
<style>
#Container {
width: 400px;
height: 400px;
margin-left: auto;
margin-right: auto;
border:1px solid #000000;
}
.boxTop {
position: relative;
left: 100;
top: 100;
width: 200px;
height: 10px;
background-color:#00CC00;
/*place background image css code here and remove line above*/
}
.box {
position: relative;
left: 100;
top: 100;
width: 200px;
height: 200px;
background-color:#CC0000;
}
.boxBtm {
position: relative;
left: 100;
top: 100;
width: 200px;
height: 10px;
background-color:#0000CC;
/*place background image css code here and remove line above*/
}
</style>
<div id="Container">
<div class="boxTop"></div>
<div class="box"></div>
<div class="boxBtm"></div>
</div>
Darcey's solution is very good. The box div with 3 divs inside, the middle one for content and the other 2 for the images (with css property background-image).
If you don't want to modify your html you could try playing with css :before and :after
Example
If the block has fixed height and width just set background one image and paddings. If it has fixed width use #Mr. Alien's solution. And if it has fixed height crop image horizontaly and make background repeat-x. If both width and height are dynamic i'd suggest to use 2-3 additional divs anyway (i know you want to avoid it), i dont think playing with :before and :after is better.
First solution: use just gradients. No images, no extra elements or even pseudo-elements.
Of course, gradients are not supported by IE9 and older, so another solution would be to use multiple backgrounds.
IE8 and older don't support multiple backgrounds the CSS3 way, but you could use AlphaImageLoader filter as fallback for these browsers.