Pin elements to a div with background-size: cover - html

I have a page that displays a map with some pins placed on places of interest. Markup and style as follows:
HTML:
<div class="map">
<div class="pins">
Pin #1
...
Pin #12
</div>
CSS:
.map {
width: 100%;
height: 100%;
position: relative;
background: transparent url([image]) no-repeat 50% 50%;
background-size: cover;
}
.pins {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
{
.pins > a {
width: 20px;
height: 31px;
position: absolute;
}
My question is: how can I keep my pins, which are absolutely positioned to specific locations on the map, aligned correctly with the map? I've tried using percentage values for the pin positions but because the map is always centered, the alignments go off as soon as the map starts getting cropped at the sides.
I realise I can implement a JS fix, but I'm wondering if there's a pure HTML/CSS solution to this.
Thanks.

I like your question!
So what background-size cover does is keeping the perspective of the image.
This way you don't know how the displayed dimensions of the image are.
Execpt you knew the ratio in the first place.
I did some experimenting, with the fluid-video-padding-bottom "hack".
So imagine a 16/9 map.
All you need is a container that lays exact on top of the image (or it could be the very same container as in my example) and behaves the same as background-size cover. Achieved using padding-bottom trick.
The only thing left to do is resize the pins accordingly. (I used viewport based units)
My example.
padding-bottom: 56.25%; /* 16:9 */
Instead of using the padding bottom trick, you could use object-fit positioning. Which is not well supported yet.

Related

CSS - how to place a background-image on my background?

I want to display some random design images on my sites background as background-image, problem now is that every time I place such an image it somehow interacts with nearby boxes etc.
I just want my design images (small icons etc) to be part of the background without getting in touch with other non-design elements like text, boxes etc.
Something like that I guess:
body {
min-height: 100vh;
position: relative;
height: auto;
width: auto;
background-image: url("/static/pattern.jpg");
background-repeat: repeat;
z-index: -10;
} -> "The actual background of the site"
.design_element_01 {
position: relative;
z-index: -1;
background-image: url("/static/xyz.png");
max-width: 100px;
} -> "The design element that should get placed onto the body background from above"
Try:
.design_element_01 {
position: absolute
/*...*/
}
In addition, you might need to change max-width to width, since a background doesn't provide width to the element.
Centering the Background
There are a few different approaches to centering the background. I'll outline one here; if it doesn't work for you, I can describe others.
Essentially, the idea is to make the .design_element_01 element itself take up the entire page. Then, background-size can be used to constrain the size of the background, and background-position can be used to center it. A basic example would be:
.design_element_01 {
position: absolute;
top: 0;
left: 0;
background: url("/static/xyz.png");
width: 100%;
height: 100%;
/* I'm using 100px here since you used max-width: 100px, but you can use whatever you want. */
background-size: 100px;
background-position: center;
background-repeat: no-repeat;
z-index: -1;
}
(Do note that I haven't tested this; you may need to tweak it.)
If you test this example, however, you will notice that this centers the background on the screen, but not necessarily the entire page. This may or may not be what you want. If not, you can change the <body> element's position property:
body {
position: relative;
}
This should cause the .design_element_01 element to be positioned relative to the <body> element.
I also created a JSFiddle example to demonstrate the solution: https://jsfiddle.net/mouqewzv/.
Finally, if you don't want your element completely centered, but just offset from the center, you could tweak the left and top properties of design_element_01 to position the background initially at the center, but then offset it.
Try setting your design_element_01 position to absolute NOT relative
and then try to place it however you want using
left:
right:
top:
bottom:
z-index:
Hope this works!

Responsively rescale and position image over responsive element

Example to best describe question:
I have an image, lets call it background (blue in example). In this example the image is
2000px wide / 1000px high
has width: 100% set and will rescale with the browser window.
I also have another image, let's call it green. It's a square which is
200px x 200px (width is 10% of the size of the background).
What I want to achieve is that I want green to rescale and reposition accordingly and fully cover the pink target position of the background, regardless of current viewport width (in other words: it should be "responsive").
The rescaling part is easy, as it's just to set the width to 10%. The positioning is a harder nut to crack. The following code is as far as I get. As I'm using position: absolute I'm removing the element from it's natural flow and top: 40% will be 40% of 0 and the green square will stay at the top.
Same example code is available as a CodePen for easier editing: http://codepen.io/emiloberg/pen/vGdNaX?editors=1100#
Is this simply not possible with pure CSS? If not, one possible workaround could be to use the image element of a svg.
.wrapper {
position: relative;
}
.bg {
position: absolute;
width: 100%;
}
.green {
position: absolute;
width: 10%;
left: 60%;
top: 40%; /* This isn't working */
}
<div class="wrapper">
<img class="bg" src="https://dl.dropboxusercontent.com/u/3378286/solayout/bg.png">
<img class="green" src="https://dl.dropboxusercontent.com/u/3378286/solayout/green.png">
</div>
(I had a hard time finding a suitable title for this question. Feel free to edit it)
Explanation: http://www.w3schools.com/css/css_positioning.asp
CSS:
.bg {
position: relative;
width: 100%;
}

Position an element on an empty container responsively

I got the following problem. I want to display a map on a site. The map is a background image.
This Code makes the image perfectly responsible.
section#map {
max-width: 960px;
}
div#map-image {
background: url(Map.jpg) top left no-repeat;
background-size: 100%;
padding-top: 41.875%; /* 402px/960px = 0.41875 height/width of map */
}
So far so good!
But now I want to have some sort of location pin on that map, that behaves also responsive. Since I want to animate it I didn't include in the map graphics, so that is of the table.
Is that possible to do?
Using position:relative; doesn't work because the parent element do not have a width/height specified. Margin/Padding didn't work either.
style for the location pin:
span#location
{
background-color: red;
width: 12px;
height: 12px;
border-radius: 6px;
/*position: relative;
top: 86.9%;
left: 52.26%;*/
}
html looks like this:
<section id="map">
<span id="location"></span>
<div id="map-image"></div>
</section>
Any ideas how to pull this off?
add position: relativeto #map the width of the map seems to be 100% of its parent. position:relative for the pin should then work.
Unless you set the map to position:relative, any relative or absolute positioned elements within that <section id="map"> will take its relative position from the <body>
Can't test it because I don't have the map-image, but this seems working:
position: absolute;
jsfiddle

Positioning to specific element on parent background

I want to make a device-independent animation in HTML5/CSS3. That means I have a background image, specifically drawn so that its edges can be cut off, and I am using it in a div element with background-size: cover, like this:
#main-image {
background: url(intro1-1.jpg) no-repeat center center fixed;
background-size: cover;
height: 100%;
width: 100%;
overflow: hidden;
z-index: 0;
}
#propeller {
background: url(propeller2.png) no-repeat;
position: relative;
top: 265px;
left: 1080px;
z-index: 10;
background-size: 100% 100%;
width: 18%;
height: 12%;
}
<div id="main-image"><div id="propeller"></div></div>
On top of the background layer, I want to draw the animating layer. Here comes the trouble: how do I position the transparent animating parts to a specific position in the full (non-scaled) background image?
I'd also need to scale the animation layer using the same ratio as the background was scaled. But how do I do that?
SO in effect, I'm looking for a way to load the HD background image, define the HD animating layer on top of it, and then apply the cover to fill the full browser screen.
What is the simplest way to do this?
In my experience this is hard to do in pure CSS. I've made something similar to what you're asking here: http://jsfiddle.net/ahhcE/
Here's the propeller specific code:
#propeller {
background: url(propeller2.png) no-repeat;
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
margin-left: -9%;
margin-top: -6%;
z-index: 10;
background-size: 100% 100%;
width: 18%;
height: 12%;
}
I positioned it absolute just for ease, but you're likely going to want it relative if it's positioned relative to the parent div.
(sorry for the colors, my replacement for your images)
The problem is that on the top margin, and height percentages, the browser inherits those values from the width of the window. So you'll notice that if you resize the view window the box doesn't stay perfectly centered. I've usually solved this in the past using javascript. Something like this:
function heightAdjust() {
var windowHeight = $(window).height();
totalMenuHeight = $("#menu").height();
document.getElementById('menu').style.marginTop = windowHeight / 2 - totalMenuHeight / 2 + 'px';
$('.thing').css("height", windowHeight+'px');
}
Hopefully that helps. Centering vertically is really your only issue here, you can also hack this successfully using table styling which is what a few sites use for vertical positioning. More on that, and other solutions here: http://coding.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/

