How to prevent changing position of items with position absolute when resizing - html

Hi I have a question about my code.
Here is my problem.
I have two items and one frame. Frame has position relative a two items (children) have position absolute. They should be always on the same point inside my frame but when I am resizing the position of children are different in relation with frame. How to make the children always stay on same position for responzive design? Is it possible?
Try to change height of window in example too (not only width)
https://codesandbox.io/s/adoring-jackson-c6fth?file=/index.html:0-900
.frame {
width: 70vh;
height: 90vh;
border: 10px solid red;
margin: 10px auto;
position: relative;
}
.objA {
width: 130%;
position: absolute;
height: 40%;
bottom: -10%;
left: -20;
border: 2px solid green;
background: rgba(10, 101, 10, 0.7);
z-index: 2;
}
.objB {
width: 10%;
position: absolute;
height: 20%;
bottom: 20%;
left: 30%;
background: red;
z-index: 1;
}
<div class="frame"></div>
<div class="objA"></div>
<div class="objB"></div>
I post here my real example image for better imagination what the problem is.
All objects are positioned absolute (Waves, stars, robot etc...) Each wave should in every resized situation be in same position. Good to know is that every wave is separatly.

Make sure the positions and heights/widths are all in percents and most important: place your items inside the main <div class="frame"></div> element. You can start this way:
* {
box-sizing: border-box;
}
body {
background: none #014653;
margin: 0;
}
.frame {
width: 70vw;
height: 90vh;
border: 10px solid #5cb9b8;
background: none #5cb9b8;
margin: 5vh auto;
position: relative;
border-radius: 6px;
}
.frame-stage {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 5px solid #a2cece;
background: none #014653;
border-radius: 5px;
}
.objA {
width: 10%;
position: absolute;
height: 20%;
bottom: 10%;
left: -20;
border: 2px solid green;
background: rgba(10, 101, 10, 0.7);
z-index: 2;
}
.objB {
width: 10%;
position: absolute;
height: 20%;
bottom: 30%;
left: 30%;
background: red;
z-index: 1;
}
<div class="frame">
<div class="frame-stage">
<div class="objA"></div>
<div class="objB"></div>
</div>
</div>
Updated codesandbox here.

Related

Preventing shapes from overflow + positioning?

I'm trying to create a component where there is a hollow circle that is cropped at the bottom-left corner:
I've attempted to do so with the pseudo classes below but am facing two issues after working with it for a while (dimensions of the circle are not the same, but I will address this later):
The circles overflow outside of the component
The positioning of the circles changes depending on where the element is used.
#element {
max-width: 750px;
height: 350px;
border-radius: 8px;
background-color: #008001;
}
#element:before {
content: '';
position: absolute;
width: 100px;
height: 100px;
z-index: 1;
background: #008001;
border-radius: 50%;
top: 290px;
right: 94%;
}
#element:after {
content: '';
position: absolute;
width: 150px;
height: 150px;
background: #fff;
opacity: 0.5;
border-radius: 50%;
top: 260px;
right: 92%;
}
<div id="element"></div>
Set overflow:hidden to #element. SO `we can hide overflowing content of ::before CSS. Also set #element to position:relative, which set's boundary for ::before when we try to set it after making it absolute.
Once above =e things are done, just apply #element::before to bottom:-50px and left:-50px, I have used 50px as height and width were set to 100px.
Then to get the border just set border:25px solid #yourolor.
#element {
max-width: 750px;
height: 350px;
border-radius: 8px;
background-color: #008001;
overflow: hidden;
position: relative;
}
#element:before {
content: '';
position: absolute;
width: 100px;
height: 100px;
z-index: 4;
background: #008001;
bottom: -50px;
left: -50px;
border-radius: 100%;
border: 25px solid #c5ffc6;
}
<div id="element"></div>

How to make a div absolute to another absolute div in CSS?

