CSS vertically align div while maintaining aspect ratio - css

I used the JsFiddle at jsfiddle.net/5tzk3/10. I changed it to display the div as square shaped dialog (both horizontally and vertically centered). The result is at jsfiddle.net/5tzk3/548.
As you see, centering horizontally was easy, but I could not get it centered vertically. Anyone who knows how to do that with pure CSS?
Edited code below:
<div class="blind">
<div class="wrapper">
<div class="main">
I'm your div with an aspect-ratio of 1:1!
</div>
</div>
</div>
html, body, .blind {
height: 100%;
width: 100%;
}
.blind {
left: 0;
position: fixed;
text-align: center;
top: 0;
}
.wrapper {
display: inline-block;
margin: auto;
position: relative;
width: 50%;
}
.wrapper:after {
content: '';
display: block;
padding-top: 100%;
}
.main {
background-color: rgb(0, 162, 232);
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
}

Use display: table for the parent div, and display:table-cell; vertical-align: middle for the content div which you want to vertically center.

The most common way of doing this if you've got an element with known dimensions is to use positioning to firstly position it top: 50% (which places the top edge of the element 50% of the way down) and then use a negative top-margin of half the height of the element (pulling it back up by half it's height).
To give you an example, to absolutely position a 200x200 element dead-centre on the page you would use:
.element{
display: block;
width: 200px;
height: 200px;
position: absolute;
top: 50%;
margin-top: -100px
}
Alternatively, you can use a combination of display: table and then display: table-cell on the parents to open up the ability to use vertical-align although this is a bit nasty when it comes to laying out elements around it.

you can drop absolute positionning and use either display:table or inline-block with pseudo elements.
here is a mixed of the 2 methods
1) html/body as a table one cell
2) inner content with ratio preserved and content as inline box set in the middle.
.ratio1-1 {
width:25%;
vertical-align:middle;
margin:auto;
background:turquoise;
}
.ratio1-1:before {
content:'';
padding:50% 0;
width:0;
display:inline-block;
vertical-align:middle;
}
.ib {
display:inline-block;
vertical-align:middle;
}
/* center body content as a table cell */
html {
height:100%;
width:100%;
display:table;
}
body {
display:table-cell;
vertical-align:middle;
text-align:center;
}
<div class="ratio1-1">
<div class="ib">content in middle</div>
</div>
demo: http://codepen.io/gc-nomade/pen/pubFm

Related

How to create a vertical div which fill entire screen?

I have four DIVs :
The first div has a fixed height and located on top (header).
The second div also has a fixed height and located below the first div.
The fourth div has a fixed height located on bottom.
The third div will have a variable height: it will expand to make the total of four divs are full to vertical space in browser IF the content is less than that. But it will follow the content's height if the content's height is larger than that. So at all times, I want the first div (the header) to stick at the top of the page, and the fourth div (the footer) to stick at the bottom of the page. I have no way to know how tall the content will be.
header
header
header
header
the CSS file:
#container { width:800px; height:*; }
#header { height:200px; }
#menu { height:50px; }
#content { height:*; }
#footer { height:150px; }
can I actually do this? how is the correct css way to do this? I get the feeling this should be not too hard, but I can't find relatable answers anywhere. Thank you.
What you could do is something like this:
#content { height: 100vh; /*100% of viewport height*/
margin-top: 250px;
margin-bottom: 150px; }
This way it will always be 100% of the screen height in total.
Well that turned out looking cool, JSBin
HTML
<div class="header">Header !</div>
<div class="menu">Menu !</div>
<div class="content">Content !</div>
<div class="footer">Footer !</div>
CSS
body { margin: 0; }
.header { width: 100%; height: 200px; position: fixed; top: 0; }
.menu { width: 100%; height: 50px; position: fixed; top: 200px; }
.footer { width: 100%; height: 150px; position: fixed; bottom: 0; }
.content { width: 100%; position: fixed; top: 250px; bottom: 150px;
overflow: auto; }

How to hide overflown content of floated element

