How to use SVG symbols in CSS? - css

Using symbols in SVG formats seems like a good idea to me, so you can only load a single SVG file, and use it as a sort of spritemap.
It feels wrong to me though, to directly include the <svg></svg> tags in my html for icons, since they are presentation only and should be added in my CSS.
Is there a way to add a symbol from an svg in an :after pseudo element in my CSS?

You can refer to fragments in CSS this way (fragments must have an ID to identified):
.element {
background-image: url('vector.svg#fragment');
}
You can also show a specific area by clipping it with viewBox:
.element {
background-image: url('vector.svg#fragment(viewBox(0,0,25,25))');
}
Here you can read more about this methods:
http://www.broken-links.com/2012/08/14/better-svg-sprites-with-fragment-identifiers/
Another method could be to create all your symbols in a icon font.

As Blazemonger mentioned in comment you can give it inside the content of an afterelement.
But if you are setting it as a background of an after you would have more control over it regarding its size,position and any other properties a background image can have
html
<div id = "mydiv"><div>
css
#mydiv{
width:500px;
height:100px;
background:tomato;
}
#mydiv:after{
content:"After of #mydiv";
width:500px;
height:100px;
background:url('http://xn--dahlstrm-t4a.net/tmp/sharp-icons/svg-icon.svg') no-repeat;
position:absolute;
top:200px;
border:solid 1px tomato;
}
You can save the svg as a separate file and give it as url for background
DEMO
Read more on ways of adding SVG to page here

Related

Stop CSS 'a' styles being applied to images that are linked

