How to center div vertically inside of absolutely positioned parent div - html

I am trying to get blue container in the middle of pink one, however seems vertical-align: middle; doesn't do the job in that case.
<div style="display: block; position: absolute; left: 50px; top: 50px;">
<div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
<div style="background-color: lightblue;">test</div>
</div>
</div>
Result:
Expectation:
Please suggest how can I achieve that.
Jsfiddle

First of all note that vertical-align is only applicable to table cells and inline-level elements.
There are couple of ways to achieve vertical alignments which may or may not meet your needs. However I'll show you two methods from my favorites:
1. Using transform and top
.valign {
position: relative;
top: 50%;
transform: translateY(-50%);
/* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
<div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
<div class="valign" style="background-color: lightblue;">test</div>
</div>
</div>
The key point is that a percentage value on top is relative to the height of the containing block; While a percentage value on transforms is relative to the size of the box itself (the bounding box).
If you experience font rendering issues (blurry font), the fix is to add perspective(1px) to the transform declaration so it becomes:
transform: perspective(1px) translateY(-50%);
It's worth noting that CSS transform is supported in IE9+.
2. Using inline-block (pseudo-)elements
In this method, we have two sibling inline-block elements which are aligned vertically at the middle by vertical-align: middle declaration.
One of them has a height of 100% of its parent and the other is our desired element whose we wanted to align it at the middle.
.parent {
text-align: left;
position: absolute;
height: 56px;
background-color: pink;
white-space: nowrap;
font-size: 0; /* remove the gap between inline level elements */
}
.dummy-child { height: 100%; }
.valign {
font-size: 16px; /* re-set the font-size */
}
.dummy-child, .valign {
display: inline-block;
vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
<div class="parent">
<div class="dummy-child"></div>
<div class="valign" style="background-color: lightblue;">test</div>
</div>
</div>
Finally, we should use one of the available methods to remove the gap between inline-level elements.

use this :
.Absolute-Center {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
refer this link: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

Use flex blox in your absoutely positioned div to center its content.
See example https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview
.some-absolute-div {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
-moz-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
-moz-align-items: center;
align-items: center;
}

Center vertically and horizontally:
.parent{
height: 100%;
position: absolute;
width: 100%;
top: 0;
left: 0;
}
.c{
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
}

For only vertical center
<div style="text-align: left; position: relative;height: 56px;background-color: pink;">
<div style="background-color: lightblue;position:absolute;top:50%; transform: translateY(-50%);">test</div>
</div>
I always do like this, it's a very short and easy code to center both horizontally and vertically
.center{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="center">Hello Centered World!</div>

EDIT: 10/22 as nowdays, display flex or grid is widely implemented i would suggest to use one or the other (display:table/table-cell will still work if you need compatibility with old or exotic browsers , like my TV...)
flex
.a{
position: absolute;
left: 50px;
top: 50px;
}
.b{
display:flex;
align-items:center;
background-color: pink;
height: 56px;
}
.c {
background-color: lightblue;
}
/* move the flex demo aside */
.a.b{left:100px}
You even need less markup
<div class="a">
<div class="b">
<div class="c">test</div>
</div>
</div>
<div class="a b">
<div class="c">test</div>
</div>
grid (similar at that point)
.a{
position: absolute;
left: 50px;
top: 50px;
}
.b{
display:grid;
align-items:center;
background-color: pink;
height: 56px;
}
.c {
background-color: lightblue;
}
/* move the grid demo aside */
.a.b{left:100px}
You even need less markup
<div class="a">
<div class="b">
<div class="c">test</div>
</div>
</div>
<div class="a b">
<div class="c">test</div>
</div>
Original answer 02/2015 (still efficient everywhere) use with very old or exotic browsers not implementing yet flex or grid
You may use display:table/table-cell;
.a{
position: absolute;
left: 50px;
top: 50px;
display:table;
}
.b{
text-align: left;
display:table-cell;
height: 56px;
vertical-align: middle;
background-color: pink;
}
.c {
background-color: lightblue;
}
<div class="a">
<div class="b">
<div class="c" >test</div>
</div>
</div>

Here is simple way using Top object.
eg: If absolute element size is 60px.
.absolute-element {
position:absolute;
height:60px;
top: calc(50% - 60px);
}

An additional simple solution
HTML:
<div id="d1">
<div id="d2">
Text
</div>
</div>
CSS:
#d1{
position:absolute;
top:100px;left:100px;
}
#d2{
border:1px solid black;
height:50px; width:50px;
display:table-cell;
vertical-align:middle;
text-align:center;
}

You can do it by using display:table; in parent div and display: table-cell; vertical-align: middle; in child div
<div style="display:table;">
<div style="text-align: left; height: 56px; background-color: pink; display: table-cell; vertical-align: middle;">
<div style="background-color: lightblue; ">test</div>
</div>
</div>

Related

Div container with text on the left side and overflow image on the right

I want to recreate the following structure:
With black is div container and inside the container on the left there will be text and on the right i need an image bigger than the container.
I tried to do this by grids but things got funky real quick.
As it seems to be important that the containing div maintains the dimensions (as shown by its border), this snippet adds in the actual image as a background on a pseudo element that is absolutely positioned.
That way the protruding bit of image does not alter the container div dimensions.
Here's a simple snippet using a grid to position the left and right sides. Of course you will want to alter proportions to suit your particular case, add styling to the leftside and so on:
.container {
display: grid;
grid-template-columns: 3fr 2fr;
width: 50vw;
height: auto;
margin-top: 10vh;
border: solid 2px black;
}
.leftside {
padding: 1vw;
}
.rightside {
position: relative;
width: 100%;
height: 100%;
}
.rightside::before {
content: '';
background-color: pink;
background-image: url(https://picsum.photos/id/1015/500/200);
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
width: 50%;
height: 140%;
bottom: 0;
left: 25%;
position: absolute;
}
<div class="container">
<div class="leftside">
<h2>Heading</h2>
<div>text1</div>
<div>text2</div>
</div>
<div class="rightside"></div>
</div>
go with the flexbox.
.main-container{
display:flex;
display: flex;
justify-content: space-evenly;
border:1px solid black;
margin:30px;
height:300px;
padding:10px;
}
.image{
width:50vw;
position:relative;
}
img{
width:100%;
height:150%;
width: 100%;
height: 150%;
top: -50%;
position: absolute;
}
.text{
display:flex;
align-items:center;
}
<div class="main-container">
<div class="text">
<p>Somthing Somthing</p>
</div>
<div class="image">
<img src="https://loremflickr.com/640/360" />
</div>
</div>
Here you go:
.background {
padding: 25px;
display: flex;
border: 1px solid black;
height: 150px;
position: relative;
margin-top: 50px;
}
.text {
border: 1px solid green;
width: 50%;
padding: 10px;
}
.img {
text-align: center;
width: 50%;
display: flex;
justify-content: center;
}
.img>div {
border: 1px solid blue;
width: fit-content;
padding: 10px;
height: 200px;
position: absolute;
bottom: 25px;
}
<div class="background">
<div class="text">
<p>
text1
</p>
<p>
text2
</p>
<button>
Click me
</button>
</div>
<div class="img">
<div>
me img
</div>
</div>
</div>
Hope this helps

Vertically centering an element inside an image

I know there are many ways to vertically center a div inside another div, but what I'm experiencing problems on is a way to vertically center a div inside an image element.
Here's the minimum code I require:
HTML:
<img class="star" src="star.png"></img>
<div class="vCenter">Text to be vertically centered in the image.</div>
CSS:
.star {
position: absolute; /* I need this value for another thing in my project */
}
Also, the height of the image is in percentage.
Wrap the image in another element
Move the position: absolute to the wrapper element
Center the text in the wrapper element, let the image expand the wrapper element
.wrapper {
position: absolute;
top: 30px;
left: 10px;
display: flex;
justify-contents: center;
align-items: center;
}
.wrapper img {
/* debug */
background: yellow;
width: 300px;
height: 300px;
}
.wrapper .vCenter {
position: absolute;
left:50%;
max-width: 100%;
transform: translateX(-50%);
}
<div class="wrapper">
<img class="star" src="star.png" />
<div class="vCenter">Text to be vertically centered in the image.</div>
</div>
Try this way:
<div class="container">
<img class="star" src="star.png"></img>
<div class="centered-div">Text to be vertically centered in the image.</div>
</div>
.container {
position: relative;
}
.star {
display: block;
margin: auto;
width: 100%;
}
.centered-div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
code solution:https://stackblitz.com/edit/web-platform-5qivc2?file=index.html
referred link:https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_image_text
<div class="container">
<img src="https://via.placeholder.com/250" alt="Snow" style="width:100%;">
<div class="centered">Centered</div>
</div>
.container {
position: relative;
text-align: center;
color: white;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20px;
color: red;
}
You may add your image and text to a container set to position:absolute
This should do the job ;-)
.container {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// just add the desired position to this container
}
.star {
position: absolute;
}
.vCenter {
z-index: 1;
}
<div class="container">
<img class="star" src="star.png" />
<div class="vCenter">Text to be vertically centered in the image.</div>
</div>

Strange behaviour of position absolute inside table-cell on IE11

I have to fix this layout, which is a messy combination of flexbox, table layout and absolute positioning.
While it's working normal on Chrome, FF and Safari, the output screen on IE11 is strange.
In my code, I want the span to be at the bottom-right of each square, but on IE11, it appears on top-right instead.
Can anyone please help me to fix this problem? The constraint here is that the flexbox .container and the table system must be maintained. I want to fix only the span element. Thanks in advance!
.container {
display: flex;
width: 400px;
}
.inner {
width: 50%;
}
.table {
display: table;
width: 100%;
border: 1px solid;
}
.table:before {
content: '';
display: table-cell;
width: 0;
padding-bottom: 100%;
}
.cell {
display: table-cell;
vertical-align: bottom;
position: relative;
padding: 20px;
}
.cell span {
position: absolute;
bottom: 20px;
right: 20px;
}
<div class="container">
<div class="inner">
<div class="table">
<div class="cell">
Yeah?
<span>Yo!</span>
</div>
</div>
</div>
<div class="inner">
<div class="table">
<div class="cell">
Yeah?
<span>Yo!</span>
</div>
</div>
</div>
</div>
remove your .cell span block and
use below code instead of that.
i have checked its working in every browser.
.cell span {
float: right;
}
One thing you can do to fix it in IE11 is to wrap your cell contents into a block container and then add position: relative to it. Now you can adjust the position with right: 0px - see demo below:
.container {
display: flex;
width: 400px;
}
.inner {
width: 50%;
}
.table {
display: table;
width: 100%;
border: 1px solid;
}
.table:before {
content: '';
display: table-cell;
width: 0;
padding-bottom: 100%;
}
.cell {
display: table-cell;
vertical-align: bottom;
position: relative;
padding: 20px;
}
.cell span {
position: absolute;
/*bottom: 20px;
right: 20px;*/
right: 0px; /* ADDED */
}
.cell div { /* ADDED */
position: relative;
}
<div class="container">
<div class="inner">
<div class="table">
<div class="cell">
<div>Yeah?
<span>Yo!</span></div>
</div>
</div>
</div>
<div class="inner">
<div class="table">
<div class="cell">
<div>Yeah?
<span>Yo!</span></div>
</div>
</div>
</div>
</div>

z-index of child element of a flex item

I want an absolute positioned child element (.tag-preview-container) of a flex item (.image-container) to overlap other elements in the DOM (for instance the header .header). I'm setting the z-index of the absolute positioned element to be 2 (even 1 should work). However, the element doesn't overlap any DOM element outside the flex container(.tags-panel). In fact, it is completely cut off by the container. I am not setting z-index of any other element in the DOM, so the root should be the stacking context.
<div class="panel-container">
<div class="header">
</div>
<div class="tags-panel">
<div class="image-container">
<div class="tag-preview-container">
</div>
</div>
<div class="image-container">
</div>
<div class="image-container">
</div>
<div class="image-container">
</div>
</div>
</div>
This is the scss code and here's the JSFiddle
.panel-container {
width: 400px;
height: 400px;
position: relative;
margin: auto;
.header {
width: 100%;
height: 40px;
background-color: green;
}
.tags-panel {
position: absolute;
background-color: red;
top: 40px;
bottom: 0px;
width: 100%;
overflow-y: auto;
display: flex;
flex-flow: row wrap;
align-content: flex-start;
}
}
.image-container {
flex: 0 0 33%;
box-sizing: border-box;
border: 1px solid black;
margin-top: 5px;
margin-left: 1px;
height: 80px;
background-color: yellow;
position: relative;
.tag-preview-container {
background-color: black;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 200px;
height: 200px;
z-index: 2;
opacity: 0.5;
}
}
The z-index is affected by the overflow property in .tags-panel, removing overflow-y: auto; will solve the issue. Here is the updated fiddle https://jsfiddle.net/yc5xanax/
overflow-y: auto; will automatically wrap/hide the content outside the .tags-panel container.

Why cant center an image inside a 'div' with 'float' right or left?

I have enclosed an image inside a nested div .box. If it is not floated the image can be exactly centered to the .box, but when I float it left or right the center alignment goes away! I have 4 images with various sizes that need te be centered inside their own .box. How can I fix it?
HTML
<div class="con">
<div class="box">
<img src="../_images/icon-test.png">
</div>
</div>
CSS
.con {
width:300px;
height:200px;
background: #996600;
}
.box {
position:relative;
width:150px;
height:150px;
background-color: #333333;
display:table-cell;
text-align:center;
vertical-align:middle;
float:right;
}
You can use display: flex for this.
Change your display: table-cell to display: flex.
Then change text-align:center; and vertical-align:middle; to align-items: center; and justify-content: center; to center it vertically and horizontally.
Edit: Then I have also added a max-width of 150px to the image, to stop it expanding out of the container when the image is bigger than it. Props to #Hkidd for pointing out that this happens.
.con {
width: 300px;
height: 200px;
background: #996600;
}
.box {
position: relative;
width: 150px;
height: 150px;
background-color: #333333;
display: flex;
align-items: center;
justify-content: center;
float: right;
}
img {
max-width: 150px;
}
<div class="con">
<div class="box">
<img src="http://placehold.it/200x100">
</div>
</div>
Explanation
I think you have to position the img absolute, so it will be positioned absolute to its parent .box since .box is positioned relative. Also the display: table-cell; is unnecessary since the img is not inside a table.
This is what I came up with:
.con {
background: #996600;
height: 200px;
width: 300px;
}
.box {
background-color: #333333;
float: right;
height: 150px;
position: relative;
width: 150px;
}
.box img {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 90%;
}
<div class="con">
<div class="box center">
<img src="http://placehold.it/120x100">
</div>
</div>
If you have a single image as in the question, you can use the line-height solution which places the image exactly in center of the .box div & use vertical-align: middle on the image. Works on all browsers & simple to understand.
Refer code:
.con {
width: 300px;
height: 200px;
background: #996600;
}
.box {
position: relative;
width: 150px;
height: 150px;
background-color: #333333;
text-align: center;
vertical-align: middle;
float: right;
line-height: 150px;
}
img {
height: 60px;
vertical-align: middle;
}
<div class="con">
<div class="box">
<img src="http://www.w3schools.com/css/img_fjords.jpg">
</div>
</div>