Absolute position does not work on elements with % width - html

I have a div that has width set to 50%, and a border-radius of 50% in order to make it a circle. Inside there are 3 other divs that serve as buttons, and a fourth div, that serves the purpose of making it as tall as it is wide.
Now I want to position my buttons relative to the div .appContainer. Basically what I'm trying to achieve is that one button is always at the top center of the div, and the other two are at the bottom right and left corners.
Now something strange happens to my buttons - instead of positioning according to the parent element, when the parent div is smaller than the page, they are always positioned at the bottom of the screen.
Any ideas on how to achieve what I want to are appreciated.
If anything is unclear please let me know and I'll edit the main post.
body {
background-color: gray;
margin: 0;
padding: 0;
}
.appContainer {
width: 50%;
margin: 0 25%;
background-color: white;
border-radius: 50%;
}
.heightElement {
height: 0;
padding-bottom: 100%;
}
#button1, #button2, #button3 {
position: absolute;
background-color: red;
padding: 1em;
border-radius: 50%;
}
#button1 {
right: 50%;
top: 0%;
}
#button2 {
right: 25%;
top: 100%;
}
#button3 {
right: 75%;
top: 100%;
}
<div class="appContainer">
<div class="heightElement"></div>
<div id="button1">Button 1</div>
<div id="button2">Button 2</div>
<div id="button3">Button 3</div>
</div>

Your .appContainer might need a position: relative style rule.
.appContainer {
position: relative; // Try adding this line.
width: 50%;
margin: 0 25%;
background-color: white;
border-radius: 50%;
}
What this now means, is that anything within this item that is positioned absolutely, will be positioned relatively to its parent.
Here's a working demo for you: https://jsfiddle.net/usgp8ume/

Related

Why can't I set the margin of this wrapper?

I have a problem that I can't figure out despite an hour of YouTube videos and looking on here. I have 4 divs inside of a wrapper. I would like the wrapper to have a top margin of 27px, and a left margin of 2%. For the bottom and right sides, I would like it to automatically expand to the edge of the screen. (Viewport) What am I doing wrong here?
My code is below, and I have a fiddle at
However, the wrapper seems to do nothing and the div content starts at the edge of the screen no matter what I put in the CSS.
.wrapper {
margin: 27px auto auto 2%; // Does nothing
position:absolute;
}
#square1 { position:absolute; top:50%; width:50%;height:50%;left:0;background-color:blue}
#square2 { position:absolute; top:50%; width:50%;height:50%;left:50%;background-color:yellow}
#square3 { position:absolute; top:0; width:50%;height:50%;left:0;background-color:green}
#square4 { position:absolute; top:0; width:50%;height:50%;left:50%;background-color:red}
<div id="wrapper">
<div id='square1'></div>
<div id='square2'></div>
<div id='square3'></div>
<div id='square4'></div>
</div>
To select an element with id (wrapper in your code) you need to use '#' instead of '.'.
If you want to position something absolute, you need to position it direct/indirect parent relative, to let the browser know relative to which element place that absolutely positioned.
Also auto margins on right and left would center element (element is in the center if space from right and left are equal), but to span the element across you need to specify it's width. Keep in mind that margin in percents would be calculated from parent sizes.
Moreover if you have only absolutely position content inside element (wrapper) it would have zero height and you need to specify it explicitly.
As a side note, try to avoid repeting yourself. All squares have same properties, so combine it to new selector (square).
#wrapper {
position: relative;
width: 100%;
height: 100vh;
margin-top: 27px;
margin-left: 2%;
}
.square {
position: absolute;
width: 50%;
height: 50%;
}
#square1 {
top: 50%;
left: 0;
background-color: blue;
}
#square2 {
top: 50%;
left: 50%;
background-color: yellow;
}
#square3 {
top: 0;
left: 0;
background-color: green;
}
#square4 {
top: 0;
left: 50%;
background-color: red;
}
<div id="wrapper">
<div id='square1' class="square"></div>
<div id='square2' class="square"></div>
<div id='square3' class="square"></div>
<div id='square4' class="square"></div>
</div>
selector is incorrect, should be id or class
made wrapper relative so child can be absolute otherwise they will stack to window not parent div
made parent div 100% height and width
There is no point of giving auto margin to right and bottom
CSS comment should be /* */
#wrapper {
margin: 27px auto auto 2%;
position:relative;
width:100%;
height:100vh;
}
#square1 {
position: absolute;
top: 50%;
width: 50%;
height: 50%;
left: 0;
background-color: blue
}
#square2 {
position: absolute;
top: 50%;
width: 50%;
height: 50%;
left: 50%;
background-color: yellow
}
#square3 {
position: absolute;
top: 0;
width: 50%;
height: 50%;
left: 0;
background-color: green
}
#square4 {
position: absolute;
top: 0;
width: 50%;
height: 50%;
left: 50%;
background-color: red
}
<div id="wrapper">
<div id='square1'></div>
<div id='square2'></div>
<div id='square3'></div>
<div id='square4'></div>
</div>
your wrapper is not class, it is id. Thats why you should use #wrapper. And it actually works:
just because of position: absolute you don't see the result, because position: absolute works so, it's mean you are using it in wrong way. Read about position. The same result we can get with code below, or with flexs or grids.
#wrapper {
margin: 27px auto auto 2%;
height: 100vh;
}
.square {
width: 49.5%;
height: 50%;
display: inline-block;
}
#square1 {
background-color: blue;
}
#square2 {
background-color: yellow;
}
#square3 {
background-color: green;
}
#square4 {
background-color: red;
}
<div id="wrapper">
<div id='square1' class="square"></div>
<div id='square2' class="square"></div>
<div id='square3' class="square"></div>
<div id='square4' class="square"></div>
</div>

