Vertically center a fluid image in a fluid container - css

I certainly do not want to add to the pile of vertical alignments CSS questions, but I've spent hours trying to find a solution to no avail yet. Here's the situation:
I am building a slideshow gallery of images. I want the images to be displayed as large as the user's window allows. So I have this outer placeholder:
<section class="photo full">
(Yes, I'm using HTML5 elements). Which has the following CSS:
section.photo.full {
display:inline-block;
width:100%;
height:100%;
position:absolute;
overflow:hidden;
text-align:center;
}
Next, the image is placed inside it. Depending on the orientation of the image, I set either the width or height to 75%, and the other axis to auto:
$wide = $bigimage['width'] >= $bigimage['height'] ? true: false; ?>
<img src="<?= $bigimage['url'] ?>" width="<?= $wide? "75%" : "auto"?>" height="<?= $wide? "auto" : "75%"?>"/>
So, we have a fluid outer container, with inside a fluid image. The horizontal centering of the image works, yet I cannot seem to find a way to vertically center the image within it's container. I have researched centering methods but most assume either the container or image has a known width or height. Then there is the display:table-cell method, which does not seem to work for me either.
I'm stuck. I'm looking for a CSS solution, but am open to js solutions too.

This works out fine:
section.photo.full {
display: table;
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
text-align: center;
}
section.photo.full a {
outline: 0;
display: table-cell;
vertical-align: middle;
}
section.photo.full img {
margin-top: 0;
}
I'm guessing display table-cell hadn't worked for you because it's parent container wasn't displayed as a table.
Here is a demo in jsfiddle:
http://jsfiddle.net/duopixel/5wzPS/

Maybe this works for you (div is the div wrapped around your image):
div {
display: table-cell;
vertical-align: middle;
text-align: center;
}
Running example.

Let's skip all of the table nonsense! :)
<div>
<img src="https://placehold.it/1000x1000">
</div>
div {
position: relative;
}
img {
position: absolute;
width: 70%;
top: 50%;
left: 50%;
transform: translate3d(-50%,-50%,0);
}
Example: https://jsfiddle.net/te29m9fv/1/

Related

Positioning text over an image so that it always points to the same spot in the image even when resizing the browser

I am currently building a website with weblflow but run into a problem that someone here might be able to help me with. The is an issue I have for multiple projects, so I would really appreciate someone's help.
Basically, if you have an image full screen size (set as background image, 100vw and 100vh), and then want to put headings/labels on top of that image pointing to specific sections in that image, how do I get these headings/labels always move with the image when someone would resize the browser?
As for now I used absolute positioning for the headings/labels and used % margins to position them where I want them to point to on the image. The image itself I have set to position relative. However, with that solution the headings/labels never exactly continue to point to the same spot on the image when resizing the browser.
I think the main issue is that when someone only changes the browser's width, the image gets (for example) smaller bc it keeps it's ratio. Vertically the headings/labels don't move bc the height was unchanged, it's just the browser's width that was changed. So horizontally it's still fine but vertically the headings are off now since the image got smaller due to resizing the browser's width. So I guess I do know why it's not working but I don't know how to fix this. If someone has a solution for this, please let me know.
As an example: if you open this page: http://nestin.bold-themes.com/classy/ and scroll down to the section ‘True value is always inside’, there is an image with 5 numbered labels, no matter how you resize the browser, these labels/numbers stay in the same spot of the image. I see this quite often on websites. How was this achieved?
Would appreciate any help!
You create a parent wrapper, put inside the image and all the divs.
the parent is relateive and the divs are absolute.
here's a small demo.
* {
box-sizing: border-box;
margin: 0;
}
img {
max-width: 100%;
display: block;
width: 100%;
}
.parent {
position: relative;
}
.parent .box {
position: absolute;
width: calc(1.6vw + 10px); height: calc(1.6vw + 10px);
border-radius: 50%;
background-color: #fff;
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
}
.parent .box.window {
top: 0;
left: 39%;
}
.parent .box.light {
top: 16%;
left: 46%;
}
.parent .box.pool {
top: 90%;
left: 50%;
}
.parent .box.plant {
top: 55%;
left: 3%;
}
<div class="parent">
<div class="box plant">1</div>
<div class="box window">2</div>
<div class="box light">3</div>
<div class="box pool">4</div><img src="https://images.pexels.com/photos/4075088/pexels-photo-4075088.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" alt=""/>
</div>
https://codepen.io/ShadiMouma/pen/BaKYyYX?editors=1100
You can achieve this with percentage positioning. For example,
In the parent div
position: relative;
In the child div
position: absolute;
top: 50%;
left: 30%;
Now the child div will always position itself 50% from the top and 30% from the left of the parent div. It does not matter what size the parent div is. I suggest you take a parent div and put the image and texts inside it.
Your example website also uses this technique.
check their code here
Another technique would be using HTML canvas. But for something simple like this, HTML canvas would be overkill.

Center overflowing element inside other element

I have an iframe inside a div like this:
<section>
<div>
<iframe></iframe>
</div>
</section>
the iframe contains a youtube video in flash but that probably won't matter in this case.
I'm building a mosaic and is therfore trying to use the div to crop the iframe to an appropriate size.
this is done by
.section
{height: 251px;
width: 198px;
overflow: hidden}
Works great but I would like to center the video aswell. For images, I add them as background-images and use
background-size: cover
to center them. This is neat because they automatically rescale to maximum possible size. However this doesn't work for video. I would settle for simply centering the iframe vertically and horizontally, if possible.
Will adding this to your css help? It works if div is bigger than section.
section div {
margin-top:-50%;
margin-left:-50%;
}
http://jsfiddle.net/hvCXm/
Wrappping the iframe and use text-align: center; to align horizontal center
div {
text-align: center;
display: block;
}
or
iframe {
margin: 0 auto;
display: block;
}
Try:
iframe {
margin:0 auto;
}
The standard way to center block elements:
iframe {
display: block;
margin-left: auto;
margin-right: auto;
}

Play button centred with different image/video sizes

How can I keep the play button centred even if the the image/video size changed?
.image{
position:relative;
width:500px; //changed
height:300px;
}
Here is my example...
Attention: my images/videos haven't no specific size, so they can change according to their own size... This is just an example!
I set up three examples to show how you could solve this problem.
Please see the fiddle: http://jsfiddle.net/audetwebdesign/mxSkQ/
The HTML is essentially yours:
<div class ="image ex1">
<a href="#">
<img src="http://placehold.it/200x150" alt="video">
<span class="play">
<span></span>
</span>
</a>
</div>
I am using a demo image with configurable dimensions, 200x150 for example, easily changed for testing.
Example 1 - Image Size Determines Size of the Parent Container
.ex1.image {
position: relative;
display: inline-block;
margin-left: 50px;
}
.image a {
display: inline-block;
position: relative;
}
/* Gets rid of the extra white space that follows an inline element*/
.image img {
vertical-align: bottom;
}
If you want the .image div to shrink to fit the image, use inline-block to display.
The margin-left is optional, will depend on the rest of the layout.
Important: To center the play button motif, simply set the a tag to display as inline-block and your arrow-motif-span will position itself nicely.
Because img is an inline element, browsers insert a small space after it that can show up if you have borders or backgrounds. Use vertical-align: bottom to clean that up.
Example 2 - Parent Container Has A Specified Width
You can specify a width for the .image parent container and then use text-align to position the image element.
.ex2.image {
position: relative;
display: inline-block;
width: 400px;
height: auto;
text-align: center;
}
Example 3 - Parent Container Has Full Width and Specified Height
In this example, I let the parent container fill up the width of the window and set the
height to 200px. To get vertical centering, I set margin-top to a hard-coded value that will depend on the height of the image. If you let the image take on a fixed height, this example is useful.
.ex3.image {
position: relative;
display: block;
width: auto;
height: 200px;
text-align: center;
}
.ex3.image a {
margin-top: 25px;
}
You need
top: 50%;
left: 50%;
margin: -25px 0 0 -25px; // top and left equal to half of the size * (-1)
http://jsfiddle.net/nGKcn/13/
Try playing with the image size/different images.
Give the image CSS of:
display: block;
margin: 0 auto;
This is just a general way you put stuff in the middle.
Unless I'm missing something maybe?

CSS - how to hide the top of a container using CSS-height, vertical-align and overflow?

I have an image container based on Jquery Mobile listview element structure.
Looks like this:
<li>
<div class="ui-btn-inner">
<div class="ui-btn-text">
<a>
<img src="img/products/l/demo2.jpg">
<h3>product2</h3>
</a>
</div>
</div>
</li>
I'm overriding JQM-CSS to create an image gallery-list. Images and h3 are both contained inside a link element. As the images can have different heights, I want to set a CSS fixed-height/overflow:hidden to the link element to cut off images at the top using vertical align: top.
Here is my CSS so far:
li {
display: inline-block;
min-width: 200px;
max-width: 300px;
width: 24%;
}
li img {
width: 100%;
position: static !important;
max-width: 185px;
max-height: inherit;
}
// fix height and overflow hidden
li a {
height: 100px;
overflow: hidden;
vertical-align: bottom;
}
It doesn't work... If I check on Firebug, the element-height is set to 100px, but it covers the image top versus covering the image bottom and h3, which I do not want to crop away.
I have tried setting line-height to 100px as well, but this does not work at all.
Any hints on what I'm doing wrong?
Thanks!
EDIT:
Can't use clip either, because I don't know at what height I want to start (img.height-100px) and I cannot clip from the bottom. Or can I?
SOLUTION:
It would work like this:
li a {
position:absolute;
bottom: 0;
left: 0;
}
li div.ui-btn-text {
position: relative;
height: 100px;
overflow: hidden;
}
Doesn't use vertical-align but the result is ok.
I'm afraid that can't work. Adding display:block; to your link and would be a start for your method, but check the result: http://jsfiddle.net/uu96D/
vertical-align: bottom; won't push the a tag to the bottom of the container. Here is a guide of how vertical-align works: http://phrogz.net/css/vertical-align/index.html
To solve your problem i'd go to some js solution, and add a negative top margin to the image if its taller than, for example, 80px. Here's a fiddle with the result: http://jsfiddle.net/uu96D/1/
And the code using jQuery:
$('img').each(function(){
var height = $(this).height();
if (height > 80) {
$(this).css({marginTop: "-" + (height-80)});
}
});

How to horizontally center a floating element of a variable width?

How to horizontally center a floating element of a variable width?
Edit: I already have this working using a containing div for the floating element and specifying a width for the container (then use margin: 0 auto; for the container). I just wanted to know whether it can be done without using a containing element or at least without having to specify a width for the containing element.
Assuming the element which is floated and will be centered is a div with an id="content"
...
<body>
<div id="wrap">
<div id="content">
This will be centered
</div>
</div>
</body>
And apply the following CSS:
#wrap {
float: left;
position: relative;
left: 50%;
}
#content {
float: left;
position: relative;
left: -50%;
}
Here is a good reference regarding that.
.center {
display: table;
margin: auto;
}
You can use fit-content value for width.
#wrap {
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin: auto;
}
Note: It works only in latest browsers.
This works better when the id = container (which is the outer div) and id = contained (which is the inner div). The problem with the highly recommended solution is that it results in some cases into an horizontal scrolling bar when the browser is trying to cater for the left: -50% attribute. There is a good reference for this solution
#container {
text-align: center;
}
#contained {
text-align: left;
display: inline-block;
}
Say you have a DIV you want centred horizontally:
<div id="foo">Lorem ipsum</div>
In the CSS you'd style it with this:
#foo
{
margin:0 auto;
width:30%;
}
Which states that you have a top and bottom margin of zero pixels, and on either left or right, automatically work out how much is needed to be even.
Doesn't really matter what you put in for the width, as long as it's there and isn't 100%. Otherwise you wouldn't be setting the centre on anything.
But if you float it, left or right, then the bets are off since that pulls it out of the normal flow of elements on the page and the auto margin setting won't work.
The popular answer here does work sometimes, but other times it creates horizontal scroll bars that are tough to deal with - especially when dealing with wide horizontal navigations and large pull down menus. Here is an even lighter-weight version that helps avoid those edge cases:
#wrap {
float: right;
position: relative;
left: -50%;
}
#content {
left: 50%;
position: relative;
}
Proof that it is working!
To more specifically answer your question, it is probably not possible to do without setting up some containing element, however it is very possible to do without specifying a width value. Hope that saves someone out there some headaches!
Can't you just use display: inline block and align to center?
Example.
for 50% element
width: 50%;
display: block;
float: right;
margin-right: 25%;

Resources