What is the best way to vertically center the content of a div when the height of the content is variable. In my particular case, the height of the container div is fixed, but it would be great if there were a solution that would work in cases where the container has a variable height as well. Also, I would love a solution with no, or very little use of CSS hacks and/or non-semantic markup.
Just add
position: relative;
top: 50%;
transform: translateY(-50%);
to the inner div.
What it does is moving the inner div's top border to the half height of the outer div (top: 50%;) and then the inner div up by half its height (transform: translateY(-50%)). This will work with position: absolute or relative.
Keep in mind that transform and translate have vendor prefixes which are not included for simplicity.
Codepen: http://codepen.io/anon/pen/ZYprdb
This seems to be the best solution I’ve found to this problem, as long as your browser supports the ::before pseudo element: CSS-Tricks: Centering in the Unknown.
It doesn’t require any extra markup and seems to work extremely well. I couldn’t use the display: table method because table elements don’t obey the max-height property.
.block {
height: 300px;
text-align: center;
background: #c0c0c0;
border: #a0a0a0 solid 1px;
margin: 20px;
}
.block::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
/* For visualization
background: #808080; width: 5px;
*/
}
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
padding: 10px 15px;
border: #a0a0a0 solid 1px;
background: #f5f5f5;
}
<div class="block">
<div class="centered">
<h1>Some text</h1>
<p>But he stole up to us again, and suddenly clapping his hand on my
shoulder, said—"Did ye see anything looking like men going
towards that ship a while ago?"</p>
</div>
</div>
This is something I have needed to do many times and a consistent solution still requires you add a little non-semantic markup and some browser specific hacks. When we get browser support for css 3 you'll get your vertical centering without sinning.
For a better explanation of the technique you can look the article I adapted it from, but basically it involves adding an extra element and applying different styles in IE and browsers that support position:table\table-cell on non-table elements.
<div class="valign-outer">
<div class="valign-middle">
<div class="valign-inner">
Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
</div>
</div>
</div>
<style>
/* Non-structural styling */
.valign-outer { height: 400px; border: 1px solid red; }
.valign-inner { border: 1px solid blue; }
</style>
<!--[if lte IE 7]>
<style>
/* For IE7 and earlier */
.valign-outer { position: relative; overflow: hidden; }
.valign-middle { position: absolute; top: 50%; }
.valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
/* For other browsers */
.valign-outer { position: static; display: table; overflow: hidden; }
.valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>
There are many ways (hacks) to apply styles in specific sets of browsers. I used conditional comments but look at the article linked above to see two other techniques.
Note: There are simple ways to get vertical centering if you know some heights in advance, if you are trying to center a single line of text, or in several other cases. If you have more details then throw them in because there may be a method that doesn't require browser hacks or non-semantic markup.
Update: We are beginning to get better browser support for CSS3, bringing both flex-box and transforms as alternative methods for getting vertical centering (among other effects). See this other question for more information about modern methods, but keep in mind that browser support is still sketchy for CSS3.
you can use flex display such as below code:
.example{
background-color:red;
height:90px;
width:90px;
display:flex;
align-items:center; /*for vertically center*/
justify-content:center; /*for horizontally center*/
}
<div class="example">
<h6>Some text</h6>
</div>
Using the child selector, I've taken Fadi's incredible answer above and boiled it down to just one CSS rule that I can apply. Now all I have to do is add the contentCentered class name to elements I want to center:
.contentCentered {
text-align: center;
}
.contentCentered::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -.25em; /* Adjusts for spacing */
}
.contentCentered > * {
display: inline-block;
vertical-align: middle;
}
<div class="contentCentered">
<div>
<h1>Some text</h1>
<p>But he stole up to us again, and suddenly clapping his hand on my
shoulder, said—"Did ye see anything looking like men going
towards that ship a while ago?"</p>
</div>
</div>
Forked CodePen: http://codepen.io/dougli/pen/Eeysg
Best result for me so far:
div to be centered:
position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;
You can use margin auto. With flex, the div seems to be centered vertically too.
body,
html {
height: 100%;
margin: 0;
}
.site {
height: 100%;
display: flex;
}
.site .box {
background: #0ff;
max-width: 20vw;
margin: auto;
}
<div class="site">
<div class="box">
<h1>blabla</h1>
<p>blabla</p>
<p>blablabla</p>
<p>lbibdfvkdlvfdks</p>
</div>
</div>
For me the best way to do this is:
.container{
position: relative;
}
.element{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
The advantage is not having to make the height explicit
This is my awesome solution for a div with a dynamic (percentaged) height.
CSS
.vertical_placer{
background:red;
position:absolute;
height:43%;
width:100%;
display: table;
}
.inner_placer{
display: table-cell;
vertical-align: middle;
text-align:center;
}
.inner_placer svg{
position:relative;
color:#fff;
background:blue;
width:30%;
min-height:20px;
max-height:60px;
height:20%;
}
HTML
<div class="footer">
<div class="vertical_placer">
<div class="inner_placer">
<svg> some Text here</svg>
</div>
</div>
</div>
Try this by yourself.
Related
It regularly occurs that I want to center a css box inside another one both vertically and horizontally. What's the simplest way to do so that satisfies the following constraints?
The box should be precisely centered, not approximately.
The technique should work in modern browsers and in IE versions back to 8
The technique should not depend on explicitly knowing the width or height of either the centered content or the containing box.
I generally know the container is larger than the content, but supporting larger content (which then overflows symmetrically) would be nice...
The underlying content of the container must still be able to respond to clicks and hovers except where obscured by the centered content
I currently use 4 (!) nested divs to achieve this, with css along the following lines:
.centering-1 {
position:absolute;
top:0; left:0; right:0; bottom:0;
text-align:center;
visibility:hidden;
}
.centering-2 {
height:100%;
display:inline-table;
}
.centering-3 {
display:table-cell;
vertical-align:middle;
}
.centering-content {
visibility:visible;
}
You can see this in action as a jsbin snippet.
However, this approach, while workable, feels like extreme overkill due to the large number of wrapper divs, and it doesn't work with content that's larger than the container. How can I center things in CSS?
Horizontal centering is easy:
.inner {
width: 70%; /* Anything less than 100% */
margin-left: auto;
margin-right: auto;
}
But vertical centering is a little tricky. The best technique for modern browsers is to combine inline-block and a pseudo elements. This originates from "Ghost element", the last technique at http://css-tricks.com/centering-in-the-unknown/. It sets adds a pseudo-element and uses inline-block styles get the centering.
The CSS:
.outer {
height: 10rem;
text-align: center;
outline: dotted black 1px;
}
.outer:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.inner {
width: 10rem;
display: inline-block;
vertical-align: middle;
outline: solid black 1px;
}
An example on Codepen: http://codepen.io/KatieK2/pen/ucwgi
For simpler cases, the following may be good options:
For single lines of content, you can do a quick and dirty vertical centering job on the text within an element by using line-height larger than your font-size:
.inner {
border: 1px solid #666;
line-height: 200%;
}
The solution with widest support is to use a non-semantic table. This works with very old versions of IE and doesn't require JavaScript:
td.inner {
vertical-align: middle;
}
And here is simple solution for known height elements (which could be in ems, not px):
.outer {
position:relative;
}
.inner {
position: absolute;
top:50%;
height:4em;
margin-top:-2em;
width: 50%; left: 25%;
}
You can get by with 2 fewer elements. Anything less than this is going to require things that IE8 (and IE9) doesn't support.
http://cssdeck.com/labs/0ltap96z
<div class="centering-1">
<div class="centering-2">
<div class="intrinsically-sized-box">
<p>You can put any content here too and the box will auto-size.</p>
</div>
</div>
</div>
CSS:
body {max-width:750px;}
.generalblock {
margin-top:2em;
position:relative;
padding:10px;
border:20px solid cyan;
font-size: 18px;
}
.centering-1 {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
text-align:center;
visibility:hidden;
display: table;
width: 100%;
}
.centering-2 {
display:table-cell;
vertical-align:middle;
}
.intrinsically-sized-box {
visibility:visible;
max-width:300px;
margin: 0 auto;
background: yellow;
position:relative;
border:1px solid black;
}
<div class="titelcontent">
<div class="name">Name</div>
<div class="hzline"></div>
</div>
I want name div and hzline div to auto fit 100% in titelcontent.
The label (for example, Name) will vary in length and I want the red underline to span the remainding space of the titlecontent div.
How do I achieve the following? It is easy to do this using tables but I can't figure out how to do this via span or div.
You can use div like a table by using table-cell.
.titlecontent {
display: table;
}
.name {
display: table-cell;
white-space: nowrap;
}
.hzline {
display: table-cell;
border-bottom: 3px solid red;
width: 100%;
}
See DEMO.
Updated to allow background images to show through
You can make the mark-up a bit tighter by using a pseudo-element as follows:
<div class="wrapper">
<div class="inner">Photoshop</div>
</div>
and use the following CSS styling:
div.wrapper {
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
line-height: 180%;
background: red url(http://placekitten.com/1000/500) no-repeat left top;
overflow: hidden;
}
div.inner {
position: relative;
display: inner;
color: yellow;
padding-right: 0.50em;
border: 1px dotted yellow;
}
div.inner:after {
content: "\A0";
position: absolute;
bottom: 0;
left: 100%;
border-bottom: 5px solid #d71d00;
width: 1000%;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/wE8bC/
How It Works
The parent element div.wrapper may contain a background image or be transparent and show the background of some ancestor element. You need to set overflow: hidden.
For the label (<div.inner>), set position: relative and then generate a 100% width pseudo-element with a bottom border to serve as an underline. Use absolute positioning to place div.inner:after to the right of <div.inner> (left: 100%) and make the width relatively large. The pseudo-element will trigger an overflow condition but this is taken care of by hiding the overflow in the parent element. You can control left/right spacing using padding.
You can use set the display property to either inline or inline-block. If you use display: inline, it will work in IE7; adjust the line height as needed for styling.
Note that the generated content is a non-breaking space, hex code "\A0".
Support for IE7
If you need to support IE7, you will need a hack if you use inline-block as discussed in a previous question: IE7 does not understand display: inline-block
IE7 also does not support table-cell so some of the other posted solutions will face the same limitation.
Or an alternative to using display: table:
.name {
float: left;
}
.line-wrapper {
display: block;
overflow: hidden;
padding-top: 6px;
}
.hzline {
border-bottom: 3px solid red;
width: 100%;
}
See example.
I've guessed you are looking something like this. Please find my solution based on my understanding about the image you posted.
HTML
<div>
<span>Photoshop</span>
</div>
<div>
<span>Adobe Illustrator</span>
</div>
<div>
<span>3D Max</span>
</div>
<div>
<span>Maya</span>
</div>
<div>
<span>Windows 8 Pro</span>
</div>
CSS
div {
line-height: 150%;
border-bottom: 5px solid #d71d00;
}
div span{
position:relative;
bottom: -10px;
background:#fff;
padding: 0 5px;
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
}
Please do let me know your feedback. Thanks
im making a self financial accounting program but im gonna use html,css and php to do it
i have a basic layout with 5 main divs on the front page
here it is the mock:
http://s24.postimage.org/le9yrx4np/divs.jpg
i never coded before and im failing hard
i want this layout compatible with "desktops" this is my desktop version
im working based on a 1024 x 768 screen
but i want webkits compatible for all browsers because i want this able to resize if its a little bigger or smaller
im not sure if need em since i can just set things to like 100% but thats where my problem starts
here is my work so far
http://jsfiddle.net/dhJPS/
my prblems are
the middle three divs are being overlapped by the right div, notice on the words how they are not centered from the left div to the right div
i cant seem to understand the concept of floating to well i cant make this layout work like i want
anyways if you can help me out a little with this one is greatly appreciated!!
thanks
#leftside {
background-color: blue;
width: 170px;
height: 770px;
float: left;
}
#intab {
background-color: yellow;
width: 100%;
height: 297px;
}
#currentday {
background-color: white;
width: 100%;
height: 170px;
}
#outtab {
background-color: yellow;
width: 100%;
height: 297px;
}
#rightside {
background-color: black;
height: 770px;
width: 200px;
float: right;
margin-top: -765px;
}
* {
margin: 0px;
padding: 0px;
list-style-type: none;
}
body {
text-align: center;
display: block;
}
img {
border: none;
}
You simply need to rearrange some things.
When floating something to the right, the HTML always need to come before any other HTML. Right, left, static is the best order to follow.
You always want to cascade your CSS. Put global styles at the top of the style sheet. The body styles should be at the top of your CSS, not the bottom.
I added a wrapper div to set a minimum width. This way the interior content will never go below that width, ensuring things never overlap. However they will expand as much as needed.
It is rare you need to set width: 100%; in the CSS. It's not always a bad thing, but you shouldn't bother setting that unless you specifically know you need it.
I rearranged some things, and removed some of the HTML that jsFiddle don't need.... UPDATED FIDDLE HERE
Here is your answer.
Key issues:
margin
inner div to group all the central ones
[VERY IMPORTANT] display: inline-block; - This will make sure that your div will be the exact size you defined. if not used it will use 100% for both width and height
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
.panels {
height: 768px;
}
.rightside, .leftside {
width: 170px;
height: 100%;
background-color: yellow;
display: inline-block;
}
.leftside {
float: left;
}
.rightside {
float: right;
}
.innerPanels {
height: 100%;
margin: 0 170px;
}
.intab, .outtab {
height: 25%;
background-color: lime;
opacity: 0.75;
}
.currentday{
height: 50%;
background-color: darkgray;
}
</style>
</head>
<body>
<div class="panels">
<!--LEFT SIDE -->
<div class="leftside">left side</div>
<!-- RIGHT SIDE -->
<div class="rightside">right side</div>
<div class="innerPanels">
<!-- IN -->
<div class="intab">in</div>
<!-- CURRENT DAY -->
<div class="currentday">current day</div>
<!-- OUT -->
<div class="outtab">out</div>
</div>
</div>
</body>
</html>
As the title says, I need two divs to be equally high. They should be as high as it needs to be for the content to fit. The current CSS is:
.portfolioleft{
float:left;
width:189px;
background-color: #436FAC;
min-height: 100px;
height: auto;
color: #FFF;
padding: 20px;
margin-bottom: 20px;
border-radius: 10px;
}
.portfolioleft img{
border-radius: 10px;
}
.portfolioright{
float:right;
width:500px;
background-color: #436FAC;
min-height: 100px;
height: auto;
color: #FFF;
padding: 20px;
margin-bottom: 20px;
border-radius: 10px;
}
.portfolioright a{
color:#FFFFFF;
}
and the html for the divs is:
<div class="portfolioleft"><img src="img" alt="img" width="189" height="311" /></div>
<div class="portfolioright">
<h2>Title</h2>
<p>Text</p>
</div>
<div class="clear"> </div>
CSS alone cannot tackle this feat (unless you want a hack solution where you can use an image). You will need to implement a JS solution. Since the content is dynamic and you do not know how high the columns will be, you will need to access the DOM to determine the height of the tallest column then apply to the indicated columns. I use the following regularly and it works quite well and is easy to implement.
http://www.jainaewen.com/files/javascript/jquery/equal-height-columns.html
Unfortunately this is a tricky problem in CSS. If you only want to extend the background color of your left sidebar to the bottom of the section (with its height defined by the right div), try wrapping them inside a parent div (which scales to the height of the right div), then positioning the left div with position:absolute and height of 100% like so:
<div class="portfolio">
<div class="portfolioleft">...</div>
<div class="portfolioright">...</div>
</div>
.portfolio {
position: relative;
background: white;
}
.portfolio .portfolioleft {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 100%;
background: #436FAC;
}
.portfolio .portfolioright {
margin-left: 200px;
}
If BOTH sides are dynamic and you need both heights to match, the only surefire way to make it work across all major browsers is to resort to a table-based layout with two columns, as karmically bad as that might be.
cell properties in your left right div
i checked your code and replace the float into display table-cell
you can check to this live http://jsfiddle.net/rohitazad/prMLh/1/
I want to set vertical alignment of image inside a div. I use img { vertical-align:middle}
but it is not working.
Using the line-height property will solve the problem:
<style>
.someclass {
width: 300px;
height: 300px;
text-align: center;
line-height: 300px;
border: dotted;
}
.someclass img {
margin: auto;
vertical-align: middle;
}
</style>
<div class="someclass">
<img src="someimg.jpg" border="0" alt="">
</div>
This is a solution that doesn't require JavaScript (as my previous solution did).
You can achieve what you want by assigning display: table-cell to the containing div. Here's an example: http://jsbin.com/evuqo5/2/edit
I feel I must warn you that you will need to test this in every browser you intend to support. Support for the table-cell value is fairly new, particularly in Firefox. I know it works in Firefox 4, but I don't know about any of the 3.x iterations. You'll also want to test in IE (I've only tested in Chrome 10 and Firefox 4).
The CSS:
div#container {
width: 700px;
height: 400px;
position: relative;
border: 1px solid #000;
display: table-cell;
vertical-align: middle;
}
div#container img {
margin: 0 auto;
display: block;
}
You won't need the div#container img styles if you don't also want to horizontally align the image.
If you're trying to do what I think, vertical align isn't going to work; you'll need to use positioning.
In general, position the container relative, and then position the image absolute, with top and left set to 50%, and then move the image back to the center by setting negative margins equal to half the width / height.
Here's a working example: http://jsbin.com/evuqo5/edit
Basic CSS is this:
#container { position: relative; }
#container img {
position: absolute;
left: 50%;
top: 50%;
margin-top: /* -1/2 the height of the image */
margin-left: /* -1/2 the width of the image */
}
See this awser: How to vertical align image inside div
If you want to align horizontally also, add the right and left, like this:
div {
position:relative;
}
img {
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
The following post has some useful references:
Text Alignment w/ IE9 in Standards-Mode
Also, depending on which version of IE you are testing against, you may end up needing some browser-specific hacks or some jQuery/JavaScript code.
If you have to, use a one-row-one-cell table and take advantage of the vertical-align property. This is brute-force, not overly semantic, but it works.
If you set the div display attribute to table-cell then vertical-align: middle; will work.
The vertical-align rule only affects table cells or elements with display: table-cell.
See this article from SitePoint for a detailed explanation.
<style>
/* change body to .someClasses's parent */
body {
width: 100%;
height: 100%;
display: table;
}
body > .someclass {
width: 300px;
height: 300px;
text-align: center;
border:dotted;
margin: 0 auto
display: table-cell;
vertical-align: middle;
}
</style>
<body>
<div class="someclass">
<img src="someimg.jpg" border="0" alt="">
</div>
</body>