I want the elements inside .bannerinner class to be in the exact middle alignment of the .banner class but it doesn't really work that way. I'm open to any advices, any help would be greatly appreciated, thanks from now.
I have this .banner class "absolute" to my "relative" background
.banner {
background-color: rgba(209, 29, 155, 0.212);
padding: 8px 15px;
overflow: hidden;
height: 10vh;
width: 150vh;
max-height: 10vh;
min-height: 10vh;
position: absolute;
bottom: 9vh;
}
and also inside this .banner class there is a .bannerinner class
.bannerinner {
padding: 0;
margin: 0;
left: 2vh;
position: absolute;
bottom: 50%;
vertical-align: middle;
}
Set .innerbanner to left:50% and top:50%. This puts the upper left corner of .innerbanner to the center of .banner.
Then transform .innerbanner back to -50% of its own width and height. This sets the center of .innerbanner exactly to the center of .banner.
See code example:
div {
box-sizing: border-box;
}
.background {
position: relative;
width: 80%;
height: 400px;
padding: 0.5em;
margin: 0 auto;
background-color: #bbb;
}
.banner {
position: absolute;
width: 80%;
height: 200px;
padding: 8px 15px;
left: 10%;
bottom: 2vh;
overflow: hidden;
background-color: rgba(209, 29, 155, 0.212);
}
.bannerinner {
position: absolute;
left: 50%;
top: 50%;
width: 200px;
transform: translate(-50%, -50%);
text-align: center;
background-color: #fff;
border: 1px solid #000;
}
<div class="background">
<p>Background: relative</p>
<div class="banner">
<p>Banner: absolute </p>
<div class="bannerinner">
<p>Inner Banner: absolute</p>
</div>
</div>
</div>

Positioning of Div in Browser with Absolute scheme

I have 2 Divs both of which are subject to absolute position condition. First Div has top: 200px and second one has top: 400px. However surprisingly, when I see them in Computers with different screen size, their relative positions look quite different. For example, when I see them in Laptop they appear to be closer to each other, whereas when I see then in wide-screen Desktop, they appear to be far.
I wonder, since I have position: absolute for both Divs, shouldn't their relative position be same regardless the screen size I chose?
What I need to do to make them appear in the same position relative to each other regardless the screen size?
CSS details for both Divs
.one {
margin: 0 auto;
padding: 32px 0 0 0;
background-color: rgba(248, 248, 255, 0.15);
height: 140px;
position: absolute;
top: 134px;
width: 100%;
text-align: center;
}
.two {
position: absolute;
margin: auto;
top: 237px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
align-items: center;
}
Thanks for your advice.
The problem is that you're using bottom: 0 for the second div, instead of a height. This means that the bottom of your second div will always be at the bottom of the page, so if you resize it, this div will become taller proportionally to the height of your screen size.
To fix this, I removed the top, left and right positioning and instead applied a height (like in your first div) and a width of 100%.
.one {
position: absolute;
margin: 0 auto;
padding: 32px 0 0 0;
background-color: pink;
height: 140px;
top: 134px;
width: 100%;
text-align: center;
}
.two {
height: 100px;
width: 100%;
position: absolute;
margin: auto;
background-color: steelblue;
top: 237px;
text-align: center;
align-items: center;
}
<div class="one"></div>
<div class="two"></div>
This can be one solution.
*{box-sizing:border-box;}
.one {
position: absolute;
margin: 0 auto;
padding: 32px 0 0 0;
background-color: pink;
height: 140px;
top: 134px;
width: 100%;
text-align: center;
}
.two {
height: 140px;
width: 100%;
position: absolute;
margin: auto;
background-color: steelblue;
top: 274px;
text-align: center;
align-items: center;
}
<div class="one"></div>
<div class="two"></div>
The other solution is to just group them into 1 div, make make that div absolute.
The advantage of this is that u dont have to maintain positioning of 2 divs. Only the parent is enough
* {
box-sizing: border-box;
}
.parent {
position: absolute;
top: 134px;
width:100%;
left:0;
right:0;
}
.one {
margin: 0 auto;
padding: 32px 0 0 0;
background-color: pink;
height: 140px;
width: 100%;
text-align: center;
}
.two {
height: 140px;
width: 100%;
margin: auto;
background-color: steelblue;
text-align: center;
align-items: center;
}
<div class="parent">
<div class="one"></div>
<div class="two"></div>
</div>
In other to make look same regardless of screen size, you have to set the properties say left=0 , right=0 and bottom=0for bottom div and then you could control the height using different top values. Doing this you have make both div behave like a block container with absolute position and their placement will not shift each other like relative.
.one {
margin: 0 auto;
padding: 32px 0 0 0;
background-color: red;
height: 140px;
position: absolute;
top: 134px;
left: 0;
right: 0;
bottom:0;
width: 100%;
text-align: center;
border: 1px solid blue;
}
.two {
position: absolute;
margin: auto;
top: 237px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
align-items: center;
background-color: green;
border: 1px solid blue;
}
<div class="one">
1
</div>
<div class="two">
2
</div>