I have 2 columns 50% width each. Inside each column I have overflown content positioned absolutely relative to body.
<div class='column left'>
<div class='inner'><h1>Pink</h1></div>
</div>
<div class='column right '>
<div class='inner'><h1>Blue</h1></div>
</div>
I need the inner divs to be hidden. How do I do that? Setting overflow:hidden on .column has no effect on inner divs. Fiddle HERE
PS. The idea is to animate the width of the columns and show the inner content. This fiddle illustrates what i am trying to achieve (but it is using vh, vw that I cannot use due to browser requirement)
html, body {
width :100%;
height: 100%;
position: relative;
}
.column {
float: left;
width: 50%;
height: 100%;
overflow: hidden; /*has no effect*/
}
.inner {
position: absolute;
top: 50%;
width: 100px;
}
.left .inner {
right: 20px;
text-align: right;
}
.right .inner {
left: 20px;
text-align: left;
}
Are you simply looking for
visibility: hidden;
or
display: none;
This last one removes the element from the DOM.

Absolute position element on equal height columns - how?

Here's what I can't do by any means, using only CSS:
Columns should have equal heights.
And, on a given column, a absolute positioned element should be present relative to that column:
The HTML:
<div class="wrapper">
<div class="inner">
<div class="column">
<img src="http://www.english3.com/wp-content/uploads/2013/05/DFI-Logo-300px-X-200px.png"/>
</div>
<div class="column info">
<p>Some text here yeah :).</p>
<p>Some text here yeah :)</p>
<p>Some text here yeah :)</p>
<a class="link" href="#">I should be absolute.</a>
</div>
</div>
</div>
THE CSS:
.wrapper {
overflow: hidden;
position: relative;
}
/*added */
.inner {
width: 100%;
display: table;
}
.column {
display: table-cell;
width: 50%;
vertical-align: top;
background-color:red;
}
.column img {
max-width:100%;
display: block;
}
.info {
background-color: blue;
padding-bottom: 25px;
}
.link {
display: block;
position: absolute;
left: 50%;
bottom: 3%;
color: yellow;
}
Fiddle to play:
Here's the try with table-cell; and a relative inner container:
http://jsfiddle.net/BuuFv/98/
TRIES AND FRUSTRATIONS:
1) - Display table
For equal heights I can't pull this out, due to FF issues.
Tried with an extra relative parent container
But left image doesn't shrink according to it's container on FF.
Tried giving height: 100%
http://davidwalsh.name/table-cell-position-absolute
But didn't work either, the image doesn't shrink or expands using max-width;
2 - Huge positive padding and negative margin values
Will not work, because the absolute positioned element will not stay in place.
3 - Faux Columns
Seems to be of any help, due to the fact that, we are not playing with solid background colours, and we have an image on the left column instead.
A picture:
Any help, please?
1)
On this case, adding an extra relative container with position relative attribute (.inner), did the trick.
2)
The fact that the image didn't shrink or grow on FF was because it wasn't considering the max-width declaration as it should.
Fix:
.inner {
width: 100%;
display: table;
table-layout:fixed; /* <<-- ADD */
}
the table-layout fixed algorithm made Firefox recognize the max-width in the cell and this let the image shrink.
Credits on this solution should be shared with Paul O'B.
Here is my take on it http://jsfiddle.net/E6UDD/
So basically, uncoment padding and negative margin hack, and add the height of the column to be the same amount.
Then, add relative positioning to the .column.
Then, position of the absolute positioned link should be top: 50% to have it at the very bottom, or 44% to mimic the 3% you originally indended.
DEMO
.wrapper {
position:relative;
overflow: hidden;
white-space:nowrap;
outline:1px solid red;
height:auto;
}
.column {
position:relative;
display:inline-block;
vertical-align:top;
background-color:red;
width:50%;
}
.column img {
max-width:100%;
min-width:30px;
min-height:20px;
}
.info {
position:absolute;
bottom:0;
top:0;
background-color: blue;
}
.link {
clear:left;
display: block;
position: absolute;
bottom: 3%;
color: yellow;
}
http://jsfiddle.net/BuuFv/75/
You can try changing the link from absolute positioned to another table-cell. Not 100% on your use case but it seems to accomplish what you are asking.
.link {
height:100px;
display:table-cell;
vertical-align:bottom;
color: yellow;
}