I've been instructed to make links on a website have a different colour underline than the font colour. It all seemed quite easy, using border-bottom as below, except that linked images are now also underlined.
Is there a way, without using JS, to stop happening?
a{
color: #6A737B;
text-decoration: none;
}
a:hover{
border-bottom: 1px solid #C60B46;
text-decoration: none;
}
An example - hovering over the below image now adds the border-bottom CSS style to it, which I don't want -
<a title="Dyne Drewett" href="http://test.dynedrewett.com">
<img class="attachment-full" width="202" height="78" alt="Dyne Drewett Solicitors" src="http://test.example.com/Website-Header.png">
</a>
The only static way to do this would be to use a class on image links like:
<a href='http://whatever.url.here/' class='imglink'>
<img src='img/image.png' alt='Alt text'>
</a>
Then apply a CSS style to this class:
a.imglink:hover {
border-bottom: 0px solid;
}
You'd have to declare this AFTER the other a:hover CSS class.
Technically, you cannot set a style on an element based on what elements it contains. You cannot make the border of an a element depend on the presence of an img element inside (and this is what you are dealing with). Using classes would help, but from the comments, it seems that this is out of the question.
There’s a workaround: place each image at the bottom of the containing element (not on the baseline as per defaults), and shift it down one pixel, or whatever the border width might be. This way, the image will cover the bottom border, provided that the image has no transparency. CSS code:
a img {
vertical-align: bottom;
position: relative;
top: 1px;
}
This slightly changes the position of all images, so it might affect the overall layout unless you take precautions.
I'd suggest adding a class to the link, so you can do
a.imglink:hover{
border:0;
}
Alternatively, if you can't control that class, you can try adding a negative margin to your image to ensure the border doesn't show:
a img{
margin:0 0 -1px 0;
}
That -1px might need adjusting based on your other rules
Here's a fiddle to show the negative margin solution: http://jsfiddle.net/QRXGe/
Your solution will require you adding an additional class name to links that wrap images (or anything where the border should be removed). There's no way to sort of "reverse select" unless you want to employ a JavaScript technique.
A jQuery technique would be something like this:
$('a > img').parent().css('border-bottom', 'none');
That will remove a "border-bottom" style from all anchor tags that have image as a direct descendant. But you'll need it on every page, and every page is getting parsed by this script, so it's a little added overhead on each page.
Otherwise, if you have access to the HTML, creating a CSS class to target these specific links such as:
a.img-link{ border-bottom:none; }
And apply it to any link that's around an image such as:
<img src="#" alt="" />
I hope that helps!
Another way to achieve this is to simply make the images in links relative and then offset the bottom to cover the border. 5px seems to do it http://jsfiddle.net/ECuwD/
a{
color: #6A737B;
text-decoration: none;
}
a:hover{
border-bottom: 1px solid #C60B46;
text-decoration: none;
}
a img {
position:relative;
bottom: -5px;
}
a:hover img {
border-bottom:none;
}
or perhaps...
a:hover img.attachment-full {
border-bottom:none;
}
Apparently, what you want is a different behavior for the same markup (<a>) based on its content.
Sadly, there is no real way to do this with pure CSS, as this language is not programming language and therefore lacks the condition structures, such as if.
That does not mean that there is no solution! Here is a couple of things you can do:
Declare (say) in your HTML that the element (<a>) should be handled differently (with classes, in your case either <a class="text"> or <a class='image'>.
Use JavaScript to change your style dynamically, which means based on conditions, such as content for instance. In your case it would probably be something like:
function onLoad() {
for (var element in document.body) {
// look for links
// if this is a link:
// look for image inside link
// if there is one:
// remove the border
}
}

CSS : stencil effect

I wonder if it is possible in pure css to have a stencil effect:
A block with a background color, and color "transparent" that would reveal the background of the parent block.
For example, I have a parent block with a gradient or pattern as background, and I want to overlay a block with a black background where the text content would leave see the gradient of the parent block.
I haven't found a way to get this to work, but maybe someone has an idea or a tip?
EDIT
Sorry, I should not be precise enough.
Here is a picture of the desired result:
May be you can use CSS3 background-clip. write like this:
HTML
<p>T</p>
CSS
p{
font-size:50px;
font-family:impact;
background: url(http://lorempixel.com/output/technics-h-c-1414-1431-2.jpg);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
position:relative;
width:80px;
height:80px;
text-align:center;
padding-top:10px;
}
p:after{
content:'';
position:absolute;
background:rgba(0,0,0,0.8);
width:80px;
height:80px;
border-radius:100%;
top:0;
left:0;
z-index:-1;
}
body{
background: url(http://lorempixel.com/output/technics-h-c-1414-1431-2.jpg);
}
​
Check this http://jsfiddle.net/rD6wq/6/
Something using an embedded font, such as http://www.google.com/webfonts/specimen/Allerta+Stencil may be close to what you want. By changing the background and text colours, you should get what you are looking for
#element_id {
opacity:0.4;
filter:alpha(opacity=40);
}
this will set the opacity of the div or whatever you apply it too 40% of its original opacity (which is usually 100% unless you apply this to .png or .gif images with reduced opacity already)
As far as I know, you can use SVG for that, but it won't be trivial.
This (and this) might be the closest implementation of what you need. The problem is that it doesn't work the same in every browser, though you may try deeper research.
Upd: Lea Verou has presented a simple and elegant solution in her article: Text masking — The standards way
You can play with the CSS3 text-shadow property.
p{ text-shadow:0px 0px 2px #000 }
See my example here.
Detailed info about the property here.

Printable Stylesheet with DIV

I have a site that I'm trying to make a printable version and I'm using a new print stylesheet, but I'm having a problem. I have a DIV for star ratings that is just an empty DIV in the html file, but in the regular CSS I have background images for the actual stars.
The DIV in the html file looks like this:
<div class="example_rating"></div>
The code in the regular stylesheet looks like this:
.example_rating {
height:40px;
width:200px;
margin-left:20%;
background: url('../stars.png') no-repeat scroll 0 0 transparent;
}
My problem is that the star ratings aren't showing up at all in the printable format of the web page. I don't have the DIV hidden or anything, but I'm not sure what I can do to get it to show up in the printable format.
I realize the question may be a little vague, but I'm not sure how else to explain it. I can definitely give more details if need though. Thanks!
In your CSS, the stars are rendered as a background image, and when printing, backgrounds aren't usually displayed by default.
You'll either have to display the stars as an <img>, or tell your users to enable printing of backgrounds.
EDIT:
The easiest way to get round this would be to print the star rating as text as well as the background image, and then have the font inside the div transparent (and yellow in the print stylesheet). Example:
<div class="example_rating">
4/5 stars.
</div>
Stylesheet:
.example_rating {
color:Transparent;
/* Alternatively: text-indent: -9999px; */
height:40px;
width:200px;
margin-left:20%;
background: url('../stars.png') no-repeat scroll 0 0 transparent;
}
EDIT 2:
You could try putting this in your print stylesheet:
.example_rating {
background: none;
}
.example_rating:after {
content: '4/5 stars'
}
This puts some text inside the div using CSS, and if you put it in your print stylesheet only, it will only appear when you print!
Try making a new print only stylesheet... like this:
<link rel="stylesheet" type="text/css" media="print" href="print.css" />
Or in you current stylesheet, put your printing styles in
#media print {
}

Rollover without image change

I have a small thumbnail image that I wish to change when the mouse rolls over it. I was wondering if there was a way to do this without swapping images on the rollover. For example, through CSS could I have the opacity change on rollover? If you have any other ideas about how to manipulate the image with CSS on rollover for making a change I am open.
Thanx!
You could put both images in one bigger image, use it as a background image and change only the position on roll-over.
With CSS3, there is an opacity option. This way you wouldn't be forced to reload an image when they hover above something.
#div {
background-image: url('blah.png');
}
#div:hover {
opacity: 0.5;
}
I'm not exactly sure if that's the right way to use it so you should use google for more examples. However, you should be careful because not all browsers might be supporting CSS3 yet.
Try using the :hover style on a tag. It may not be supported very well in early IE editions. But you can do something like:
img {
border: 1px solid black;
}
img:hover {
border: 1px solid white;
}

