Is there a CSS way to vertically align my div within the body element?
The thing is my div will have a different height each time, so its not constant.
These are the things I've tried but they dont work:
body { vertical-align: middle; }
#mainContent {
vertical-align: middle;
}
// Also this
body { margin-top: 20%; margin-bottom: 20%; }
I did it without table: (demo on dabblet.com)
The main trick in this demo is that in the normal flow of elements going from top to bottom, so the margin-top: auto is set to zero. However, for an absolutely positioned element acts the same distribution of free space, and similarly can be centered vertically at the specified top and bottom (does not work in IE7).
This trick will work with any sizes of div.
HTML:
<div></div>
CSS:
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
A common problem indeed. I have seen many people offering straight css solutions for this but they all require knowing the height of the element needing to be centered, so no help there.
I usually do it this way using jquery:
$(document).ready(function(){
site.resize();
$(window).resize(function(){
site.resize();
});
});
var site = {
resize: function(){
var new_margin = Math.ceil(($(window).height() - $('#mainContent').height()) / 2);
$('#mainContent').css('margin-top', new_margin + 'px');
}
};
Surprisingly (or not), the vertical-align tool actually works best for this job. Best of all, no Javascript is required.
In the following example, I am positioning the outer class in the middle of the body, and the inner class in the middle of the outer class.
Preview: http://jsfiddle.net/tLkSV/513/
HTML:
<div id="container">
<span></span><div class="outer">
<span></span><div class="inner">
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
padding: 0; }
#container {
text-align: center;
height: 100%; }
span {
height: 100%;
vertical-align: middle;
display: inline-block; }
.outer {
width: 100px;
height: 200px;
padding: 0;
border: 1px solid #000;
vertical-align: middle;
display: inline-block; }
.inner {
background: red;
width: 30px;
height: 20px;
vertical-align: middle;
display: inline-block; }
Vertical align works by aligning the centers of elements that are next to each other. Applying vertical-align to a single element does absolutely nothing. If you add a second element that has no width but is the height of the container, your single element will move to vertically center with this no-width element, thus vertically centering it. The only requirements are that you set both elements to inline (or inline-block), and set their vertical-align attribute to vertical-align: middle.
Note: You may notice in my code below that my <span> tag and <div> tag are touching. Because they are both inline elements, a space will actually add a space between the no-width element and your div, so be sure to leave it out.
You can do it without using tables, and without adding extra elements:
<ul>
<li>One short item</li>
<li>Any real long text...</li>
<li>Another short item</li>
</ul>
And then the CSS:
ul {
list-style-type: none;
display: table-row;
}
li {
display: table-cell;
vertical-align: middle;
}
You can see it here
It would work with any other kind of hierarchy, including div, p, etc.
Honestly, my opinion is often that if you're doing vertical alignment you should still be using a table. I know it's often frowned upon, but it is still the simplest and cleanest way to vertically center something.
HTML
<table>
<tbody>
<tr>
<td>
<div>Your DIV here.</div>
</td>
</tr>
</tbody>
</table>
CSS
td {vertical-align: middle;}
Related
I am trying to get a square to have a limited size and stay within the bounds of the parent div and scale cleanly. I can get one or two of these, but not all.
Setup is I have a main div, two column divs on the left, and a div that takes up the remaining space on the right. I would like the div on the right to contain the square and the bounds of the square stay within the parent div. I can get it to stay put if I don't use the padding-bottom to keep it square, but then the pic of the item looks horrible.
Take a look at my js bin. The pathway to hit the square is:
Weapons -> item b1 -> click on it to make it stay
The padding-bottom pushes it way down and outside of the parent div and blows the bottom out of the whole thing.
css
.itempanel{
display: block;
align-items: center;
position: relative;
}
.itemcontainer{
position: relative;
top: 30%;
height: 60%;
width: auto;
margin-left: auto;
margin-right: auto;
}
.itemdisplay{
display:none;
flex-direction: column;
width: 60%;
padding-bottom: 60%;
margin-left: auto;
margin-right: auto;
position: relative;
align-items: center;
overflow: hidden;
}
/* .itemdisplay::after{
content: " ";
display: block;
padding-bottom: 100%;
} */
html
<div class="itempanel">
<div class = "itemcontainer">
<div id="itemdisplay" class="itemdisplay">
<img id="itemimg" class="itemimg" src=""></img>
<div id="itemdesc" class="itemdesc">
<div id="itemtitle" class="itemtitle"></div>
<div id="itembody" class="itembody"></div>
<a id="itemclick" class="itemclick" href="">Click To Place Order</a>
</div>
</div>
</div>
</div>
Thanks for any help!
*little bit of background - girlfriend wants a skyrim wedding so building out a website for rsvp and stuff. Belethor's shop is going to be setup to help those not so nerdy shop for cheap cosplay outfits. Everything else works just like I want it, but the itempanel/itemcontainer/itemdisplay is not in the display area how I want it.
figured it out. The psuedo element has to be opposite what padding you are using. For instance, using this worked like I expected it to. it's always the simple things...
.itemdisplay::after{
content: " ";
display: block;
padding-top: 100%;
I see that you have created a class .bottommenu but I don't see it being applied anywhere on your HTML or JavaScript. If you want to display two rows using Flex-box and you are not quite sure of the height of your images or content, you could set that parent container to have a height: auto and on your child container you could use the align-self: flex-end to handle the positioning of items, and on your parent use the justify-content or align-content to your liking. Something like this:
div .parent {
display:flex;
height: auto;
min-width: 300px;
}
div .child {
align-self: center;
width: 100%;
min-height: 50%;
height: auto;
margin: 0 auto;
}
Hope that helps.
I have two <div>s with absolute position. One is displayed and the other is display: none on load. When the link on the visible one is clicked it is moved and the other is displayed.
I have a third <div> with link that I would like to display directly below these. Since they’re both position: absolute I have not been able to find a way to do this. I have found various solutions, but most of them are workarounds for using absolute position. Since my <div>s need to show ontop of each other I unfortunately can’t remove the absolute positioning.
As such I have tried various combinations of position: absolute and position: relative on the three <div>s, but so far nothing has worked.
JSFiddle with my problem: https://jsfiddle.net/dagz9tLw/1/
<div> with id linkbar is the one that needs to be at the bottom.
The other two <div>s don’t have a set height so margin-top won’t work. linkbar also needs to be just below the <div>s and not right at the bottom of the page.
I experienced that using a div acting as a buffer is quite useful and easy to implement for this purpose. You just set it above your div#linkbar and adjust it's height on load and when the div#front get's repositioned:
$("#topBuffer").css("height", $("#front").offset().top + $("#front").height());
$("#showLink").click(function() {
if (!$("#back").is(":visible")) {
$("#back").show();
$("#front").animate({
'marginLeft': "+=30px"
});
$("#front").animate({
'marginTop': "+=20px"
});
$("#topBuffer").animate({
'height': "+=20px"
});
}
return true;
});
.front {
width: 400px;
display: block;
border: 2px solid #000000;
text-align: center;
position: absolute;
margin-top: 20px;
z-index: 10;
background-color: white;
}
.back {
display: none;
width: 400px;
border: 2px solid #000000;
text-align: center;
position: absolute;
z-index: 1;
margin-top: 20px;
background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="front" class="front">
<a id="showLink" href="javascript:void(0);">front</a>
</div>
<div id="back" class="back">
back
</div>
<div id="topBuffer"></div>
<div id="linkbar">
test
test
test
</div>
For example, I have a div :
<div>I am a square</div>
Inside style.css :
div:nth-child(1) {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
}
The text-align: center property aligns the text in the center of a div, but the text remains on the top inside the square, I want to push the text to the bottom of a square. So it looks like in this diagram. How can I accomplish this without wrapping the text in any sort of tag?
__________________
| |
| |
| |
| |
| |
|_I am a square__|
If you really don't want to wrap your text
You can do this by setting the display of the block to be table-cell, and then vertical-align to bottom. This is the only way I can think of to align the text to the bottom of the div without wrapping it in another element. This will cause a slew of other problems with your div placement, though; and you will probably have to wrap the div anyway.
div {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
/* Here is my addition */
display: table-cell;
vertical-align: bottom;
}
JsFiddle example.
If you wrapping your text is an option (AKA the right way)
You really should wrap your text. Aside from semantics, you can get a lot more flexibility in your styling options.
Once you do that, your div can be set to position: relative so that it can act as a container for the child, who will get the position: absolute style. Then you add bottom: 0 and voila! It's glued to the bottom.
This method is preferred as you can still style your div as you'd expect.
HTML:
<div>
<p>test</p>
</div>
<div>
<p>test</p>
</div>
CSS:
div {
height: 200px;
width: 200px;
border-radius:0;
background-color: pink;
color: #fff;
text-align: center;
margin : 0 3px 3px 0;
/* Make sure that it contains the child properly */
position: relative;
}
div p {
position : absolute;
bottom : 0;
}
Example
So if I want to have two divs, each of 100% of the entire page, side by side, given that the wrapper has overflow:hidden, how should I go about implementing it?
I have tried using inline-block but it did not work.
I have tried using float too but it caused errors.
I want the second div to be hidden so I can change it's left as an animation, sort of like a slide.
Thanks in advance!
If I've understood you correctly, you can achieve what you're after using inline-block. You just have to be a little careful with white space (i.e. you need to make sure you've got no white space between the two child div elements). I've stopped the divs from wrapping by setting white-space: nowrap;.
<div class="foo">
<div> woo woo !</div><div> woo woo !</div>
</div>
.foo {
overflow: hidden;
white-space: nowrap;
}
.foo > div {
display: inline-block;
vertical-align: top;
width: 100%;
background: aqua;
}
.foo > div + div {
background: lime;
}
Try it out at http://jsfiddle.net/8Q3pS/2/.
Edit: Here's an alternative implementation using position: absolute;: http://jsfiddle.net/8Q3pS/5/. That way you'll be able to animate the second one into view using left. Note that you'll need to set a height on the parent div.
.foo {
position: relative;
width: 100%;
height: 1.5em;
overflow: hidden;
}
.foo > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
background: aqua;
}
.foo > div + div {
left: 100%;
background: lime;
}
This should be purely a matter of positioning one of the divs off the page using absolute positioning and transitioning the left property using either hover state or javascript.
Hover the red div.
Codepen Example
Could you not set max-width to 100%, not set the actual width and float them side by side? With both overflow:hidden, as they expand it should create horizontal scrollbars.
I've been spacing list items using the technique found in this answer, but a recent change is requiring me to insert the elements dynamically. I have found that for some reason the approach completely stops working if the elements are inserted dynamically. Why?
This fiddle demonstrates the static and dynamic versions.
As seen in the linked question, the basic idea is below. It's just when the HTML is inserted to the page via Javascript, the menu items don't justify.
HTML
<div id="menuwrapper">
<div class="menuitem">menu</div>
<div class="menuitem">menu</div>
...
<span class="stretcher"></span>
</div>
CSS
#menuwrapper, #dynamic {
height: auto;
background: #000;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 300px; /* just for demo */
}
#dynamic {
background: blue;
}
.menuitem {
width: auto;
height: 40px;
vertical-align: top;
display: inline-block;
*display: inline;
zoom: 1
background: #000;
color: yellow;
}
.stretcher {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0;
}
There was no spaces between elements.
take a look jsfiddle
document.getElementById("dynamic").innerHTML = '<div class="menuitem">CAREERS</div> <div class="menuitem">TRADE</div> <div class="menuitem">CONTACT US</div> <div class="menuitem">PRIVACY POLICY</div> <div class="menuitem">T&CS</div> <div class="menuitem">SITEMAP</div> <span class="stretcher"></span>';
Some related articles:
- Fighting the Space Between Inline Block Elements
You can do what apple website does and make your menu items display: table-cell;
This is probably not completely cross browser compatible (e.g. IE6 will probably fail), but it does not require any javascript at all