How to make a <div>'s bottom edge below background image

I have a background image, but I need to place a div that its bottom edge should go below the image. What's the easiest way to do this?
Please see the attached image. The white part is the background image and the blue part is my div over the background.
You can create a relative positioned wrapper and then set absolute positioning with bottom: -10%; or bottom: -20px; for a div over a div with image:
.image-with-block-wrapper {
position: relative;
}
.image {
height: 200px;
border: 1px solid #111;
background: url('https://www.gravatar.com/avatar/f42a832da648291bf80206eda08e3332?s=328&d=identicon&r=PG&f=1');
}
.div-over-bg {
border: 1px solid #111;
position: absolute;
height: 50px;
bottom: -10%;
left: 50%;
transform: translateX(-50%);
background: green;
width: 100px;
margin: 0 auto;
}
<html>
<head></head>
<body>
<div class='image-with-block-wrapper'>
<div class='image'></div>
<div class='div-over-bg'></div>
</div>
</body>
</html>
Edit:
In the case of using percents for bottom it will be related with the wrapper height, but you can use bottom: 0;
and transform: translate(-50%, 15%); in order to set the upper block vertical position as relative to the block itself.
So I've created a container with a background image and placed a div inside.
I've given the .block margin: auto; to center it and added position: relative; so I can move it, because it has position: relative; I can add top: 100px; to move it down from the top by 100px
.container {
background-image: url('https://via.placeholder.com/150');
width: 100%;
background-position: cover;
height: 300px;
position: relative;
}
.container .block {
height: 300px;
background-color: blue;
width: 500px;
position: relative;
margin: auto;
top: 100px;
}
<div class="container">
<div class="block">
</div>
</div>
Extra info by #I_Can_Help
In the case of using percents for bottom it will be related with the wrapper height, but you can use bottom: 0;
and transform: translate(-50%, 15%); in order to set the upper block vertical position as relative to the block itself.

How do I center a div ontop of another div that has inline block

