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>
Related
I'm wondering if it's possible to have a centered text overlay (caption) on an image that is object-fit: contain; AND object-position: left top; (ie. not centered)
Image is being displayed in CSS Grid. (Display: Grid;)
Example of what I'm trying to do:
.container {
height: 40vw;
width: 40vw;
border: 1px solid black;
display:grid;
}
img {
max-width: 100%;
max-height:100%;
height: 100%;
width: 100%;
object-fit: contain;
object-position: left top;
}
<div class="container">
<img src="https://ichef.bbci.co.uk/news/660/cpsprodpb/A825/production/_103954034_gettyimages-990971906.jpg">
</div>
Thank you in advance!
object-fit controls how replaced content fits within its container. You do not have access to the replaced content in terms of layout and positioning. A way to achieve the effect you're wanting within a grid would be to add a new container, set some width/height attributes on your image based on the container values and then position your text relative to that image, avoiding the use of Object Fit.
.container {
align-items: start;
height: 40vw;
width: 40vw;
border: 1px solid black;
display:grid;
}
img {
display: block;
height: auto;
margin: 0 auto;
max-height: 40vw;
max-width: 40vw;
}
.textcontainer {
position: relative;
}
.textcontainer-x-text {
color: limegreen;
font-family: sans-serif;
font-weight: bold;
left: 50%;
position: absolute;
text-align: center;
text-transform: uppercase;
top: 50%;
transform: translate(-50%, -50%);
}
<p>Portrait</p>
<div class="container">
<div class="textcontainer">
<div class="textcontainer-x-text">Example Text Which Could Be Long</div>
<img src="http://placehold.it/150x400">
</div>
</div>
<p>Landscape</p>
<div class="container">
<div class="textcontainer">
<div class="textcontainer-x-text">Example Text Which Could Be Long</div>
<img src="http://placehold.it/300x150">
</div>
</div>
<p>Square</p>
<div class="container">
<div class="textcontainer">
<div class="textcontainer-x-text">Example Text Which Could Be Long</div>
<img src="http://placehold.it/300x300">
</div>
</div>
Here's one of the many solutions:
Use the position: relative; on the .container, then position: absolute; on the text (here I used a h3) to relocate it, using a -10vh from top.
HTML:
<div class="container">
<img src="https://ichef.bbci.co.uk/news/660/cpsprodpb/A825/production/_103954034_gettyimages-990971906.jpg">
<h3>LOREM IMPSUM</h3>
</div>
CSS:
.container {
height: 40vw;
width: 40vw;
border: 1px solid black;
display:grid;
position: relative;
}
img {
max-width: 100%;
max-height:100%;
height: 100%;
width: 100%;
object-fit: contain;
object-position: left top;
}
h3 {
position: absolute;
left: 50%;
transform: translate(-50%, -10vw);
top: 20vw;
}
I need to create something like the image below, without using any frameworks like bootstrap. Basically, I need the image to not be full width, but to take say 80% of the screen, and the title of the webpage to be above that image. At the moment all of my content is flowing all around the page.
It should also remain the same when I make the screen smaller.
I don't know why something simple is just not working for me...
.container {
width: 100%;
}
}
#main {
background: red;
width: 80%;
margin: 0 auto;
}
img {
max-width: 100%;
width: 80%;
float: right;
display: block;
}
<div id='main'>
<div class='container'>
<!--Image-->
<div id='img-div'>
<img id='image' src='https://www.projectarm.com/wp-content/uploads/2018/01/Frida-Kahlo-Vogue-1939-New-York-foto-di-Nickolas-Murray-2.jpg' />
<div id='img-caption'>This is a caption for the image</div>
</img>
</div>
<!--Title-->
<div id='pagetitle'>
<h1 id='title'>Frida Kahlo</h1>
<span id='tagline'>A short Tribute</span>
</div>
<!--End Title-->
</div>
<div id='tribute-info'>
This is my main information about the person
This is a link for more information
</div>
I would use flex for your container, so you can swap the order and it is a more up to date way to position things than floating, then inline block for your tag lines
Please note your image tag is invalid - img tags are self closing
.container {
width: 100%;
display: flex; /* make the container flex */
flex-direction: row; /* align the children in a row */
}
#img-div {
max-width: 85%; /* 85% width */
flex-basis: 85%;
order: 2; /* put this div 2nd */
}
#image {
display: block;
width: 100%; /* make div stretch size of div */
}
#pagetitle {
box-sizing: border-box; /* make this div 15% width with a bit of padding */
padding: 20px;
max-width: 15%;
flex-basis: 15%;
order: 1; /* put this div 1st */
display: flex; /* make this flex for vertical aligning and align children in a column */
flex-direction: column;
justify-content: center; /* vcertical align center (only works with flex) */
overflow: visible; /* show overflow */
position: relative; /* make overflow appear on top of image */
z-index: 2;
}
#title {
font-size: 20px;
font-weight: normal;
}
.tag-holder {
position: relative;
}
.tagline {
display: inline-block; /* make inline block so you can add white background */
white-space: nowrap;
font-size: 30px;
font-weight: bold;
text-transform: uppercase;
background: white;
padding:0.1em 0.5em;
}
<div id='main'>
<div class='container'>
<!--Image-->
<div id='img-div'>
<img id='image' src='https://www.projectarm.com/wp-content/uploads/2018/01/Frida-Kahlo-Vogue-1939-New-York-foto-di-Nickolas-Murray-2.jpg' />
</div>
<!--Title-->
<div id='pagetitle'>
<h1 id='title'>Emilia<br>Cole</h1>
<div class="tag-holder">
<span class='tagline'>Twist</span>
<span class='tagline'>in my</span>
<span class='tagline'>reality</span>
</div>
</div>
<!--End Title-->
</div>
<div id='tribute-info'>
This is my main information about the person
This is a link for more information
</div>
Without flex:
.container {
width: 100%;
position: relative;
}
.container:after {
content: '';
display: block;
height: 0;
clear: both;
overflow: hidden;
}
#img-div {
width: 85%;
/* 85% width */
float: right;
}
#image {
display: block;
width: 100%;
/* make div stretch size of div */
}
#pagetitle {
position:absolute; /* this is for 100% height */
top:0; bottom:0;
left:0;
right:15%;
overflow: visible;
z-index: 2;
}
.center { /* center text vertically */
position:absolute;
top:50%;
left:20px;
transform:translateY(-50%);
}
#title {
font-size: 20px;
font-weight: normal;
margin-top:0;
}
.tag-holder {
position: relative;
}
.tagline {
display: inline-block;
/* make inline block so you can add white background */
white-space: nowrap;
font-size: 30px;
font-weight: bold;
text-transform: uppercase;
background: white;
padding: 0.1em 0.5em;
}
<div id='main'>
<div class='container'>
<!--Image-->
<div id='img-div'>
<img id='image' src='https://www.projectarm.com/wp-content/uploads/2018/01/Frida-Kahlo-Vogue-1939-New-York-foto-di-Nickolas-Murray-2.jpg' />
</div>
<!--Title-->
<div id='pagetitle'>
<div class="center">
<h1 id='title'>Emilia<br>Cole</h1>
<div class="tag-holder">
<span class='tagline'>Twist</span><br>
<span class='tagline'>in my</span><br>
<span class='tagline'>reality</span>
</div>
</div>
</div>
<!--End Title-->
</div>
<div id='tribute-info'>
This is my main information about the person
This is a link for more information
</div>
Try this image caption is placed on top
.container {
width: 100%;
}
}
#main {
background: red;
width: 80%;
margin: 0 auto;
}
img {
max-width: 100%;
width: 80%;
float: right;
display: block;
}
#img-caption{
position: absolute;
left: 50%;
margin-left: -50px; /* margin is -0.5 * dimension */
}
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tribute Page</title>
</head>
<body>
<div id='main'>
<div class = 'container'>
<!--Image-->
<div id='img-div'>
<img id='image' src='https://www.projectarm.com/wp-content/uploads/2018/01/Frida-Kahlo-Vogue-1939-New-York-foto-di-Nickolas-Murray-2.jpg'/>
<div id='img-caption' class='alert alert-info'>This is a caption for the image</div>
</div>
<!--Title-->
<div id='pagetitle'>
<h1 id='title'>Frida Kahlo</h1>
<span id ='tagline'>A short Tribute</span>
</div>
<!--End Title-->
</div>
<div id ='tribute-info'>
This is my main information about the person
This is a link for more information
</div>
</div>
</body>
</html>
I was able to solve it simply by giving my container element a relative positioning, and my title #pagetitle element an absolute positioning, and then positioning the title top: 30px and left 30px RELATIVE to my container element. In this way, my title was positioned relative to the container, and not to the page - which would otherwise be the case had I not given the relative positioning to the container of the title.
.container {
height: 90vh;
min-height: 410px;
margin-top: 40px;
position: relative;
}
#pagetitle {
font-size: 2em;
text-transform: uppercase;
letter-spacing: 0.3em;
position: absolute;
top: 30px;
left: 30px;
}
I also gave a height to my container to make sure the content won't flow around it.
This can be easily done with CSS Grid, which is a more modern technology as well, but I preferred to stick to the traditional positioning to learn and fully understand them before skipping steps and using the easier grid system.
Whole pen and result can be seen here: https://codepen.io/commiesar/pen/GBMLza?editors=1100
I'm trying to create a specific layout in which:
Two images have to be one to the side of the other, filling all the width
Images height must adapt to create a squared image
In the middle of both images, an icon or text will be placed, as linking the images
The external container doesn't have a fixed height nor width
This is a representation of what I'm looking for:
Side to side images with one overlapping in the center
This is what I've managed to do, but it has the following problems:
Depending on the size of the images, the squares take a different size
The middle icon doesn't go to the middle...
.main_container_1 {
position: absolute;
width: 100%;
height: 600px;
background-color:lime;
margin: 10px;
padding: 10px;
}
.row {
width: 100%;
background-color: yellow;
display:flex
}
.image_cell {
width:50%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden
}
.image_cell img {
flex-shrink: 0;
min-width: 100%;
min-height: 100%
}
.text-cell {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
background:white;
}
.inner {
width: 50px;
height: 50px;
background-color:red;
}
<div class="main_container_1">
<div class="row">
<div class="image_cell">
<img src="http://placehold.it/450x200">
</div>
<div class="image_cell">
<img src="http://placehold.it/200x200">
</div>
<div class="text-cell">
<div class="inner">
text
</div>
</div>
</div>
You basically need to make your .row's height to be half its width (that would give you space for two squares). To do that you need to use the padding trick.
.row {
width: 100%;
padding-top: 50%;
background-color: yellow;
position: relative;
}
and then you'll need to position your images absolutely since you're faking their parent's height with padding.
.image_cell {
width: 50%;
height: 100%;
position: absolute;
top: 0;
}
.image_cell:nth-child(1) {
left: 0;
}
.image_cell:nth-child(2) {
right: 0;
}
and finally you can position your .text-cell in the center using transform like this (you must make sure to put position: relative to the parent container you want to position it relative to, which is .row in this case):
.text-cell {
position: absolute;
background: white;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
Here's the final result:
.main_container_1 {
position: absolute;
width: 100%;
height: 600px;
background-color: lime;
margin: 10px;
padding: 10px;
}
.row {
width: 100%;
padding-top: 50%;
background-color: yellow;
position: relative;
}
.image_cell {
width: 50%;
height: 100%;
position: absolute;
top: 0;
}
.image_cell:nth-child(1) {
left: 0;
}
.image_cell:nth-child(2) {
right: 0;
}
.image_cell img {
width: 100%;
height: 100%
}
.text-cell {
position: absolute;
background: white;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.inner {
width: 50px;
height: 50px;
background-color: red;
}
<div class="main_container_1">
<div class="row">
<div class="image_cell">
<img src="http://placehold.it/450x200">
</div>
<div class="image_cell">
<img src="http://placehold.it/200x200">
</div>
<div class="text-cell">
<div class="inner">
text
</div>
</div>
</div>
One more thing: you probably want to look into using background images instead to maintain aspect ratio.
In order to solve this, I've added a .square class to maintain the aspect ratio. The other thing I did is use justify-content and align-items on the div surrounding the cells in order to center the text cell.
* {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
color: #fff;
padding: 10px;
background-color: #333;
display: inline-block;
}
.container .cells {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.container .cells .image {
flex: 0 0 50%;
background: linear-gradient(
135deg,
rgb(252, 223, 138) 0%,
rgb(243, 131, 129) 100%
);
}
.container .cells .image img {
width: 100%;
height: 100%;
}
.container .cells .text {
position: absolute;
width: 60px;
line-height: 60px;
background-color: #5e2563;
text-align: center;
}
.container p {
margin-top: 10px;
}
.square {
position: relative;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.square .content {
position: absolute;
width: 100%;
height: 100%;
}
<div class="container">
<div class="cells">
<div class="image square">
<div class="content"></div>
</div>
<div class="image square">
<div class="content"></div>
</div>
<div class="text">
middle
</div>
</div>
<p>This is a variable width and height container</p>
</div>
This question already has answers here:
Horizontally & Vertically centering 2 divs within two side by side 50% width columns
(1 answer)
2 side by side divs centered?
(3 answers)
Align 2 divs side by side in a parent
(4 answers)
Closed 4 years ago.
How can I put two centered divs next to each other, with some padding in between? I've tried display: inline but that doesn't seem to work.
.my-container {
position: relative;
text-align: center;
color: red;
width: 20%;
margin: auto;
}
/* Centered text */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-moz-border-radius: 50%;
border-radius: 50%;
background-color: blue;
}
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text</div>
</div>
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text 2</div>
</div>
(Note: I'm also looking for a way to make the blue text-elipse a circle, but that's a different question I suppose.)
Use display:inline-block in your .my-container to align them side by side...
Also you will need to wrap your .my-container divs into a wrapper div with text-aign:center to align the inner inline items to center
.wrapper {
text-align: center;
}
.my-container {
position: relative;
text-align: center;
color: red;
width: 20%;
margin: auto;
display: inline-block;
}
/* Centered text */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-moz-border-radius: 50%;
border-radius: 50%;
background-color: blue;
}
<div class="wrapper">
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text</div>
</div>
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text 2</div>
</div>
</div>
You should add display: inline-block; to my-container class.
.my-container {
position: relative;
text-align: center;
color: red;
width: 20%;
margin: auto;
display: inline-block;
}
/* Centered text */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-moz-border-radius: 50%;
border-radius: 50%;
background-color: blue;
}
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text</div>
</div>
<div class="my-container">
<img src="https://demo.keypasco.com/res-1.2.2/img/User_ring.png" style="width:100%;">
<div class="centered">text 2</div>
</div>
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>