Fullscreen background with absolute divs - html

I'm trying to display a full screen background with multiple div's on top of it. When I'm resizing the browser, the divs also have to move. I want the divs to resize as well, so that they will stay at the same spot of the background image.
I've found a great solution on Stackoverflow, but the image isn't a full screen background. I've tried to adjust it but it doesn't seems to work. Who can help me?
.div-bg {
height: 100vmin;
width: 100vmin;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
}
.cities {
border: 1px solid red;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: red;
}
.cities.Delhi {
position: absolute;
top: 27%;
left: 30%;
}
.cities.Bangalore {
position: absolute;
top: 85%;
left: 33%;
}
<div class="div-bg" style="background-image:url('https://image.ibb.co/f1qio5/insights_indiamap.jpg')">
<div class="cities Delhi"></div>
<div class="cities Bangalore"></div>
</div>

Just change .cities position from absolute to fixed...and instead of using vmin for width and height...use px or rem
.div-bg {
background-image: url('https://image.ibb.co/f1qio5/insights_indiamap.jpg');
height: 30rem;
width: 30rem;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
background-size: auto;
}
.cities {
position: fixed;
border: 1px solid red;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: red;
}
.cities.Delhi {
position: absolute;
top: 27%;
left: 30%;
}
.cities.Bangalore {
position: absolute;
top: 85%;
left: 33%;
}
<div class="div-bg">
<div class="cities Delhi"></div>
<div class="cities Bangalore"></div>
</div>

Related

transform scale works incorrectly for odd pixel widths

