I set my wrapper's height to 100vh to fill up the entire screen and then inside the wrapper I wanted a div to be set to 50% - vertically in the middle and used position: relative and set top / transform (translateY) to 50%. It works perfectly on my desktop computer, but when displaying on my macbook (both running Chrome) it doesn't display correctly and is "pushed" to maybe 30% of screen height. What am I doing wrong ? Here is my code:
#main-1 {
width: 100%;
height: 100vh;
background-image: linear-gradient(to right, #e1484f 50%, #f9f9f9 50%);
}
#info-left {
width: 20%;
height: 300px;
padding-left: 10%;
position: relative;
top: 50%;
transform: translateY(-50%);
float: left;
text-align: center;
color: #FFF;
}
You can set up your inner div this way:
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
It will center horizontally and vertically your div.
Do not forget the -webkit for a good cross-browsing exerience.
Related
When working with hero images or full screen anything, I typically see text or images with the following bit of CSS:
.item {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
What is this code actually doing?
The reason why transform: translate(-50%, -50%) is required is because you want the center of the element to line up with the center of its parent. In simple terms, it can be boiled down to translateX(-50%) translateY(-50%), which means:
move me leftwards by 50% of my width, along the x-axis, and
move me upwards by 50% of my height, along the y-axis
This effectively moves the center of the element to its original top left corner. Remember then when you set left: 50%; top 50% on the element, you are moving its top left corner to the center of its parent (which means it is not visually centered at all). By moving the element back leftwards and upwards by half of its width and height respectively, you are sure that its center now aligns with the parent's center, making it visually horizontally + vertically centered.
As a proof of concept, see the code snippet below: hover over the parent to cause the child element's "ghost" to reposition itself by means of transform: translate(-50%, -50%):
body {
margin: 0;
padding: p;
}
.parent {
background-color: #ccc;
width: 100vw;
height: 100vh;
position: relative;
}
.child {
background-color: rgba(0,0,255,0.5);
width: 50px;
height: 50px;
position: absolute;
top: 50%;
left: 50%;
}
.child::before {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
content: '';
transition: all .5s ease-in-out;
}
body:hover .child::before {
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child"></div>
</div>
TL;DR version
Let's say there is a .container and an .item inside.
This code below is positioning .item relatively to .container; meaning .item top left corner is in the center of its container
.item {
top: 50%;
left: 50%;
}
While the below is positioning .item relatively to its own width and height; meaning minus 50% of its width and height.
.item {
transform: translate(-50%, -50%);
}
If the two code snippets below are combined, then the expected center will show up.
When working with hero images or full screen anything, I typically see text or images with the following bit of CSS:
.item {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
What is this code actually doing?
The reason why transform: translate(-50%, -50%) is required is because you want the center of the element to line up with the center of its parent. In simple terms, it can be boiled down to translateX(-50%) translateY(-50%), which means:
move me leftwards by 50% of my width, along the x-axis, and
move me upwards by 50% of my height, along the y-axis
This effectively moves the center of the element to its original top left corner. Remember then when you set left: 50%; top 50% on the element, you are moving its top left corner to the center of its parent (which means it is not visually centered at all). By moving the element back leftwards and upwards by half of its width and height respectively, you are sure that its center now aligns with the parent's center, making it visually horizontally + vertically centered.
As a proof of concept, see the code snippet below: hover over the parent to cause the child element's "ghost" to reposition itself by means of transform: translate(-50%, -50%):
body {
margin: 0;
padding: p;
}
.parent {
background-color: #ccc;
width: 100vw;
height: 100vh;
position: relative;
}
.child {
background-color: rgba(0,0,255,0.5);
width: 50px;
height: 50px;
position: absolute;
top: 50%;
left: 50%;
}
.child::before {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
content: '';
transition: all .5s ease-in-out;
}
body:hover .child::before {
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child"></div>
</div>
TL;DR version
Let's say there is a .container and an .item inside.
This code below is positioning .item relatively to .container; meaning .item top left corner is in the center of its container
.item {
top: 50%;
left: 50%;
}
While the below is positioning .item relatively to its own width and height; meaning minus 50% of its width and height.
.item {
transform: translate(-50%, -50%);
}
If the two code snippets below are combined, then the expected center will show up.
Given a relative black box within the white box here:
I'm looking to offset the black box with negative top and left positioning.
Is it possible to offset the black box via the content inside?
Use transform: translate(-50%,-50%) to move the white box up and to the left 50% of it's overall width/height.
body {
background: #444;
}
div {
width: 50vh;
height: 50vh;
background: white;
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%,-50%);
}
span {
display: block;
background: black;
transform: translate(-50%,-50%);
color: white;
}
<div>
<span>asdf asdf<br>asdfasdf<br>fooooo<br>barrr</span>
</div>
I have an element, of id "r-u-ok". It's a pop-up and its content can have different word counts.
I want to set only the max-width, not the fixed width. A fixed width can't self-adapt to the content's word count. Besides, I also hope to vertical align it in the middle and horizontal align it to the center.
But even when I set 100% to max-width attribute, its max-width still is not the width of window, though it contains many words.
WHY?
Ignore my poor English.
#r-u-ok {
position: fixed;
/* display: none; */
max-width: 70%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
z-index: 99;
background-color: rgba(0, 0, 0, .8);
color: #fff;
box-sizing: border-box;
padding: 20px;
text-align: center;
border-radius: 10px;
font-size: 16px;
}
<div id="r-u-ok">
I think it should 100% width of this window, if the word more enough.
</div>
Here is an example: fiddle link
I think due to the position fixed, the div cannot grow as it would in normal document flow. To get over this, use an extra div - the outer div to position and the inner div can then grow with it's content:
#r-u-ok {
position: fixed;
width:100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
z-index: 99;
text-align:center;
}
#r-u-ok > div {
display: inline-block;
max-width: 100%;
background-color: rgba(0,0,0,.8);
color: #fff;
box-sizing: border-box;
padding: 20px;
text-align: center;
border-radius: 10px;
font-size: 16px;
}
<div id="r-u-ok">
<div>
I think it should 100% width of this window, if the word more enough.
</div>
</div>
Updated Fiddle
The problem is that with the left:50%, the system thinks you want to restrict the width to half of the window, even though you translate the whole thing by -50%.
So what you need to do is set the width explicitly. There is no other way. Otherwise you'd be stuck with this half.
Fortunately, width: 100% is not the only solution. What you can do is width: max-content, which does exactly what you need.
Unfortunately, it doesn't work in all browsers. IE and Edge will not comply. But most others will, if you provide the right prefixes.
#r-u-ok {
position: fixed;
/* display: none; */
max-width: 99%; /* changed */
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
z-index: 99;
background-color: rgba(0, 0, 0, .8);
color: #fff;
box-sizing: border-box;
padding: 20px;
text-align: center;
border-radius: 10px;
font-size: 16px;
/* added */
width:-webkit-max-content;
width:-moz-max-content;
width:max-content;
}
<div id="r-u-ok">
I think it should 100% width of this window, if the word more enough.
</div>
Just add width:100%
#r-u-ok {
position: fixed;
/* display: none; */
width: 100%;
max-width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
z-index: 99;
background-color: rgba(0, 0, 0, .8);
color: #fff;
box-sizing: border-box;
padding: 20px;
text-align: center;
border-radius: 10px;
font-size: 16px;
}
i have a demand, the element, which id is "r-u-ok",is a pop, has a several possibility of content's word count.it's judge by a ajax request's callback data. and i want the element only has a max-width, not a fixed width.a fixed width can't self-adaption
the content's word count, besides i also hope it is vertical align middle and horizontal align center. but, even i set 100% to max-width attribute, it's max-width still not the width of window, though it's contain many word. WHY?
<div id="r-u-ok">
I think it should 100% width of this window, if the word more enough.
</div>
I assume you want to display this div in full width. In order to do that:
Remove
max-width: 70%;
Add
width: 100%;
OR
width: 100vw;
I have the following jsfiddle:
https://jsfiddle.net/quacu0hv/
I cant figure out how to center this div. The fact that it is rotated makes it hard to actually center the object on screen. How exactly can this be achieved with pure css? I imagine its due to the point of origin that changed its position (upper left vertex of the div).
div {
transform: rotate(-45deg) scale(2) translate(-50%, -50%);
opacity: 1 !important;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
background: black;
position: absolute;
}
Try rearranging the transform values and see what happens ;)
Turns out order does matter. If you think about it, it does makes sense:
Rotate > Scale > Translate
Once you've rotated it, the origin has been rotated too. That's why your square moves "left" and "up" from the origin.
Translate > Rotate > Scale
This is what you want to do. Position before you make any other adjustments that can affect the origin.
Use CSS transform-origin: 50% 50% or try 0 0. Remove position: absolute first.
This is at 0 0
This is at 50% 50%
This is at 45% -290% Centered?
Yeah, looks centered to me, see Full Page. Anyways, as you can see from the other answers transform-origin is the best solution. Scott suggested to remove the transform: -50% -50% which makes perfect sense if you wanted the div centered in the first place, but if you wanted that in there still and have it centered as a square in a rectangle (height is smaller than width), then 45% by -290%.
SNIPPET
.box {
position: relative;
}
.center {
transform: rotate(-45deg) scale(2) translate(-50%, -50%);
transform-origin: 45% -290%;
opacity: 1 !important;
width: 200px;
height: 200px;
background: black;
position: absolute;
}
<div class='box'>
<div class='center'></div>
</div>
You could just remove translate(50%, 50%);
div {
transform: rotate(-45deg) scale(2);
opacity: 1 !important;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
background: black;
position: absolute;
}
<div></div>
Fiddle
or add transform-origin: 0 0; to start transformations in the upper left corner.
div {
transform: rotate(-45deg) scale(2) translate(-50%, -50%);
transform-origin: 0 0;
opacity: 1 !important;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
background: black;
position: absolute;
}
<div></div>
Fiddle
Using transform-origin you can get the result, also scale and rotate goes before positioning.
div {
transform-origin: 0 0;
transform: rotate(-45deg) scale(2) translate(-50%, 50%);
opacity: 1 !important;
width: 100px;
height: 100px;
background: black;
}
<div></div>
jsfiddle: https://jsfiddle.net/quacu0hv/8/