How to compensate for left,top,bottom, right in CSS - html

I've been looking very hard and I see many examples where people will have left or top or something like that at 50%, and I'd expect that would be sufficient to center anything, but that's not the case.
Sometimes when I put left 50% for something, the div looks as if it's slightly more than that (relative to browser). So then they have negative margins and I'm just wondering how do you know what values to put in order to center the elements, and what property for position would I need to put? I just don't understand why position:relative and left:50% won't make my div go to the center of the page.

When absolute positioning an element using top, right, bottom and left you're moving it a certain distance from that elements edges. It will move it in relation to the last positioned element. The last position element is the next ancestor element that has any type of positioning applied to it via CSS. If no ancestor element as positioning set then the viewport window will be used as a reference.
I created a quick diagram to show what is going on.
left: 50%; moves the element's left edge 50% (half) of the width of the last positioned element's left edge. You're effectively moving elements to the right by adding space between element left edges.
margin-left: <negative value>; is set to half the element's width pulling it back to the left. This fixes the off center issue you're seeing.
Today a lot of people will forgo using margin-left with a negative value and opt for transform: translateX( -50% );. This allows them to be more flexible as the elements width does not need to be known.
The CSS for transform: translateX( -50% ); might look like this:
div {
position: absolute;
left: 50%;
border: 2px dashed red;
width: 200px;
height: 100px;
transform: translateX( -50% );
}
Demo JSFiddle.
If you're looking to simply center something horizontally and you have applied a width (px, %, etc. work) then you can use margin: 0 auto; width: <width value>;. A width must be set for margin: 0 auto; to work!
Example:
div {
margin: 0 auto;
width: 25%;
height: 100px;
border: 2px dashed red;
}
Demo JSFiddle.

Sometimes when I put left 50% for something, the div looks as if it's slightly more than that(relative to browser).
It positions the left edge at the 50% point.
So then they have negative margins and I'm just wondering how do you know what values to put in order to center the elements
Half of whatever the width is
what property for position would I need to put?
That technique generally assumes absolute positioning
I just don't understand why position:relative and left:50% won't make my div go to the center of the page.
Relative positioning offsets the element from its static position. Generally, any time you want to try to centre something with relative positioning you would be better off with setting the left and right margins to auto (and leaving the positioning as static).

That's because it positions the top-left corner at 50%.
You should use the translate:
.centered {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
// this moves the center of centered item to 50%
}

When you apply left: 50% its in fact the left edge of your element which is centered. Not the middle of your element.
apply margin:auto; to your element to center it.

Related

How does position: absolute - left/right work with transform: translateX/translateY?

.dice#dice1 {
position: absolute;
top: 20%;
left: 45%;
transform: translateX(-55%);
}
.dice#dice2 {
position: absolute;
top: 20%;
right: 45%;
transform: translateX(55%);
border: 1px solid blue;
}
The above code is resulting in the following:
Although I'm using this code I'm a little bit confused as to how the absolute left and right work with translate...
Can anyone please help me understand this?
The part that I suspect is throwing you is that the transformX percentage is the percentage of the width of the positioned element itself, whereas the top/left are percentages of the parent positioning context element.
.dice#dice1 {
position: absolute;
top: 20%;
left: 45%;
transform: translateX(-55%);
}
Consider this case when:
the containing element is 100px high and 100px wide, and
the element being positioned is 10px high and 10px wide
The element is positioned with its top at 20px, its left at 45px, because that's 20% and 45% of the parent, respectively.
The transformX then moves the element left 5.5px, which is 55% of 10px, the element's own width.
When using percentage, left/right/up/down position an element relative to the container and transform: translate() positions an element relative to its own dimensions.
So, left: 50% is half way across the container and transform: translateX(50%) is half of the elements width.
When an element is position: absolute, the body becomes the container, unless you add position: relative to the parent.
From your code it can be inferred that first you are absolutely positioning the two div, here dice1 and dice2, such that it's 20% from the top and 45% from the right.
Next after positioning the two div at the same place, you are translating 55% from the current position, one along the positive x direction and the other along the negetive x direction.

position: absolute not doing what I expect