Make text visible above overlapping div [duplicate]

This question already has answers here:
Html/Css Triangle with pseudo elements
(1 answer)
Speech bubble with arrow
(3 answers)
Closed 4 years ago.
I have a design requirement where a div has to overlap another div, but the text within the inner div needs to be visible.
<div class='box1'>
<div class='sendAbove'>
This is a message I want to be visible in this div
</div>
</div>
<div class='box2'>
</div>
CSS
.box1 {
width: 100px;
height: 100px;
position: absolute;
top: 20px;
left: 20px;
background: white;
border: solid red 1px;
z-index: 3;
}
.box2 {
width: 100px;
height: 100px;
position: absolute;
top: 50px;
left: 50px;
background: white;
border: solid blue 1px;
z-index: 4;
}
.sendAbove {
z-index: 5;
}
https://jsfiddle.net/sriv87/Lcoxrgpw/9/
Edit:
Updated fiddle
https://jsfiddle.net/sriv87/c8eh5fcs/
Ok, Edited as per your updated requirement. Check this.
.callout {
position: relative;
background: #ffffff;
border: 1px solid #f00;
width: 200px;
}
.callout:after,
.callout:before {
position: absolute;
left: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
}
.callout:after {
border-color: rgba(255, 255, 255, 0);
border-left-color: white;
border-width: 10px;
margin-top: -10px;
}
.callout:before {
border-color: rgba(255, 0, 0, 0);
border-left-color: #f00;
border-width: 11px;
margin-top: -11px;
}
<div class="callout">
<p>Message here</p>
</div>
With your current layout it wont work. Because the parent of .sendAbove is absolute positioned, its html will allways be part of its parent. Regardless you make it absolute or relative.
So to make this workable, you should put the .sendAbove outside .box1. Give them both the same position, height and width.
.wrapper {
position: relative;
}
.box1, .sendAbove {
position: absolute;
top: 20px;
left: 20px;
width: 100px;
height: 100px;
}
.box1 {
background: white;
border: solid red 1px;
z-index: 3;
}
.box2 {
width: 100px;
height: 100px;
position: absolute;
top: 50px;
left: 50px;
background: white;
border: solid blue 1px;
z-index: 4;
}
.sendAbove {
z-index: 5;
}
<div class="wrapper">
<div class='box1'>
</div>
<div class='sendAbove'>
This is a message I want to be visible in this div
</div>
<div class='box2'>
</div>
</div>
Just change the background color settings in .box2 and that will make text underneath visible. How visible will be decided by the 'a' in rgba, and runs from 0 to 1, ie, 0.1 is very transparent, 0.9 has virtually no transparency.
.box2 {
width: 100px;
height: 100px;
position: absolute;
top: 50px;
left: 50px;
**background-color: rgba(255,255,255,0);**
border: solid blue 1px;
z-index: 4;
}

How to center child divs along each side of a parent div