I'm trying to center a text div on top of box div that has inline block. I tried using position: absolute on the text div. But when the browser screen is shrunk or expanded, the positioning of the text div gets messed up. How to fix this?
.mainDiv {
margin: auto;
width: 100%;
padding: 10px;
left: 300px;
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
}
.text {
background-color: blue;
position: absolute;
top: 70%;
left: 45%;
}
<div class="mainDiv">
<div class="box"></div>
<div class="text">text</div>
</div>
I assume you are using inline-block to center the .box inside the .main-div. Technically, with your current html structure you can't center the .text element on the .box one, but you can center it on .main-div, which is essentially the same thing in your example.
I would start by adding position: relative to .main-div. An absolutely positioned element is positioned based on it's nearest ancestor that has a positioning context. The easiest way to set this is to add position: relative.
Then with your .text element you can adjust to:
.text {
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50% );
}
This works because top and left position the top and left element from the top and left of its parent. So the top of .text would start 50% of the way down .main-div, and likewise with left. This would leave your text too far down and to the left.
transform: translate values work differently - they are based on the size of the element itself. So -50% will move an element back half of its width or height. By setting it on both width and height we are moving the .text so that instead of its top and left edges being at 50%, it's center is at 50%.
.mainDiv {
position: relative; /* added to make .text align relative to this, not the document */
margin: auto;
width: 100%;
padding: 10px;
/* left: 300px; (I removed this for demo purposes, but if you need it you can add it back in) */
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
}
.text {
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50% ); /*pull the text left and up 50% of the text's size*/
}
<div class="mainDiv">
<div class="box"></div>
<div class="text">text</div>
</div>
The markup for text should be written first then the box. Then you may try using block instead of inline-block, then set the width of the text to 100 percent, display block and 'margin: 0 auto'. Also, maybe consider using the appropriate semantic tags as opposed to divs if you can. Also, I suspect the top and left rules to be causing the text to not align properly. You should no longer need position:absolute either.
If you want, you can make the blue div a child of the red div so that the blue div will always be relative to the red div. I also added position:relative to the red div, and used transform:translate to the blue div.
If I'm not mistaken, this is also responsive, so try shrinking your browser.
.mainDiv {
margin: auto;
width: 100%;
padding: 10px;
left: 300px;
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
position:relative;
}
.text {
background-color: blue;
position: absolute;
left: 50%;
transform:translate(-50%, -100%);
}
<div class="mainDiv">
<div class="box">
<div class="text">text</div>
</div>
</div>
.mainDiv {
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
margin-top: 19px;
}
.text {
background-color: blue;
position: absolute;
margin: -19px 0 0 36px;
}
<div class="mainDiv">
<div class="box">
<div class="text">text</div>
</div>
</div>

Div leak parent container max width