Vertical align in CSS, no heights known

Here's my markup:
<div id="container">
<img id="image" src="image.jpg" />
<div id="contents">Contents</div>
</div>
The height of #container equals the height of #image.
All the heights are dynamic (they change on window resize).
The image can not be set via background property.
How can I have Contents over the image and vertically centered in #container?
Is the height of #contents known? In that case this should do it (jsfiddle demo):
#container{
position:relative;
/* For demo only */
height:500px;
border: 5px solid red;
}
#image{
position:absolute;
/* For demo only */
height:500px;
}
#contents{
position: absolute;
top:50%;
height:100px;
margin-top: -50px; /* Half of #contents height */
/* For demo only */
background-color: blue;
}
​This ought to do what you are looking for. I have just set the height of the container and image in css, but if they are the same set in html or using javascript, the result should be the same. The background colour is just there for clarity.
#container {
background-color: #333;
height: 200px;
}
#image{
height: 200px;
float: left;
}
#contents{
line-height: 200px;
float: left;
position: fixed;
}
​
EDIT: Here is a fiddle of a solution using the old classic margin auto trick. The only thing that may cause problems here is that the parent needs to be position: fixed; which may cause issues for you elsewhere. The main thing is it works, and no heights are set using pixels.
link
Here is the code from the fiddle for a pure css solution with no fixed heights.
<div id="container">
<img id="image" src="https://www.google.co.uk/logos/2012/juan_gris-2012-hp.jpg" />
<div id="contents">Contents</div>
</div>
#container {
position: fixed;
}
#contents{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50%;
height: 10%;
margin: auto;
}
If you know the height of #contents you can set up
#container{position:relative;}
#contents{
position:absolute;
top:50%; /*50% of parent*/
margin-top:/*negative one-half of container height i.e. if contaner is 4 em -2em*
}
You say you don't know the height of #contents, though.
Another option is to set the display: to table-cell and use vertical-align: middle
#container{
display: table-cell;
vertical-align: middle;
}
But depending on what browsers you are targetting for support, that may cause display issues as well.
The more sure fire way is to combine the first option with some jquery or javascript to find the element's height and set its margin-top:
content= document.getElementById('content')
content.style.marginTop = '-' + content.offsetHeight + 'px';
http://jsfiddle.net/h76sy/
EDIT: Sorry, had a bug in my javascript, try it now

vertical align - z-index

I am trying to align vertically a modal box. But the margin-top:50% did not work as i expect. Basically i want a square centered on another square.
<style type="text/css">
#modal {
width: 300px;
height: 300px;
z-index: 100;
background-color: red;
margin: 0 auto;
position:relative;
margin-top:50%; //problem here
}
#content {
position: absolute;
width:950px;
height: 950px;
margin: 0 auto;
background-color: green;
}
#replace {
width:950px;
height:500px;
}
</style>
<div id="replace">
<div id = "content"></div>
<div id="modal"></div>
</div>
thanks
demo
Instead of margin you need to use top:325px; for #modal
If it's not too much trouble to have the modal inside the content div, you might want to try this HTML:
<div id = "content">
<div id="modal"></div>
</div>
...with this CSS:
#modal {
width: 300px;
height: 300px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -150px;
}
#content {
position: absolute;
width: 550px;
height: 550px;
background-color: green;
}
Demo
Basically you're absolutely-positioning the modal div inside the content div, and telling it to go start at 50% from the top and 50% from the left. This will center the top-left corner of the modal, but not the div as a whole. To center the div as a whole, you then have to add a negative margin to move it back up and to the left. The amount of the negative margin is half the height/width of the modal div.
If you want to keep the same HTML, you can still accomplish the same thing using this technique, just make sure to do position: relative on your replace div so that any absolutely-position children are positioned relative to it.
Add position: relative; to your container if you want absolutely positioned elements inside it to be positioned relative to it:
#replace {
position: relative;
width: 950px;
height: 500px;
}
Then set to top value of the item you want to position. One thing to note here, your #replace div is the container here, but it's smaller than the #content div, so when you position #modal, you're going to have to give it specific pixel values to get it centered over #content.

Resources