This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best Way to Sprite Images?
I have the following image that I want to use for users to log into site.
http://dl.dropbox.com/u/7468116/facebook_signin.png
However I am not able to make css work properly.
.sprite {
background-image: url("pathto/facebook_signin.png");
background-position: 0 0;
}
.sprite:hover {
background-position: 0 16px /*or whatever the y position of the 2nd button is*/
}
.sprite:active {
background-position: 0 32px /*or whatever the y position of the 3rd button is*/
}
Something like this should work:
a.fb {
display: block;
background: ("/path/to/sprite.png") 0 0 no-repeat; /* start with normal state */
width: 150px;
height: 18px;
text-indent: -9999px; /* for image replacement */
}
a.fb:hover,
a.fb:focus {
/* hover and focus state */
background-position: 0 -20px;
}
a.fb:active {
/* click state */
background-position: 0 -40px;
}
If you are on mac, you can use some tools for writing your CSS file automatically. These tools are ordering your sprites in an effective way and also writes CSS files for you. You don't need to fight with ordering and calculating pixel coordinates, etc. I
suggest Sprite Master.
What exactly's not working in your CSS? Spriting is involves changing the background position of the image on hover (or other states).
So it's really just
#element {
background-position-y: 10px;
}
#element:hover {
background-position-y: 0px;
}
Would be helpful to see your CSS.
Related
I admit I am fairly new to less. While playing with it to make my site as dynamic as possible I was trying to use less variables so if I had to change something I could just do it in one file.
I have run across an issue though when trying to position elements. For example I have a button that is currently sitting on the left side, but in the future I may want to move it to the right. Normally how you call that is either left:0; or right:0;
Is there a way to make that left, or right a variable?
My css looks like this
.previous{
position:fixed;
left:0; //The left is what I want to declare somewhere else
top:#header-padding;
height:#side-height;
font-size: #button-side-font !important;
}
I have tried something like
#{prevPos}: left;
and then calling
#prevPos: 0;
but it just stopped loading my application altogether.
Mixins (update)
Have you tried using a mixin?
It could look something like this:
.previous {
.previous-position();
font-size: #button-side-font !important;
height: #side-height;
position: fixed;
top: #header-padding;
}
.previous-position() {
left: 0;
// right: 0;
}
To swap the left and right, change the comment in the mixin.
Multiple classes approach (original answer)
I'd actually approach this differently. Instead of having the button styles and positioning in the same CSS rule, I'd have the positioning in a sub-class.
.previous {
font-size: #button-side-font !important;
height: #side-height;
}
.previous-left,
.previous-right {
position: fixed;
top: #header-padding;
}
.previous-left {
left: 0;
}
.previous-right {
right: 0;
}
Then your buttons look like this:
I am on the left
I am on the right
I am not fixed
This way you can update your page pretty quickly without having to tear apart your LESS files and it makes your styles more re-usable.
And yet another answer for how to get it to work in a "variable way" using old-fashioned method (intentionally using the most conservative syntax so it could work even with ancient compilers):
#previous-position: right;
.previous {
position: fixed;
margin: 1em;
font-size: 400%;
.-(left) {left: 0}
.-(right) {right: 0}
.-(#previous-position);
}
I'm fairly new to LESS, and I have some code--which seems to work--for a sprite given to me that looks like this. First a variable is defined as follows:
#my_img: 0px 105px 0px -105px 22px 22px 44px 150px 'sprites/sprite-img.png';
This variable gets used like this:
.someClass {
.sprite(#my_img);
}
CSS output of this looks like this:
.someClass{
background-image: url("sprites/sprite-img.png");
background-position: 0 -105px;
height: 22px;
width: 22px;
}
What do the parameters in that variable definition indicate? The last one (url) is obvious, and I believe from looking at the sprite that the 3rd and 4th ones seem to be the background position offsets (X and Y). But what are the others? What do each of the 9 elements in this variable specify?
?
?
horizontal position
vertical position
width
height
?
?
background-image url
The comments on other answers helped make it clear that the .sprite usage is actually not part of LESS, but is a mixin definition, as follows. So the extra stuff in the variable definition is not used in the sprite at all, but exists for other uses.
.sprite-width(#sprite) {
width: ~`"#{sprite}".split(', ')[4]`;
}
.sprite-height(#sprite) {
height: ~`"#{sprite}".split(', ')[5]`;
}
.sprite-position(#sprite) {
#sprite-offset-x: ~`"#{sprite}".split(', ')[2]`;
#sprite-offset-y: ~`"#{sprite}".split(', ')[3]`;
background-position: #sprite-offset-x #sprite-offset-y;
}
.sprite-image(#sprite) {
#sprite-image: ~`"#{sprite}".split(', ')[8].slice(1, -2)`;
background-image: url(#sprite-image);
}
.sprite(#sprite) {
.sprite-image(#sprite);
.sprite-position(#sprite);
.sprite-width(#sprite);
.sprite-height(#sprite);
}
I'm in the midst of creating a SASS mixin that will let me take a spritesheet of social media icons and display them, but I'm having an issue with the background-position when it's hovered over, here's the SASS code:
#mixin social-button($imgurl,$xpos,$ypos,$height,$width) {
background-image: url($imgurl);
background-position: $xpos $ypos;
display: block;
float: left;
height: $height;
width: $width;
&:hover {
background-position: 0px -$height;
}
& span {
position: absolute;
top: -999em;
}
}
And my include:
a.facebook {
#include social-button("../img/social-buttons.png",0px,0px,26px,26px);
}
If you'd like to see/use the spritesheet in action, I've uploaded it here: http://i49.tinypic.com/2evtbwp.png
Here's the HTML as well:
<a class="facebook" href="#"><span>Facebook</span></a>
Essentially the CSS output for the hover is displaying as this:
a.facebook:hover {
background-position: -26px;
}
And in Firebug it displays as this:
a.facebook:hover {
background-position: -26px center;
}
Any help is greatly appreciated, I'm pretty stumped on what I'm doing wrong at this point.. thanks!
PS. I'm going to be creating 5 of these, so I wouldn't mind creating a loop that could auto generate that for me, but at the present time it's not a huge deal, just need to get the hovers working first!
You have to add parentheses around variables when you change them to negatives otherwise it just does the math (0px - $height):
background-position: 0px (-$height);
You probably want to fix the 0px, too.
I am using compass to generate sprite images. And I have MANY sprite icons, and it is generating too much CSS code (too many class selectors for the background image). So lets analyze the compass sprite code:
as you can see here http://compass-style.org/help/tutorials/spriting/
#import "my-icons/*.png";
#include all-my-icons-sprites;
Will generate:
.my-icons-sprite,
.my-icons-delete,
.my-icons-edit,
.my-icons-new,
.my-icons-save { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
If you see I use this way: <div class="my-icons-sprite my-icons-delete"></div>
I want Compass to generate this code:
.my-icons-sprite { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
Else each new image, it'll add for background and background position. Causing too many selectors.
Is there a configuration for that?
Thanks
Have you tried this snippet for Compass?
$icons: sprite-map("icons/*.png");
i{
background: $icons;
display: inline-block; // or block
}
#each $i in sprite_names($icons){
.icn-#{$i}{
background-position: sprite-position($icons, $i);
#include sprite-dimensions($icons, $i);
}
}
This example uses the <i></i>-tag with a class containing the prefix icn- combined with the filename of the separate .png-files in your icons-folder. Like this:
<i class="icn-delete"></i>
The generated CSS looks like this:
i {
background: url('/path/to/generated/spritemap/my-icons-xxxxxxxxxxx.png');
display: inline-block;
}
.icn-delete {
background-position: 0 0;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
.icn-edit{
background-position: 0 -32px;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
.icn-new {
background-position: 0 -64px;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
...
..
.
Still, I haven't quite figured out how to use this in combination with Compass' Magic Selectors.
Magic Selectors works very nice when you need different states (:hover, :active, :target). All you have to do is name your files like this: filename_state.png (delete_hover.png, delete_active.png etc). Compass' Magic Selectors then automatically generates css for :hover, :active and :target (delete:hover, delete_hover and delete-hover). This way you are quite free to choose how you would represent a state-change.
If you, in my first example, has filenames with the postfix for hover/ active states, the snippet only writes CSS like this:
.icn-edit_hover {
background-position: -32px -32px;
height: 32px;
width: 32px;
}
I'd really like to have it print this:
.icn-edit:hover, .icn-edit_hover, .icn-edit-hover{
background-position: 0 -32px;
height: 32px;
width: 32px;
}
like the traditional Compass' Magic Selectors does. Any idea?
In my opinion, it seems like the best of both worlds (less HTML and CSS) would be to have this code (using an attribute selector for the image):
HTML
<div class="my-icons-delete"></div>
CSS
[class^="my-icons-"] { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
Unfortunately, I do not know how to get Compass to export like that. However, unless you are using Compass dynamically rather than just to build your back end static css, you could just change it once generated.
For anyone looking to the answer to ScottS question.
How can I use a css selector for anything starting with a baseclass
Try this:
http://codepen.io/Acts7/pen/nwsEb
I'm pasting the code below.
the spriteGen mixin requires two parameters
1) the baseclass you want to use (in ScottS case --- "myicons"
2) the second parameter is the folder location
Also DONT forget the "." before #{$mySpriteBaseClass}.
Otherwise you get >> myicons-home_icon{background-position:...}
(notice no . for class name selector)
// _custom.scss
// ---------------------------------------------------------
// Sprite Generation
--------------------- */
#include spriteGen('sprites','sprites');
// _mixins.scss
// ---------------------------------------------------------
// Sprite Generation Mixin with options
#mixin spriteGen($mySpriteBaseClass:'.spritebc',$mySpriteFolder:'sprites'){
$mySprites:$mySpriteFolder + "/*.png";
$spritefoldername-map: sprite-map($mySprites,
$spacing: 10px,
$layout: vertical
);
// if using base class as starter for sprite name class
[class^="#{$mySpriteBaseClass}"]{
/*// if using a separate base class
.#{$mySpriteBaseClass}{*/
// TODO:
// Add if/else to set width globally
// or let spriting assign it per each
//width: 48px;
//height: 48px;
display: inline-block;
vertical-align: middle;
background: $spritefoldername-map no-repeat;
}
#each $sprite in sprite_names($spritefoldername-map) {
// if using sprite base class as prefix to full sprite class name
.#{$mySpriteBaseClass}-#{$sprite} {
/*// if using separate base class and sprite name class
.#{$sprite} {*/
background-position: sprite-position($spritefoldername-map, $sprite);
#include sprite-dimensions($spritefoldername-map, $sprite);
}
}
}
What's wrong with the current output?
You can already assign my-icons-delete/edit/new/save only, this is semantic enough - it already says it's an icon and it's a delete icon.
This is what I'm currently doing, it requires Sass 3.3 though:
$icons: sprite-map('icons/*.png');
.icon {
background: $icons;
display: inline-block;
vertical-align: middle;
}
#each $i in sprite_names($icons) {
$underscore: str-index($i, _);
#if ($underscore < 1) {
.icon--#{$i} {
background-position: sprite-position($icons, $i);
#include sprite-dimensions($icons, $i);
}
} #else {
$prefix: str-slice($i, 0, $underscore - 1);
$postfix: str-slice($i, $underscore + 1);
.icon--#{$prefix}:#{$postfix} {
background-position: sprite-position($icons, $i);
}
}
}
I'm using BEM here so it assumes you'll use this like <i class="icon icon--star></i>, so if if you have a "star.png" and "star_hover.png" images it'll generate .icon--star and .icon--star:hover class names.
How can I add css to be only read by safari? bascially a div needs moving 5pixels to the left, as it shows fine on ff/ie etc
Thanks
EDIT - added code
code:
#subheading
{
background-color: #004376;
color: #ffffff;
height: 25px;
padding: 10px;
margin: 0 933px;
margin-top: -25px;
width: 761px;
}
you can have a check for a specific css property in webkit. This would likely work in chrome as well.
#media screen and (-webkit-min-device-pixel-ratio:0) {
.someClass{
color:#FF0000;
}
}
margin: 0 933px;
margin-top: -25px;
width: 761px;
This doesn't sound right. The first line sets both left and right margin to 933px. And the width is 761px. The total width of the element would be (933 * 2 + 10 * 2 + 761) = 2647px.
Is this what you want it to be?