I am trying to scale a div, but keep the inside element at the same position and the same size. To do that, I use transform: scale(value) on wrapper and transform: scale(1/value) on the inside div.
The problem is, that the inside div shifts when I change scale. That only happens if width/height of wrapper is odd or not whole. It does not happen for even widths/height of the wrapper.
My goal is to have many child elements of wrapper that scale alongside wrapper, but only one that does not.
Take a look at this example to see problem in action (hover to scale).
Example with no issue, inner element stay fixed on scale (height and width of container are even):
https://jsfiddle.net/o16rau6u/5/
.wrapper {
width: 200px;
height: 200px;
background-color: blue;
position: relative;
}
.bg {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.wrapper:hover {
transform: scale(2);
}
.wrapper:hover .bg {
transform: scale(0.5);
}
<div id="wrapper" class="wrapper">
<div id="bg" class="bg"></div>
</div>
Example with issue, the inner element move a little on scale (height and width of container are odd):
https://jsfiddle.net/o16rau6u/6/
.wrapper {
width: 201px;
height: 201px;
background-color: blue;
position: relative;
}
.bg {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.wrapper:hover {
transform: scale(2);
}
.wrapper:hover .bg {
transform: scale(0.5);
}
<div id="wrapper" class="wrapper">
<div id="bg" class="bg"></div>
</div>
How can I fix this issue and avoid my elements to move on scale whataver the size of container is ?
PS : The example used above is a very simplified example to show the issue and it's not the needed output or the code used. So we are not looking for another way to achieve the same behavior above as it's pretty easy to be done.
At the start I thought this is related to the calculation done by the browser and some rounding but it's seems to be bug. I have done a lot of test and whataver the value of the scale I use it always fail on odd value.
Here is a simple example with only scaleX
body:after {
content: "";
position: absolute;
z-index: 999;
top: 0;
bottom: -200%;
width: 2px;
right: 50%;
margin-right: -1px;
background: rgba(0, 0, 0, 0.5);
}
.box {
width: 200px;
height: 100px;
margin: 50px auto;
background: blue;
position: relative;
}
.inner {
height: 20px;
width: 20px;
background: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -10px;
text-align: center;
color: #fff;
margin-top: -10px;
}
<div class="box">
<div class="inner">A</div>
</div>
<div class="box" style="transform:scaleX(2)">
<div class="inner" style="transform:scaleX(0.5)">A</div>
</div>
<div class="box" style="width:201px;transform:scaleX(2)">
<div class="inner" style="transform:scaleX(0.5)">A</div>
</div>
As you can see below, the browser seems to add an extra pixel to inner div, but if you look more closely the inner div has a correct size but it's being translated by 1px to the right. So the hover block of Dev Tools is positioned correctly but not element itself! So it seems that the browser correctly calculated the position but did a wrong painting.
The same issue appear if we simply apply scale on the container. So it's not because the scale of inner element:
body:after {
content: "";
position: absolute;
z-index: 999;
top: 0;
bottom: -200%;
width: 2px;
right: 50%;
margin-right: -1px;
background: rgba(0, 0, 0, 0.5);
}
.box {
width: 200px;
height: 100px;
margin: 50px auto;
background: blue;
position: relative;
}
.inner {
height: 20px;
width: 20px;
background: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -10px;
text-align: center;
color: #fff;
margin-top: -10px;
}
<div class="box" style="transform:scaleX(2)">
<div class="inner">A</div>
</div>
<div class="box" style="width:201px;transform:scaleX(2)">
<div class="inner">A</div>
</div>
Even if we use floating value with scale where we can say there is some rouding and complex calculation, we have correct output with even values and issue with odd values:
Example with scale(1.25) & scale(1/1.25):
body:after {
content: "";
position: absolute;
z-index: 999;
top: 0;
bottom: -200%;
width: 2px;
right: 50%;
margin-right: -1px;
background: rgba(0, 0, 0, 0.5);
}
.box {
width: 200px;
height: 100px;
margin: 50px auto;
background: blue;
position: relative;
}
.inner {
height: 20px;
width: 20px;
background: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -10px;
text-align: center;
color: #fff;
margin-top: -10px;
}
<div class="box">
<div class="inner">A</div>
</div>
<div class="box" style="transform:scaleX(1.25)">
<div class="inner" style="transform:scaleX(0.8)">A</div>
</div>
<div class="box" style="width:201px;transform:scaleX(1.25)">
<div class="inner" style="transform:scaleX(0.8)">A</div>
</div>
Example with scale(1.33) & scale(1/1.33):
body:after {
content: "";
position: absolute;
z-index: 999;
top: 0;
bottom: -200%;
width: 2px;
right: 50%;
margin-right: -1px;
background: rgba(0, 0, 0, 0.5);
}
.box {
width: 200px;
height: 100px;
margin: 50px auto;
background: blue;
position: relative;
}
.inner {
height: 20px;
width: 20px;
background: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -10px;
text-align: center;
color: #fff;
margin-top: -10px;
}
<div class="box">
<div class="inner">A</div>
</div>
<div class="box" style="transform:scaleX(1.33)">
<div class="inner" style="transform:scaleX(calc(1 / 1.33))">A</div>
</div>
<div class="box" style="width:201px;transform:scaleX(1.33)">
<div class="inner" style="transform:scaleX(calc(1 / 1.33))">A</div>
</div>
Just don't put one of these divs into another, instead put both of them into the third div like this:
.wrapper {
width: 201px;
height: 201px;
position: relative;
}
.div-1 {
width: 100%;
height: 100%;
background-color: blue;
}
.div-1:hover {
transform: scale(2);
}
.div-2 {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
<div class="wrapper">
<div class="div-1"></div>
<div class="div-2"></div>
</div>
This way you just wont be needed to scale the inner div back to it's original height and width.
Browsers are notoriously bad at calculating stuff. There was a time when web developer math stated that (in some browsers) 33.33% times 3 was larger than 100% (but that was 14 years ago). Things have gotten much better since then, but don't rely on it. Doing resize tricks like this is not the way to go.
It seems to me that you want to resize the wrapper, while keeping the background size the same. To do so, you are using a complex transform trick, which (unprefixed) excludes 17% of all internet users. That is improper browser support and another reason not to do this.
This effect can be easily achieved with 99.99% browser support, working on all sizes.
.wrapper {
width: 402px;
height: 402px;
background-color: blue;
position: relative;
}
.bg {
width: 20px;
height: 20px;
display: block;
position: absolute;
top: 201px;
left: 201px;
margin-top: -10px;
margin-left: -10px;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.wrapper:hover {
width: 4020px;
height: 4020px;
}
<div id="wrapper" class="wrapper">
<div id="bg" class="bg"></div>
</div>
If you want it to be responsive (you do!), this should do the trick:
* {padding: 0; margin: 0;}
html, body {height: 100%;}
.wrapper {
width: 50vw;
background-color: blue;
position: relative;
padding-bottom: 50%;
}
.bg {
width: 20px;
height: 20px;
display: block;
position: absolute;
top: 25vw;
left: 25vw;
margin-top: -10px;
margin-left: -10px;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.wrapper:hover {
width: 500vw;
padding-bottom: 500%;
}
<div id="wrapper" class="wrapper">
<div id="bg" class="bg"></div>
</div>

max-width and max-height on background image

I want to show an background-image while hovering over the normal image. They both should have the same height and width. I thought to make it work by giving the div with the background image display: inline-block so it takes the same size as the image, but that makes it so the width: 100% and height: 100% of the image stop working cause they try to take 100% of the width from the inline-block element.
How can I make the background-image the same size as the image while keeping the values of height and width as ..% of the .box div.
.box{
width: 500px;
height: 400px;
border: 1px solid black;
text-align: center;
}
.around-image{
background: url(http://via.placeholder.com/600x400) no-repeat center;
background-size: cover;
display: inline-block;
}
img{
max-height: 100%;
max-width: 100%;
height: 100%;
width: 100%;
opacity: 1;
vertical-align: middle;
}
.helper{
display: inline-block;
height: 100%;
vertical-align: middle;
}
img:hover{
opacity: 0;
}
<div class="box">
<div class="around-image">
<span class="helper"></span><img src="http://via.placeholder.com/300x200">
</div>
</div>
Edit
Thanks to the answer from #dbigpot I probably got a better solution which is changing the background-image on hover. Only problem is that I can't use the max-height and max-width on the image and I need that part of the code so my images always look good inside of the div.
Is there anyway to set max-height or max-width on a background-image?
.box{
margin: 30px;
width: 400px;
height: 200px;
border: 1px solid black;
text-align: center;
background: url(http://via.placeholder.com/300x200) no-repeat center;
background-size: cover;
position: relative;
}
.box:hover{
background: url(http://via.placeholder.com/200x300) no-repeat center;
}
.height p{
position: absolute;
left: -60px;
top: 45%;
-webkit-transform: rotate(-90deg);
}
.width p{
position: absolute;
left: 40%;
top: -40px;
-webkit-transform: rotate(0);
}
<div class="box">
<div class="height">
<p>height: 200px</p>
</span>
<div class="width">
<p>width: 400px</p>
</span>
</div>
As you see, the 300x200 image is stretched over an area of 400x200. I don't want the image to stretch.
To prevent stretching of the image just change the value of the background-size property to contain:
.box {
background-size: contain;
}
.box {
margin: 30px;
width: 400px;
height: 200px;
border: 1px solid;
text-align: center;
background: url(http://via.placeholder.com/300x200) no-repeat center;
background-size: contain;
position: relative;
}
.box:hover {
background: url(http://via.placeholder.com/200x300) no-repeat center;
}
.height p {
position: absolute;
left: -60px;
top: 45%;
-webkit-transform: rotate(-90deg);
}
.width p {
position: absolute;
left: 40%;
top: -40px;
-webkit-transform: rotate(0);
}
<div class="box">
<div class="height">
<p>height: 200px</p>
</div>
<div class="width">
<p>width: 400px</p>
</div>
</div>
You could try using background-size:cover
.box{
width: 500px;
height: 400px;
border: 1px solid black;
text-align: center;
}
.around-image{
background: url(http://via.placeholder.com/300x200/ff0000) no-repeat center;
background-size: cover;
display: inline-block;
}
img{
max-height: 100%;
max-width: 100%;
height: 100%;
width: 100%;
opacity: 1;
vertical-align: middle;
}
.helper{
display: inline-block;
height: 100%;
vertical-align: middle;
}
img:hover{
opacity: 0;
}
<div class="box">
<div class="around-image">
<span class="helper"></span><img src="http://via.placeholder.com/300x200">
</div>
</div>
You could use something like this -
#target {
width: 200px;
height: 200px;
background: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRN_bhuF3l7rhMNNBk4lgEoOp2qnB2TAJd5h_rVGtsWzZ0K0uzs');
}
#target:hover {
background: url('http://3.bp.blogspot.com/-KdSQjJhV4jI/TpMRe96ndUI/AAAAAAAACfQ/BC6ZMvbp_DA/s1600/gerbera-elegant-flowers-9.jpg');
}
<div id="target"></div>
Adjust the background css properties to suit your need.

How to center and overlap DIVs

I have 2 DIVs, that I want to center and overlap. The smaller one is to lay on top of the bigger one.
It works great at full-screen, but if I decrease the browser size, the top/smaller one moves to the left.
<div style="position: relative; top: 160px; border: thin solid gray; border-radius: 10px; width: 300px; height: 64px; margin-left: auto; margin-right: auto; z-index: 1; background: url(...); background-repeat:no-repeat; background-position:top; background-color: #4b2f84"> </div>
<div style="position: absolute; top: 200px; left: 15%; width: 70%; background: white; border: thin solid gray; border-radius: 10px; height: 500px; padding: 50px 30px; margin: auto">something
</div>
I like to use left: 50%; combined with transform: translateX(-50%); when trying to center and overlap content.
The content is offset 50% to the left, and then -50% of its width to the left.. or (this.left == parent.x + parent.width* 0.5 - this.width*0.5)
#div1 {
position: relative;
top: 160px;
border: thin solid gray;
border-radius: 10px;
width: 300px;
height: 64px;
margin-left: auto;
margin-right: auto;
z-index: 1;
background: url(...);
background-repeat: no-repeat;
background-position: top;
background-color: #4b2f84
}
#div2 {
position: absolute;
top: 200px;
left: 50%;
transform: translateX(-50%);
width: 70%;
background: white;
border: thin solid gray;
border-radius: 10px;
height: 500px;
padding: 50px 30px;
margin: auto
}
<div id="div1"> </div>
<div id="div2">something</div>

How to add two background images in css

i want help to add two image one over the other and position two images in center
<div class="im1"> </div>
.im1{
position: relative; top: 0; left: 0;
background-image:url("../images/img-shadow.png"),url("../images/img-1.png");
background-size:contain;
height:358px;
background-repeat: no-repeat,no-repeat;
}
background image is with shadow
i want it to be
This actually can be solved only with CSS.
I created an example here that generates the rotated border of the image.
Now you can insert any image inside :)
p.s of course you need to change the width and the height of the image inside to be the same as the frame diagonal. you can use CSS calculate for this.
body {
background-color: #F3F5F6;
}
.shadow:before,
.shadow:after {
content: "";
position: absolute;
z-index: -1;
height: 10%;
max-width: 90%;
width: 90%;
}
.shadow:before {
-webkit-transform: rotate(86deg);
left: -72px;
right: auto;
top: 118px;
box-shadow: 0 15px 5px rgba(0, 0, 0, 0.2);
}
.shadow:after {
-webkit-transform: rotate(84deg);
left: auto;
right: -92px;
bottom: 75px;
box-shadow: 0 -15px 5px rgba(0, 0, 0, 0.2);
}
.rotate {
-webkit-transform: rotate(45deg);
}
.box {
width: 200px;
height: 200px;
position: absolute;
top: 100px;
left: 100px;
}
.pic-wrapper {
width: 100%;
height: 100%;
border: 10px solid #fff;
overflow: hidden;
}
.pic {
background-image: url('http://modernschoolec.com/wp-content/uploads/2015/04/11-980x408.jpg');
background-repeat: no-repeat;
background-size: cover;
background-position: center;
/* (side)(sqrt(2)) */
width: 282px;
height: 282px;
-webkit-transform: rotate(-45deg);
position: relative;
top: -40px;
left: -40px;
}
<div class="box shadow rotate">
<div class="pic-wrapper">
<div class="pic"></div>
</div>
</div>
You could either give the shadow image a z-index of 100 and give the school image a z-index of 101 or set one to be position relative and one to be position absolute, but you will need media queries to make it responsive.
.im1{
background-image:url("../images/img-1.png"),url("../images/img-shadow.png");
height:358px;
background-repeat: no-repeat,no-repeat;
background-position: center , center;
}

Element not coming to center. I am using absolute?

div #introbox is not centering. I have used container as relative and introbox as absolute. I have set top,bottom,left and right as 0. Still box is not centring. I want to centre the introbox in the intropic.
html,body{
padding: 0;
margin:0;
}
.container{
width: 960px;
margin:0 auto;
position: relative;
}
#header{
width: 100%;
height: 120px;
border-bottom: 1px solid black;
}
#nav{
height: 55px;
border-bottom: 4px solid lightblue ;
}
#intro-pic{
height: calc(100vh - 181px);
width: 100%;
background: url("img/introbg.jpg") center fixed;
}
#intro-box{
height: 55vh;
width: 800px;
background: rgba(0,0,0,0.74);
border-radius: 15px;
position: absolute;
top: 0px;
bottom: 0px;
right: 0px;
left:0px;
}
<div id="header">
<div class="container">
Header
</div>
</div>
<div id="nav">
<div class="container">
Nav
</div>
</div>
<div id="intro-pic">
<div class="container">
<div id="intro-box">
sdfdsfds
</div>
</div>
</div>
Using transform:translate will work for any size div.
html,
body {
padding: 0;
margin: 0;
height:100%;
}
.container {
width: 960px;
margin: 0 auto;
position: relative;
height:100vh;
}
#intro-box {
height: 55vh;
width: 800px;
background: rgba(0, 0, 0, 0.74);
border-radius: 15px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
/* vertical centering */
}
<div id="intro-pic">
<div class="container">
<div id="intro-box">
sdfdsfds
</div>
</div>
</div>
Find the below code.
Make left position 50% and give margin-left half of the wrapper width value.
#intro-box{
height: 55vh;
width: 800px;
background: rgba(0,0,0,0.74);
border-radius: 15px;
position: absolute;
top: 0px;
bottom: 0px;
left:50%;
margin-left: -400px; /* Half of the wrapper width */
}
Try below example if you are trying exact center (from top & left)
#intro-box{
height: 55vh;
width: 800px;
background: rgba(0,0,0,0.74);
border-radius: 15px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -400px; /* Half of the wrapper width */
margin-top: -27.5vh; /* Half of the wrapper height*/
}
JSFIDDLE DEMO
#intro-box {
height: 55vh;
width: 800px;
background: rgba(0,0,0,0.74);
border-radius: 15px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -400px;
margin-top: -27.5vh;
}
But again, .container should have height over or equal to #intro-box
There are many ways to center Elements:
using line-height:
you want to center text and you know the size of the box:
.box { background: red; height: 200px; }
.box span { display:block; text-align: center; line-height: 200px; }
<div class="box">
<span>Text</span>
</div>
using transform:
you want to center anything but dont know the size of your box:
.box, .box2 { background: red; height: 200px; }
.box span { top: 50%; text-align: center; position: relative; display: block; transform: translateY(-50%) }
.box2 span { top: 50%; left: 50%; position: relative; display: inline-block; transform: translate(-50%, -50%) }
<div class="box">
<span>Text</span>
</div>
OR WITHOUT TEXT-ALIGN:
<div class="box2">
<span>Text</span>
</div>
using absolute position:
you know the height of the element you want to center
.box, .box2 { background: red; height: 200px; position: relative; width: 100%; }
.box span { position: absolute; background: green; height: 50px; width: 50px; top: 50%; left: 50%; margin: -25px 0 0 -25px; }
<div class="box">
<span></span>
</div>
There are even more ways to manage this.