Is it possible to achieve this flexible layout without using JS?

What I'm trying to achieve without using JS can be seen on jsfiddle.net/k2h5b/.
Basically I would like to display two images, both centered, one in background and one in foreground:
Background Image: Should cover the whole window without affecting the aspect ratio, which means that the image will always touch two opposite edges of the window, but the image will be cropped.
Forground Image: Should be inside the window without affecting the aspect ratio, which means the image will be always touch two opposite edges of the window, but the image will not be cropped.
It doesn't matter if it's a <div> or an <img> tag, as long as they are displaying the images.
Asume also that the image sizes are known upfront and can be used in CSS or HTML part.
So my question is: is it possible using only CSS or CSS3?
If it's not possible I will accept the answer that will be as close as possible to my goal.
Examples:
When the background image is cropped from the top and bottom:
When the background image when it's cropped from left and right:
After looking at #Kent Brewster's answer, I think I could achieve all the requirements of OP.
This doesn't have the problem of foreground image being cropped and you can also specify constant margin around the foreground image. Also div is being used instead of img tag, because we are using background images. Here is the link and here is the code:
<div id='bg'></div>
<div id='fg'></div>
#bg {
position: absolute;
height: 100%;
width: 100%;
background-image: url(http://i.imgur.com/iOvxJ.jpg);
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
}
#fg {
position: absolute;
top: 10px;
left: 10px;
bottom: 10px;
right: 10px;
opacity: .7;
background-image: url(http://i.imgur.com/HP9tp.jpg);
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
Try this:
<html>
<style>
body {
margin: 0;
}
#bg {
position: absolute;
height: 100%;
width: 100%;
background: transparent url(bg.jpg) 50% 50% no-repeat;
background-size: cover;
}
#fg {
position: absolute;
height: 90%;
width: 90%;
top: 5%;
left: 5%;
background: transparent url(fg.jpg) 50% 50% no-repeat;
background-size: cover;
opacity: .7;
}
</style>
<body>
<div id="bg"></div>
<div id="fg"></div>
</body>
</html>
If the scaling requirement is flexible, it might work. See http://jsfiddle.net/k2h5b/5/ to see it run.
Yes, it's possible.
Basically I just made the background image the background for the <body> (doesn't have to be the body of course), and then put the image inside that with a small margin.
<body>
<img id='fg' src='http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg'></img>
</body>
css:
body {
margin: 0; padding: 0;
overflow: hidden;
background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}
#fg {
margin: 20px 20px;
opacity: 0.7;
}
obviously if the window is too big, there'd be issues. You could (I guess) use media queries to pull in different image sizes based on window size.
edit — OK, well for the image, if you do want it to crop and retain the right aspect ratio, then I think you'll have to know the image size ahead of time to do it so that it works out. Lacking that, here's another revision.
<body>
<div id='fg'> </div>
</body>
css:
body {
margin: 0; padding: 0;
overflow: hidden;
background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}
body, html { width: 100%; height: 100%; }
#fg {
margin: 2%; width: 96%; height: 96%;
opacity: 0.7;
background: url('http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg') no-repeat center center;
}
If you know the image dimensions, you could then set max-height and max-width. (I'll try that too :-)
edit again To get the background to crop in a centered way, you'd need to set the position to "center center" instead of "left top". (Or "center top" if you just want it centered horizontally.)
Vertically centering elements with CSS without cutting-edge non-standard features (flexible box layout) is hard. That may be something to do with JavaScript. I'll say that one problem with any JavaScript solution like that is that it really slows the browser down. If you must do it, I would suggest introducing a little time lag so that you don't try to recompute the layout on every resize event. Instead, set a timer for like 200 milliseconds in the future where the work will get done, and each time you do so cancel the previous timer. That way, while a person is dragging the window corner it won't burn up their CPU.
edit even more ooh ooh yes #Kent Brewster's answer with the vertical centering is good - I always forget that trick :-)
There is no way to achieve this effect using only CSS, for two main reasons:
Because you are trying to resize your image, you cannot use the background property and must instead use an <img> tag. Your image will always try to take up as much room as it can if the width and height are not set. Thus, the aspect ratio will not be maintained, or your image will be cropped.
The other caveat of resizing the image is that you will not be able to vertically-align it to the center of your page without knowing its dimensions.