How to change background-color on text links on hover but not image links

I have a CSS rule like this:
a:hover { background-color: #fff; }
But this results in a bad-looking gap at the bottom on image links, and what's even worse, if I have transparent images, the link's background color can be seen through the image.
I have stumbled upon this problem many times before, but I always solved it using the quick-and-dirty approach of assigning a class to image links:
a.imagelink:hover { background-color: transparent; }
Today I was looking for a more elegant solution to this problem when I stumbled upon this.
Basically what it suggests is using display: block, and this really solves the problem for non-transparent images. However, it results in another problem: now the link is as wide as the paragraph, although the image is not.
Is there a nice way to solve this problem, or do I have to use the dirty approach again?
Thanks,
I tried to find some selector that would get only <a> elements that don't have <img> descendants, but couldn't find any...
About images with that bottom gap, you could do the following:
a img{vertical-align:text-bottom;}
This should get rid of the background showing up behind the image, but may throw off the layout (by not much, though), so be careful.
For the transparent images, you should use a class.
I really hope that's solved in CSS3, by implementing a parent selector.
I'm confused at what you are terming "image links"... is that an 'img' tag inside of an anchor? Or are you setting the image in CSS?
If you're setting the image in CSS, then there is no problem here (since you're already able to target it)... so I must assume you mean:
<a ...><img src="..." /></a>
To which, I would suggest that you specify a background color on the image... So, assuming the container it's in should be white...
a:hover { background: SomeColor }
a:hover img { background-color: #fff; }
I usually do something like this to remove the gap under images:
img {
display: block;
float: left;
}
Of course this is not always the ideal solution but it's fine in most situations.
This way works way better.
a[href$=jpg], a[href$=jpeg], a[href$=jpe], a[href$=png], a[href$=gif] {
text-decoration: none;
border: 0 none;
background-color: transparent;
}
No cumbersome classes that have to be applied to each image. Detailed description here:
http://perishablepress.com/press/2008/10/14/css-remove-link-underlines-borders-linked-images/
Untested idea:
a:hover {background-color: #fff;}
img:hover { background-color: transparent;}
The following should work (untested):
First you
a:hover { background-color: #fff; }
Then you
a:imagelink:hover { background-color: inherit; }
The second rule will override the first for <a class="imagelink" etc.> and preserve the background color of the parent.
I tried to do this without the class="", but I can't find a CSS selector that is the opposite of foo > bar, which styles a bar when it is the child of a foo. You would want to style the foo when it has a child of class bar. You can do that and even fancier things with jQuery, but that may not be desirable as a general technique.
you could use display: inline-block but that's not completely crossbrowser. IE6 and lower will have a problem with it.
I assume you have whitespaces between <a> and <img>? try removing that like this:
<a><img /></a>
I had this problem today, and used another solution than display: block thanks to the link by asker. This means I am able to retain the link ONLY on the image and not expand it to its container.
Images are inline, so they have space below them for lower part of letters like "y, j, g". This positions the images at baseline, but you can alter it if you have no <a>TEXT HERE</a> like with a logo. However you still need to mask the text line space and its easy if you use a plain color as background (eg in body or div#wrapper).
body {
background-color: #112233;
}
a:hover {
background-color: red;
}
a img {
border-style: none; /* not need for this solution, but removes borders around images which have a link */
vertical-align: bottom; /* here */
}
a:hover img {
background-color: #112233; /* MUST match the container background, or you arent masking the hover effect */
}
I had the same problem. In my case I am using the image as background. I did the following and it resolved my problem:
background-image: url(file:"use the same background image or color");

Resources