Why CSS Background position changes on sprite height change? - html

Something interesting happens in my website. It is in active development and I keep adding and adding stuff to the website's sprite PNG file. Sometimes I add so many icons and blocks that I NEED to change the height of the image, but when I do this, some (NOT ALL!) elements appear on different locations.
For example I have a PNG image with size 900x900 pixels. I mapped the CSS styles to the proper coordinates, they I added 200 pixels of transparent space at the bottom of the image and some styles report different positions :< breaking stuff around the website. So each time I increase the sprite file, I have to open various CSS files and add X pixels (the amount of height I've added). I even added a 1px baseline on the top of the sprite so that I would be certain that I am not changing any positions but just the height.
I read the specification even in the RFCs and the coordinate system start is at x=0,y=0 which is the top left corner of the image. It doesn't make sense to me :(
UPDATE: Some of the containers that give me bugs are made with positive coordinates rather than negative. I still can't explain it to myself, why stuff like that happens.
UPDATE: So the sprite is located at this URL http://lucho.hoolwars.com/img/sprites.png
and here are few styles that change coordinates if the height of the sprite changes
.job-summary {
width: 330px;
height: 45px;
background: transparent url(/img/sprites.png) -15px 435px;
cursor: default;
}
.popup-title {
background: url('../img/sprites.png') -425px -1077px transparent;
width: 275px;
color: black;
font-weight: normal;
}
.popup-close {
position: absolute;
background: url('../img/sprites.png') -771px -972px transparent;
right: -9px;
top: -22px;
width: 38px;
height: 38px;
z-index: 2;
cursor: pointer;
}
Each time I change the height of "sprites.png" those coordinates are no longer valid :|

I think I know whats going on. Hard to explain - but I'll give it a shot.
I believe you have configured some of your sprite images based on the repeating background, because you are not using no-repeat. Every time you add more images to the sprite any icons that were configured on a repeated image will shift.
You will need to:
1) Add no-repeat to your background (any icons that were using a repeated image will probably now be blank)
2) Reconfigure all your classes to use negative values (always use negative values for your image sprites)
I would suggest you setup your sprites similar to this:
CSS
.sprite-map {
background: url(sprites.png) no-repeat;
}
.job-summary {
background-position: -80px 0;
width: 100px;
height: 80px;
}
.popup-title {
background-position: -15px -100px;
width: 200px;
height: 100px;
}
.popup-close {
background-position: -15px -472px;
width: 50px;
height: 50px;
}
HTML
<div class="job-summary sprite-map"></div>
<div class="popup-title sprite-map"></div>
<div class="popup-close sprite-map"></div>
That way you only need to specify the URL to the sprite once. Now when you add images to the bottom or the right of the sprite - nothing else will be affected.
Also if you're familiar with Sass - Compass makes image sprites incredibly easy. It might be worth taking a look at if you're interested: http://compass-style.org/help/tutorials/spriting/
Hope this helps!

Related

How to add shapes/decoration correctly to the page layout

I know it might be a duplicated question, but I couldn't find the answer anywhere else in the internet.
Question is very simple: I want to know how should/could I add shapes/decoration to the page layout correctly so it will not look broken inside a responsive container.
Click here to see the picture!
Actually I don't know the way to add that much shapes without making some mess in the code or completely braking the responsiveness of the container itself. If anybody already have done this, please describe your solution/method of doing this correctly. Thank you in advance and hope this will be useful to somebody else.
You should probably set a position : relative in the parent element and then use position: absolut; with relative unites.
Also take care to have a lower z-index for the decorations:
section {
background-color: rgb(69, 83, 95);
display: inline-block;
position: relative;
width: 70vw;
height: 70vh;
}
.content {
z-index: 2;
}
.element {
position: absolute;
z-index: 1;
color: white;
}
.element1 {
top: 20%;
left: 20%;
}
.element2 {
top: 80%;
left: 30%;
}
.element3 {
top: 50%;
left: 70%;
}
<section>
<span class="element element1">+</span>
<span class="element element2">*</span>
<span class="element element3">*</span>
</section>
As the decorations are just that, with no particular meaning that for example would be read out by a screen reader, I would put them in as background images - either as SVGs or gradients (if suitable) and position and size each one in terms of %s relative to the dimensions of the main element.
That way you have a responsive page and you haven't cluttered up the HTML with elements.
Each of the decorations seems separate, but if they overlap then remember the one that comes first in the background-image list will be shown on top of one coming afterwards.
So you are going to end up with CSS looking something like this:
background-image: url(svg1), url(svg2), url(svg3)...;
background-position: x1% y1%, x2% y2%, x3% y3%,...;
background-repeat: no-repeat no-repeat;
background-size: w1% h1%, w2% h2%, w3% h3%,...;
It's easy to work out the percentages, just use a ruler on the image - any units will do, and divide by the width or height of the main element as appropriate * 100.

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!

