What does top: 50%; actually do on relatively positioned elements? [closed] - html

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I've been using relatively positioned elements to center things vertically for a while. I never understood, though, why position: relative; top: 50%; doesn't vertically center the element, or at least center the top edge of the element in it's container div.
position: relative according to MDN:
lays out all elements as though the element were not positioned, and then adjusts the element's position, without changing layout
The top keyword:
specifies the amount the element is moved below its normal position.
And a % value on the top keyword:
Is a percentage of the containing block's height
So a relatively positioned element with a value of top: 50% should be moved 50% of the containing blocks height downward, right? Doesn't this mean that the top edge of that element is exactly in the middle of the containing element?
Consider this snippet:
.container {
overflow: hidden;
width: 90%;
height: 90%;
margin: 0 auto;
background-color: #eee;
}
.child {
width: 40%;
height: 40%;
margin: 0 auto;
background-color: #444;
border-top: 5px solid #f00;
}
.top-50-percent {
position: relative;
top: 50%;
}
.contract-and-expand {
animation-name: contract-and-expand;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
#keyframes contract-and-expand {
50% {
height: 0%;
}
}
<html>
<head>
<style>
/* Just initial/basic CSS rules here to make this look better */
#import url("https://necolas.github.io/normalize.css/latest/normalize.css");
* {
box-sizing: border-box;
margin: 0;
}
html, body {
height: 100%;
}
body {
color: #aaa;
}
.center-vertically {
position: relative;
top: 50%;
transform: translateY( -50% );
}
p {
position: absolute; /* Remove paragraphs from flow so they don't interfere */
}
</style>
</head>
<body>
<div class="container center-vertically contract-and-expand">
<p>Container Wrapper</p> <!-- Paragraphs are removed from the flow -->
<div class="child top-50-percent">
</div>
</div>
</body>
</html>
From the snippet it looks like the top edge is centered. Is this always correct? there's this similar fiddle: https://jsfiddle.net/9kyjt8ze/5/ when the height of the viewport is pulled up the top border of the child element no longer looks centered.

I measured this with Inkscape and 2 ( yellow ) vertical blocks the same exact size. It's an optical illusion. The top edge never actually gets off center in that fiddle. Also all of my assumptions appear correct: top:50% on relatively positioned elements moves the top border of that element down 50% of the container's height. The reason this doesn't perfectly vertically center the element is the top edge is the pivot point when using top: 50% on relatively positioned elements.

Related

Container transformed to fit, positioned absolute, still causing overflow as if not transformed