I want to center 4 small, square child divs along each edge of a square parent div. My current solution depends on hacked-together absolute positioning. http://jsfiddle.net/Lrc4h/
HTML:
<div class="tile">
<div class="tile_inner"></div>
<div class="exit_left"></div>
<div class="exit_right"></div>
<div class="exit_up"></div>
<div class="exit_down"></div>
</div>
CSS:
.tile {
float: left;
width: 180px;
height: 180px;
background-color: gray;
border: 2px solid black;
}
.tile_inner {
width: 120px;
height: 120px;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid white;
}
.exit_left {
position: absolute;
top: 90px;
width: 20px;
height: 20px;
border: 3px solid pink;
}
.exit_right {
position: absolute;
left: 165px;
top: 90px;
width: 20px;
height: 20px;
border: 3px solid red;
}
.exit_up {
position: absolute;
left:90px;
top:10px;
width: 20px;
height: 20px;
border: 3px solid blue;
}
.exit_down {
position: absolute;
left:90px;
top:165px;
width: 20px;
height: 20px;
border: 3px solid green;
}
How can I get each of the exit directions centred along the edge of each axis?
Here is an updated snippet: http://jsfiddle.net/Lrc4h/3/
First of all you need to know that when you're using position: absolute the element will position with absolute coordinates based on the first parent that is position: absolute or position: relative falling back to the document if there is none.
Secondly it's important, when dealing with borders like in your example, to understand the box model and how nasty things get when borders cross the borders ;-). It's a common practice to use box-sizing: border-box to make things a bit easier and to mix relative and absolute units nicely. I've included a box model initialization how I prefer it on the top of the example I've posted.
Combining all this together you can start use relative units (percentage) in your absolute positioning. The example I've posted is still using absolute positions but relative to the .tile element. You should always make your absolute positions relative to a parent. Using left: 50% centers the start of your element to the center of your parents width. However, as your exit element also has a width this needs to be compensated by half of it's width. That's why there is a margin-left: -15px. You could also use the calc function if browser support is IE9+. This would look like this: left: calc(50% - 15px).
As you can see the example still has absolute positions and this problem is easy to solve with absolute positioning. You still have to "hard code" a few values, but they are all relative to the parent and you can easily change your .tile dimensions without changing the child elements.
Cheers
Gion
.tile_inner {
width: 120px;
height: 120px;
position: relative;
top: 50%;
left: 50%;
margin: -60px 0 0 -60px;
border: 1px solid white;
}
You just need to adjust the margin
Demo
.tile_inner{
margin: -60px 0 0 -60px;
}
Maybe as not as clean as it can get, but you can use the calc function to use percentages in conjunction with pixels (based on the width & height of the child divs. For example (I'm including only the changes to the CSS code:
.tile {
position: relative;
}
.exit_left {
top: calc(50% - 13px);
}
.exit_right {
left: calc(100% - 26px);
top: calc(50% - 13px);
}
.exit_up {
left: calc(50% - 13px);
}
.exit_down {
left: calc(50% - 13px);
top: calc(100% - 26px);
}
In that way, even when you change the parent div's dimensions, the child divs will remail in place.
Demo: http://jsfiddle.net/xPP32/
Here's slightly optimized version that relies on pseudo-elements and relative units of measurement (%). Scaling this one is a breeze. All you need to do is change the height and width on the .tile and the rest is taken care of. Here's the original square: http://jsfiddle.net/MGse6/. And, here's a square scaled up: http://jsfiddle.net/k9dxW/.
HTML:
<div class="tile">
<div></div>
</div>
CSS:
*, :before, :after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 10px;
}
.tile {
width: 180px;
height: 180px;
background-color: gray;
border: 2px solid black;
position: relative;
}
.tile > div {
width: 65%;
height: 65%;
border: 1px solid #fff;
margin: 17.5% auto 0;
}
.tile:before,
.tile:after,
.tile > div:before,
.tile > div:after {
content: "";
position: absolute;
width: 16%;
height: 16%;
border: 3px solid;
}
.tile:before {
top: 0;
left: 50%;
margin-left: -8%;
border-color: blue;
}
.tile:after {
top: 50%;
right: 0;
margin-top: -8%;
border-color: red;
}
.tile > div:before {
bottom: 0;
left: 50%;
margin-left: -8%;
border-color: green;
}
.tile > div:after {
top: 50%;
left: 0;
margin-top: -8%;
border-color: pink;
}
And, here's another solution where elements are arranged using flow: http://jsfiddle.net/xep9M/.
HTML:
<div class="tile">
<!--
It's very important
to have the divs stack
next to each other
-->
<div></div><div></div><div></div><div></div><div></div>
</div>
CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 10px;
}
.tile {
width: 180px;
height: 180px;
background-color: gray;
border: 2px solid black;
box-sizing: content-box;
}
.tile > div {
width: 16%;
height: 16%;
display: inline-block;
border: 3px solid;
}
.tile > div:first-of-type,
.tile > div:last-of-type {
display: block;
margin: 0 auto;
}
.tile > div:first-of-type {
margin-bottom: 1.5%;
border-color: blue;
}
.tile > div:last-of-type {
margin-top: 1.5%;
border-color: green;
}
.tile > div:nth-of-type(3) {
height: 65%;
width: 65%;
border: 1px solid #fff;
}
.tile > div:nth-of-type(n + 2) {
vertical-align: middle;
}
.tile > div:nth-of-type(2) {
margin-right: 1.5%;
border-color: pink;
}
.tile > div:nth-of-type(4) {
margin-left: 1.5%;
border-color: red;
}