I am having problems getting the grasp of position: absolute
I understand that it positions itself according to the position of its relative parent. So what is wrong with my example? when clicking on the first ".col-lg-6", why is the faded blue line not centered on the right col?
Please could you rework the code and explain why this is happening?
.formWrapper
{
background: blue;
height: 100vh;
position: relative;
margin: 0;
}
.formWrapper .contactForm
{
width: 750px;
height: 400px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: yellow;
}
<div class="formWrapper">
<div class="contactForm row">
<div class="col-lg-6"><h1>HI</h1></div>
<div class="col-lg-6"><h1>HI</h1></div>
</div>
</div>
I can't rework the code and give you what you want exactly, because I don't see the faded blue line you're talking about. But, I will explain what is going on with your code, as I see it.
HTML Markup
<div class="formWrapper">
<div class="contactForm row">
<div class="col-lg-6"><h1>HI</h1></div>
<div class="col-lg-6"><h1>HI</h1></div>
</div>
</div>
.formWrapper
{
background: blue;
height: 100vh;
position: relative;
margin: 0;
}
You have a .formWrapper div colored blue. It takes up the full screen, and you've positioned it relative. Positioning it relative provides an anchor for its child element to use when defining its own position as absolute (necessary).
.formWrapper .contactForm
{
width: 750px;
height: 400px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: yellow;
}
You've defined the a fixed width and height of the yellow .contactForm div and colored it yellow.
By defining position: absolute, with top:50% and left:50%, the top left position of the .contactForm div would appear in the very middle of the .formWrapper div. However, you've also added the transform: translate(-50%, -50%) style, which moves the .contactForm div to the left 50% of its own width and up 50% of its own height.
Important
The position: absolute style that you've set in the parent of the div.col-lg-6 elements does not affect the children's positioning within that element. Position absolute only directly affects the actual element to which you've applied this style, changing its position in reference to its own parent, or the closest parent that has a position style defined.
Position Fixed
If your goal is to have a pop up that sits in the center of the screen, then you might want to use position: fixed, which positions the element relative to the window. This way you don't have to worry about the effects of other elements.
You could position the popup in the middle of the view the same way you positioned the .contactForm div in the middle of the its parent div.
Bootstrap
If you are using bootstrap or any other css framework, you may want to consult their documentation on how to accomplish your goals. Frequently, when using a css framework, adding your own custom styles that affect the sizes and positioning of elements can have consequences that are difficult to manage.
By setting a position of absolute or fixed, you might break the expected flow of the rest of the css. So, only do it when there is no standard way of doing what you need and you know the consequences.

What's the reason for transform: translate when centering an element in CSS?

I want to learn to work with percentages in CSS instead of exact units, which led me to this centering technique:
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
I know that with absolute positioned elements, the top, bottom, right, and left properties set space between an element and the edge of its ancestor or father if there's one. In the technique they put the element 50% below and 50% to the left which is logical if the intention is to center horizontally and vertically the element, but why include the transform property that is used to rotate, scale, and move elements with negative values?
Here's my code:
.container {
height: 700px;
display: block;
width: 100%;
height: 700px;
text-align: center;
overflow: hidden;
}
.container img{
background-size: cover;
}
.container > h1 {
font-size: 72px;
position: absolute;
color: white;
width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
<div class="container">
<h1>Enjoy This Magical Experience</h1>
<img src="https://static.tumblr.com/737181aea20b4523b6fce168a29fe06b/nwsqmvx/cIhmrn4un/tumblr_static_bigstock_silhouettes_of_concert_crowd_i_1565261621.jpg"/>
</div>
top/left
top moves top border of your element x units from top border of container (or element we are placing out element relative to).
left moves left border of your element x units from left border of container (or element we are placing out element relative to).
Percentage in both of them is calculated from container.
Basically top: 50%; left: 50% puts your element's top-left corner in the center of container.
translate
translate(X/Y) moves your element by x units from it's current position.
In this case percentage is calculated from the element itself.
translate(-50%, -50%) moves your element by half of its width and half of its height back (root 0,0 point is in top-left corner and numbers are increasing into visible area).

Advanced CSS - Don't Understand This Solution

I've successfully gotten a video to properly fit inside a div and fill it completely all the time thanks to this SO answer.
I've modified the code just a bit but I'm stumped as to why this code works.
video
position: absolute
opacity: 0.1
z-index: 0
top: 0px
left: 50%
min-width: 100%
min-height: 100%
right: 0px
margin: auto
width: auto
height: auto
overflow-x: hidden
transform: translateX(-50%)
I don't get what the transform does and how to get it to fix to something other than the top-left corner. I think there's something about the min- properties that makes this work but I'm not sure.
An absolutely positioned element's position in relation to its parent element (which can also be the browser window) is defined by the top or bottom and left or right parameters (default is top: 0; left: 0;). If left is 50%, it means the left border is moved exactly to the horizontal middle of the container. transform: translateX(-50%) moves it back to the left (caused by the minus value) by 50%, but this time by 50% of the element itself. This causes the element to be ecactly centered horizontally. overflow-x: hidden; makes sure the element doesn't overlap its container - overflowing parts will remain invisible.
You could do the same vertically with top 50%; transform: translateY(-50%); overflow-Y: hidden;

How to make vertically responsive element based on the height of window?

I have input with set height and width of it in the center of the site (imagine Google) and need its position to be vertically responsive based on the height of the browser window. I was looking for a solution, but couldn't find it.
input {
max-height:4em;
max-width: 25em;
outline: none;
}
One way is to use CSS3 translateY like this..
input {
max-height:4em;
max-width: 25em;
margin:0 auto;
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
http://codeply.com/go/94MsX6EnaO
Make the element position:absolute with a top:50%
Set a height, and a minus margin-top which should be 50% of the height.
How?
The top:50% will push the element top to 50%. But since you want the middle of the element to be in the middle and not the top, you use a negative margin-top to pull the element up the half of it's height.
HTML
<div>
MIDDLE ME
</div>
CSS
div {
height:30px;
top:50%;
position:absolute;
margin-top:-15px;
}
Example:
http://jsfiddle.net/bpa6qgu6/
More detailed: http://jsfiddle.net/bpa6qgu6/1/
Another solution is using jQuery's innerHeight() to set the margin-top;