Edit: I had forgot to mention that I also had it positioned absolute. Absolutely sorry for that. Edits in content are in bold.
I have this container that I use for scaling its contents. I needed to scale things down evenly, and realized that I could use transform CSS attribute for my convenience.
The result is good, the contents are scaled and placed nicely. The problem is, I get overflow on the body element, caused by the container element. It is not crossing the window borders, not when its transformed, and is positioned absolute. However, for some reason, my browser (Edge 16) decides to accommodate space for the element as if it was not transformed.
.container {
position: absolute;
width: 10000px; height: 10000px;
border: solid 100px red;
transform-origin: top left;
transform: scale(0.01);
}
.orange-box {
width: 5000px; height: 2000px;
background-color: orange;
}
<div class='container'>
<div class='orange-box'>
</div>
I have tried it a couple of times on Chrome 64, I don't get overflows on body there. I do want to make use of this, though, and I want to have Edge support.
Is there a way to get around of this bug/issue? Is there, perhaps, a way to prevent specific elements from causing overflow, without completely hiding them? I don't want to overflow: none on the body, either, since the body might legitimately be overflowing.
I don't think it's a bug in Edge. At least, I see scrollbars in Chrome.
May be you can get around it placing the div far to the left and top (that don't stretch the body boundaries)
.container {
width: 10000px;
height: 10000px;
border: solid 100px red;
transform: scale(0.01);
top: -10095px;
position: absolute;
left: -10095px;
transform-origin: right bottom;
}
.orange-box {
width: 5000px; height: 2000px;
background-color: orange;
}
<div class='container'>
<div class='orange-box'>
</div>
I encapsulated it all inside another container, positioned it as relative, transformed it with translate(0). Transformation does nothing, but it is different than none, which is all I need to have a child positioned as fixed to respect its container's position: See MDN/position/fixed
Then, I have changed the positioning of our former container to fixed, which did what the absolute couldn't do on Edge 16, and removed the container from the document flow.
.container-container {
position: relative;
top: 50px;
transform: translate(0);
}
.container {
position: fixed;
width: 10000px; height: 10000px;
border: solid 100px red;
transform-origin: top left;
transform: scale(0.01);
}
.orange-box {
width: 5000px; height: 2000px;
background-color: orange;
}
<div class='container-container'>
<div class='container'>
<div class='orange-box'>
</div>
</div>
I positioned the container-container away from the top left, to show that the fixed child moves along with it, thanks to the translate(0) transform.
However, I didn't use this. I instead styled the container-container to have its overflow as hidden via CSS, and left everything as before. This works out only if the container-container has width and height set to be contained within the body, which was already the case in my application.

how to make a div stay in a div

I'm making a pong clone using HTML/CSS/Js. I've set a div element to act as a border for the game, just to keep things in a confined space. How do I get elements (for example, a scoreboard) to act relative to their parent element? For example, if I tell the child to move 50% left, it moves to the center of the parent-div, and NOT to the center of the web-page. Basically I want the child confined by the dimensions of their parent (haha). It seems like
child-div {
position:relative;
}
in CSS would do the trick, but it's not...maybe it's because I'm developing in CodeAcademy's IDE?
position:relative means relative to itself not parents/children etc. It seems likely that you want relative on the parent and possibly absolute on the children. Without code, it's hard to help much further
Here's a quick demo for you.
.container {
width: 80%;
height: 250px;
margin: 0 auto;
position: relative;
border: 4px solid green;
}
.scoreboard {
width: 200px;
height: 50px;
background: lightblue;
border: 2px solid grey;
position: absolute;
top: 10px;
/* just for a bit of space */
left: 50%;
/*almost centered*/
margin-left: -100px;
/* half of known width */
}
<div class="container">
<div class="scoreboard"></div>
</div>
Note...there are other centering methods for absolutely positioned divs depending on whether the width is known and browser support requirements
left: 50%; does not center an element...it moves the element's top/left corner to the center of the containing element. You have to move it back half of it's width (if known)...see above.
One final point....positioned elements are not constrained to their ancestor elements but rather positioned in relation to them. It's quite common to have positioned elements outside the bounds of parents.

CSS - create two columns [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a problem with my school project. I want to make two columns on my page using css, but nothing is working...
Website : http://kitlab.pef.czu.cz/~wbdinfo141528/
CSS : http://kitlab.pef.czu.cz/~wbdinfo141528/css/style.css
I hope that there is some dumb mistake, but I can't figure out, where the problem is.
I want to place the right column next to the left one :
Your margin was taking up the entire row, that's why the second div was pushed down. You don't need margin, just set the width and display it as an inline-block. The inline-block means it'll still be a block, but will wrap like text - so if there's enough space for the second div to be in the same row as the first, it can be.
Replace CSS with this, comments for what was changed.
div.leva {
background: blueviolet;
/* float: left; */
/* margin: 5px 500px auto auto; */
width: 49%;
display: inline-block;
}
div.prava {
background: yellow;
/* float: left; */
/* margin: 5px auto auto 500px; */
display: inline-block;
width: 49%;
}
Alternatively, you can use a relative container div and set that to 100%, and have two absolute divs inside the container with 50% width.
HTML
<div class="container">
<div class="leftdiv"></div>
<div class="rightdiv"></div>
</div>
CSS
.container {
position: relative;
width: 100%;
}
.leftdiv, .rightdiv {
position: absolute;
width: 50%;
top: 0;
}
.leftdiv {
left: 0;
}
.rightdiv {
right: 0;
}
You must add margin:0 in div leva et prava http://jsfiddle.net/rvp5js2w/
At first glance your floats are incorrect.
The purple is floated right while the yellow is floated left.
Set a width (where width is less then total width of stranka/2) for each of these div's and then float them correctly and it should line up.

Don't resize div to a contained image [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to createa a div, who has some links, and a logo image. The thing is that I don't want that the div to resize to the image size. I want that the image ovelap the div. I want something like the image. But when I add the image inside the div, the div size is increased to contain the image.
What you are saying is that you want to remove the image from normal flow. There are several ways to do that:
Float
img {
float: left;
margin: <position it with this>;
}
Floating is handy because it will remove the element from normal flow, while still giving you the option of clearing the float. It will also push the float: right navigation away when near. The only downside is that it's not as powerful as absolute.
Absolute
#nav {
position: relative; /* child positioned in relation to the first element with non-static position */
}
img {
position: absolute;
z-index: 1;
left: <position it with this>;
top: <position it with this>;
}
Absolute completely removes the element from flow, so it won't interfere with anything, including the right navigation (this could be a downside). You can position it accurately with left and top.
Negative Margin
img {
margin-bottom: <some negative number>;
}
This will pull the bottom of the container up, making it look like it's out of normal flow, without the consequences of that. I personally prefer this solution. It will work as long as you can calculate the correct margin-bottom for it to look right.
Plain, fixed height
#nav {
height: <some height>;
}
The simplest solution: just give your navigation a set height.
You can use absolute positioning:
HTML:
<div class="main">
<div class="image">Image Div</div>
</div>
CSS:
.main {
border: 1px solid green;
width: 50%;
height: 50px;
}
.image {
position: absolute;
top: 20px;
left: 20px;
width: 100px;
height: 100px;
border: 1px solid blue;
}
You can try it here.

Transformed body fixed-position div aligning to body, not window

I have created a <div> fixed, set the following styles on it:
#mydiv {
position: fixed;
left: -150px;
width: 150px;
top: 0;
bottom: 0;
border: 1px solid #f00;
}
This produces a <div> that is offscreen, and presumably the same height as the window.
Then I apply the following styles to the <body>:
body {
-webkit-transform: translate(150px, 0);
}
To my knowledge, this should move the body 150px to the right, thereby moving #mydiv into view. This works, but now #mydiv is the height of the body, not the height of the window.
Here's a JSFiddle example
Is this a Webkit bug? Or is this something I'm doing wrong?
EDIT:
This appears to happen on Firefox as well.
The solution to this problem, while perhaps not immediately intuitive, is pretty straightforward.
html, body {
height: 100%;
}
Normally position: fixed elements are aligned relative to the window (the parent of the html element). When css transforms are applied, however, position: fixed elements are aligned relative to the closest parent with a css transform applied.
The alternate approach Webkit and other browsers could have taken, would be to still align position: fixed elements to the window. But the problem with this would be the position: fixed div would not move at all when the body was transformed, and so the div would still be positioned offscreen.