positioning in having multiple background images in css

I had an image which I had used as background in my css. I now want to have two images, one after the other. Think, earlier my website had one sponsor, now there are two sponsors, and so, two logos.
I was able to add two background images by googling around a bit, but the position of the second image is right on top of the first. When I give pixel values, it goes off as well.
This is my code so far
.app-header-logo {
background-image: url("../images/image1.png"),url("../images/image2.png");
background-position: center center, 200px center;
background-repeat: no-repeat;
float: left;
height: 50px;
vertical-align: middle;
width: 265px;
}
.app-header-logo a {
float:left;
width:190px;
height:50px;
text-indent:-999px;
}
How can I have image2 right after image1?
This can be accomplished by using CSS Sprites, with sprites you'll be able to combine multiple images into one single .png or .jpg file. There's a great online tool which will help you combine this images into one single file and to use them you just need to call a class for example .sponsor-1 which will contain the background-position for the Sponsor numer 1 image, plus it builds your CSS automatically so you don't have to worry about finding the right position of the background for each Sponsor image. Here's an example of how to use them:
.sponsor-1, .sponsor-2{
background: url(sprites.png) no-repeat;
}
.sponsor-1{
background-position: 0 0;
width: 80px;
height: 50px;
}
.sponsor-2{
background-position: -26px 0;
width: 80px;
height: 50px;
}

Adding logo image to top right of page background

I am trying to add an image "logo.png" to the background of my page in the top right positioning. I am using css to do this and nothing else... here is what i have:
body {
background-image: url('logo.png');
background-repeat: no-repeat;
background-attachment: fixed;
background-position: right top;
background-color: #E6E6E6;
font-family: Arial;
font-size: medium;
}
I'm not sure what I am doing wrong, because no image is appearing
Check the file path where logo.png is located. Is it in the same level as your webpage?
here is a fiddle http://jsfiddle.net/z7d8kcLz/ that works. I really dont see any problem with your code
only change in your code is the link to dummy logo image
body {
background-image: url('http://www.hessionphysicaltherapy.ie/wp-content/uploads/2010/11/dummy-logo1.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
background-position: right top;
background-color: #E6E6E6;
font-family: Arial;
font-size: medium;
}
Make a separate div for the logo, then experiment. Technically you should figure it out via trial and error. Load your page on google chrom, right click>inspect element and you will have a console like bar where you will have the srouce code. On your left find the div you are using and add various elements to it.
Try this:
Put your logo inside a DIV and put it right before the closing body tag.
.logo-div {
Width: 150px; /* Adjust as needed */
height: 150px; /* Adjust as needed */
position: fixed;
right: 0; /* Adjust as needed */
top: 0; /* Adjust as needed */
z-index: 1; /* Adjust as needed */
}
Evan, with CSS you need to create building blocks. In much the way you would draw on a piece of paper you need to tell CSS where it needs to place elements. Sounds simple, but given it if 3D and your don't see the 3D it makes CSS painful. Therefore it it were me I would reap elements in different html tags etc.
HTML
<body>
<div class="brand-group">
// use div tag for CSS background img insertions
<div class="brand-logo"></div>
</div>
// etc
CSS
body{
// width and height are important in the parent element. Without it CSS will just collapse
// going back to blank sheet of paper analogy. If you don't tell CSS the dimensions of the paper
// it will assume zero and start to build the document dimensions based on the elements you create
width: 1000px; // or use 100% or
min-height: 2000px;
// ... other body styling
}
// I like to use a wrapper as I can then place everything brand related into the wrapper
// e.g. logo, tagline, etc. I then position the wrapper and following that the elements within the wrapper
div.brand-group {
// I don't like static or fixed as you cannot use float, etc,, but I get why it is done
// position attribute is essential as you telling CSS who you want to position the logo relative to its parent
// in this case it is body (1000 x 2000)
postion: relative;
float: right;
// alternatively IF you use fixed or static then use this approach
// left: 100%
// left-margin: -215px; // adding 15px right gutter
// you can do something similiar using top if you want to push to top, but lets assume this is your first html element
width: 200px;
height: 100px; //you are not building the group size
top: margin: 15px;
}
div.brand-logo {
// easier to position logos using LESS or SASS as you have functions
// in pure CSS the easiest way to center the logo would be to look at the image dimensions'
// lets say it is 100px x 50px
left: 50%;
margin-left: -50px; // half the width of the image
top: 50%;
margin-top: - 25px; // half height
background-image: url('logo.png');
background-repeat: no-repeat;
background-color: #E6E6E6;
font-family: Arial;
font-size: medium;
}

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.