I need to make a child div leak the parent container max width.
Now, i can only leak parent padding (knowing it).
I need this to wrap all the page on a container and make some sections leak.
Without this, i will need to set the container on every section.
Here is some snippets
Better snippet on codepen
.container {
max-width: 500px;
margin: 0 auto;
padding: 0 30px;
background: lightblue;
}
.child {
background: lightcoral;
height: 200px;
}
.child.cancel-padding {
margin: 0 -30px;
}
.child.leaked {
}
html,
body {
margin: 0;
padding: 0;
}
* {
text-align: center;
font-family: sans-serif;
}
<small>note: see in fullscreen or on codepen</small>
<h1>what i have</h1>
<div class="container">
<div class="child">A element inside a container</div>
</div>
<h1>what i need</h1>
<div class="container-leaked">
<div class="child leaked">
a element inside the container, but leaking all view width (100vw)
</div>
</div>
<h1>what i can do now</h1>
<div class="container">
<div class="child cancel-padding">Make the element cancel the parent padding, that's all</div>
</div>
<h1>Why i need</h1>
<p>
i will wrap all the page in the container, but sometimes i need sections to leak the container with full view width.
</p>
Note: on the demo, i've set the child height, but i will not have control of it. it's a dynamic content div, so height is dynamic.
You can do it by using relative positioning. Indeed, you need position: relative on your container and your child -leak. Then, to center your child, you use
left: 50%;
transform: translateX(-50%);
This works because your container is centered. So left: 50% will move the child left edge to 50% of its parent width from its initial position (which mean the center of its parent). Then, transform: translateX(-50%) will move the left edge of your child 50% of its width on the left. You then just need to add width: 100vw to make your child full width. Here is the snippet:
.page {
position: relative;
}
.container {
max-width: 100px;
margin: 0 auto;
padding: 0 30px;
background: lightblue;
position: relative;
}
.child-leak {
height: 200px;
background: lightcoral;
position: relative;
left: 50%;
transform: translateX(-50%);
padding: 10px;
width: 100vw;
}
html, body{
margin: 0;
padding: 0;
text-align: center;
font-family: sans-serif;
}
<div class="page">
<h1>My title</h1>
<div class="container">
<div class="child-leak">
My full width child
</div>
</div>
<div>Below content</div>
</div>
This technique for horizontally center an element works also for vertical centering. This works because a value in % for top, left, right and bottom refers to the first non static parent width and height. On the other hand, translate with a value in % use the element width and height.
This may be a little bit of a hack, but I've done it before by adding ::before and ::after. Add position: relative to the .child and then add the following css
.child.leaked:before{
content:"";
display: block;
position: absolute;
height: 100%;
width: 100%;
left: -100%;
background-color: red;
top: 0;
}
.child.leaked:after{
content:"";
display: block;
position: absolute;
height: 100%;
width: 100%;
right: -100%;
background-color: red;
top: 0;
}
Here is an approach you can try:
.container {
max-width: 500px;
margin: 0 auto;
padding: 0 30px;
background: lightblue;
}
.child {
background: lightcoral;
height: 200px;
width: 400%;
margin-left: -150%; /* (width of child - 100) / 2 */
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden; /* prevent horizontal scroll bar */
}
* {
text-align: center;
font-family: sans-serif;
}
<div class="container">
<div class="child">I am outside the parent</div>
</div>

JQuery Mobile Button - Absolute position FROM center?

I'm trying to create something in JQuery Mobile, however I need to be able to position a button from the center. Right now, the button is positioned from the top-left corner, and as such if I resize the window, everything is horribly off-center.
<body>
<button>Button</button>
<div />
</body>
div {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
button {
position: absolute;
top: 200px;
left: 200px;
}
Fiddle: http://jsfiddle.net/chpt3x1v/4/
I couldn't get JQM working in JSFiddle (didn't know how without it showing loads of errors), so I just used a regular button, but the same premise applies.
TWO IMAGES:
As you can see, it is completely off-center.
UPDATED ANSWER:
You need to give the button a set width and height, and then set the top margin to negative one half the height, and the left margin to negative half the width:
Updated DEMO
<div class="thediv"></div>
<button data-role="none" class="theButton">Button</button>
.thediv {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
.theButton {
position: fixed; /* or absolute */
top: 200px;
left: 200px;
width: 80px;
height: 80px;
margin-top: -40px;
margin-left: -40px;
}
ORIGINAL ANSWER:
You can use fixed positioning and a negative margin to keep it centered:
<div data-role="page" id="page1">
<div role="main" class="ui-content">
<div class="centered"><button>Button</button></div>
</div>
</div>
.centered {
position: fixed; /* or absolute */
top: 50%;
left: 50%;
background-color: black;
width: 200px;
height: 200px;
margin-top: -100px;
margin-left: -100px;
}
.centered button {
margin: 0 !important;
height: 100%;
}
Updated FIDDLE
Firstly your code doesn't have an opening tag. Secondly, you need to have the parent element, i.e. the div, positioned as relative.
Third, you've positioned your button to the very edge of the div by using the same dimensions. Try:
<body>
<div>
<button>Button</button>
<div />
</body>
div {
position: relative;
width: 200px;
height: 200px;
background-color: black;
}
button {
position: absolute;
top: 50%;
left: 50%;
z-index: 1;
}
The z-index property will allow the button to overlay the div.