Inserting another image next to <img> with :before - html

I'm trying to replace <img> elements with emoticons with different images through CSS (so that I can match them to the style being used). I thought that I can just insert another smiley with the :before CSS pseudo-element, and hide the original element. This would work, except that the browsers don't seem to insert the extra image! This only happens if I try it with an <img> element, works perfectly when I try it with <span>. The code I tried:
<!doctype html>
<style>
img.icon:before {
display: inline-block;
content: url(smiley.png);
width: 16px;
height: 16px;
}
</style>
<p>Lorem ipsum <img src="smiley.png" class="icon" alt=":)"> dolor sit amet...</p>
The specification at http://www.w3.org/TR/CSS2/generate.html#before-after-content has a note at the bottom:
Note. This specification does not
fully define the interaction of
:before and :after with replaced
elements (such as IMG in HTML). This
will be defined in more detail in a
future specification.
We are using a background image, like it is suggested in the comments, but that has the problem that the images won't print with default printing settings then. The next option we are considering is using <span class="icon"><img ...></span> and putting the :before on the span, but it's a little ugly.
I also wonder if this is specified in CSS3 so that there is a chance for fixing it in the near future.

It's almost certainly easier to use:
img.icon:before {
display: inline-block;
background-image: transparent url(smiley.png) 0 0 no-repeat;
width: 16px;
height: 16px;
}
You might not want to use background-image, but the :before and :after psuedo-elements are already poorly implemented; trying to use content to place images is probably a step too far at this stage.
I'm not sure I see the point of this approach, though; it seems you'll end with two versions of smiley.png next to each other. This might be more easily implemented (replacing the generic smiley.png with a themed smiley.png) on the server-side, than client.

Another way to do this is just set a background-image and hide the img element with overflow, without using :before:
<style>
.icon {
width: 0;
height: 0;
padding-top: 16px;
padding-left: 16px;
overflow: hidden;
background-position: 0 0;
background-repeat: no-repeat;
}
.smiley { background-image: url(smiley.png); }
</style>
<img class="icon smiley" src="smiley.png" alt=":)">
Also, have a look at this article about using data attributes instead of classes for this.

Related

2 background images in one div/table?

I am trying to design a layout for my forum that has 2 background images on a div or a table. I got the idea after looking at this forum's design (http://s4.zetaboards.com/APTSecretServices/index/) If you see on the main category labeled "Category" it contains 2 background images. From exploring the CSS (http://s4.zetaboards.com/c/35079/404/css.css) I found out it was labeled h2left and h2right.
Code:
.h2left {
background: url(http://z4.ifrm.com/30294/164/0/p1083155/h2left.png) no-repeat;
}
.h2right {
background: url(http://z4.ifrm.com/30294/164/0/p1083156/h2right.png) no-repeat right
top;
height: 40px;
}
After seeing this I realized they used the h2, and then on the forum they combine it all together somehow It appears to be done by this code
<table class="cat_head"><tr><td>
<h2>
Category
</h2>
</td></tr></table>
Which is very confusing considering I can't find any proof on how they combined the two.
If you don'y have to support IE<8 than the clean solution is to use pseudo-selectors :before and :after. They really contain unleashed power!
Check the browser support: http://caniuse.com/css-gencontent
In the case of IE6, IE7 the user get only background declared on 'real' DOM element.
Remember that pseudo elements :before and :after cannot be used on empty elements (like images) - because there are 'injected' into element before first (:before) and last (:after) node. Remember that you have to include 'content' declaration inside :after and :before to display the declared styles, too.
On more complicated layouts you can get very nice effects by using "position: absolute" and "z-index" (1.stacking context will prevent layers overlapping by complicated layouts, 2. for IE8 z-index by pseudo-elements don't work, so layers are displayed in the same order as rendered in DOM)
More about pseudo element is nice explained there:
http://www.hongkiat.com/blog/pseudo-element-before-after/
So, conclusion:
<tr>
<td>
<h2 class="table-header">Some text</h2>
</td>
</tr>
.table-header {
/* EDITED: didn't put position on affected element, first that makes the coordinates of :after elements to be calculated from the right element. Sorry! */
position: relative;
/* if element is h2 than we got already "display: block" => width: 100%, height:auto */
font-size:1.5em;
line-height:2.5em; /* that centers the text if it is only one line long. For multi-lined text that method is not reasonable. I took arbitrary height bigger than font-size */
background: url(img-main.jpg);
}
.table-header:after {
content: '';
position: absolute;
top:0; right: 0; bottom: 0; left:0;
background: url(img-additional.jpg);
background-repeat: no-repeat;
background-position: center right;
}
Hope that helps
The markup on that website is
<div class="h2wrap">
<div class="h2left">
<div class="h2right">
<div class="h2center">
</div>
</div>
</div>
</div>
so its a div within a div
You can use this css for multiple background images
#bg_table {
background: url(http://z4.ifrm.com/30294/164/0/p1083155/h2left.png), url(http://z4.ifrm.com/30294/164/0/p1083156/h2right.png);
background-position: left center, right center;
background-repeat: no-repeat;
}
Source: http://www.css3.info/preview/multiple-backgrounds/

How can I style a part of a single character with overlays using a dynamic width?

Question
Can I style just a part of a single character?
Meaning
CSS attributes cannot be assigned to parts of characters. But if you want to style only a certain section of a character, there is no standardized way to do that.
Example
Is it possible to style an "X" which is half-way red and then black?
Not working code
<div class="content">
X
</div>
.content {
position: relative;
font-size: 50px;
color: black;
}
.content:after {
content: 'X';
color: red;
width: 50%;
position: absolute;
overflow: hidden;
}
Demo on jsFiddle
Purpose
My intention is styling the Font Awesome icon-star symbol. If I have an overlay with dynamic width, shouldn't it be possible to create an exact visualization of scores?
While playing around with a demo fiddle, i figured it out myself and wanted to share my solution. It's quite simple.
First things first: The DEMO
To partly style a single character, you need extra markup for your content. Basically, you need to duplicate it:
<​div class="content">
<span class="overlay">X</span>
X
</div>
Using pseudo-elements like :after or :before would be nicer, but i didn't found a way to do that.
The overlay needs to be positioned absolutely to the content element:
​.content {
display: inline-block;
position: relative;
color: black;
}
​.overlay {
width: 50%;
position: absolute;
color: red;
overflow: hidden;
}​
Do not forget overflow: hidden; in order to cut off the remaing part of the "X".
You can use any width instead of 50% which makes this approach very flexible. You can even use a custom height, other CSS attributes or a combination of multiple attributes.
Extended DEMO
Great work on your solution. I’ve got a version that uses :after (instead of duplicating the content in the HTML) working in Chrome 19.
http://jsfiddle.net/v5xzJ/4/
Basically:
Set position:relative on .content
Position :after absolutely
Set :after to overflow:hidden
Adjust the width, height, text-indent and line-height of :after to hide bits of it.
I’m not sure if it’ll work well cross-browser though — the em values will probably work out a bit differently. (Obviously it definitely won’t work in IE 7 or below.)
In addition, you end up having to duplicate the content in your CSS file instead of the HTML, which might not be optimal depending on the situation.

Add image on top of another based on CSS class

I have a bunch of img tags on one of the pages in my site. I want to be able to add a custom image on top of a few of these images based on the css class applied to them
So in case of the statements below
<img src="image_path"/>
<img class="newclass" src="image_path"/>
I want another image added on top of the 2nd image and nothing on the first image.
Can I do this using CSS?
Thanks.
Why I want to do it this way
I can do this using 2 img tags. But it would be easier for me to make changes and add more images by just adding a class name to the img tag rather than adding another img tag itself in the future.
No, you can't do it in pure CSS with just a single img element.
:after is what you would use, but that doesn't work for img elements:
Note. This specification does not
fully define the interaction of
:before and :after with replaced
elements (such as IMG in HTML). This
will be defined in more detail in a
future specification.
You could do it by adding a containing element, and using :after on that.
It works "everywhere" http://caniuse.com/#feat=css-gencontent - with the exception of IE7.
For whatever reason, this specific usage of :after also doesn't work in IE8. It finally works in IE9.
http://jsfiddle.net/AQHnA/
<div class="newclass"><img src="http://dummyimage.com/100x100/ccc/fff" /></div>
.newclass {
position: relative;
float: left
}
.newclass img {
display: block
}
.newclass:after {
background: url(http://dummyimage.com/32x32/f0f/fff);
width: 32px;
height: 32px;
display: block;
content: ' ';
position: absolute;
bottom: 0;
right: 0
}
It's best to have a parent element for your image. This is how you can do it with links (or any other element):
.newclass {
background:url(2.jpg) no-repeat;
display:inline-block
}
.newclass img {
position:relative;
z-index:-1
}
<img src="1.jpg" />
<a class="newclass" href="#"><img src="1.jpg" /></a>
This works fine in IE5.5, IE6, IE7, IE8 and Safari 5 (browsers that I tested).
Edit: thirtydot noticed that this doesn't work if you have a parent container with a background color (because of the z-index on the images). See comments.

What do Google think about links without text, with only background?

Like this one:
Or should I do like this instead and change the font-size to zero:
Home
Edit:
No one here seems to understand my question. So I'll post some CSS too:
#logo {
display: block;
width: 326px;
height: 69px;
background-image: url(images/logo.gif);
background-repeat: no-repeat;
}
#logo:hover {
background-image: url(images/logo-hover.gif);
}
It looks like that, so I can't replace it with an image because then the hover wouldn't work. Seems like there is no solution to this so I guess I'll skip it.
Not including descriptive text of one form or another (text, title or description) would be a serious accessibility failure regardless of any SEO issues.
Edit: If you're asking how to hide the text of a link given a desire to use a background image, there's a few ways to do that. My preferred option (where possible) is to provide a fixed height and then a line height ~3 times as large and turn overflow off. You can also adjust letter spacing to reduce the width towards zero, e.g. from production code:
background: transparent url(../images/sprites/icons.gif) no-repeat;
a.foo
{
width: 16px;
height: 16px;
display: block;
overflow: hidden;
line-height: 666px;
letter-spacing: -1.1em;
}
As I understand, Google does use link text to rank pages. A page with an incoming link text of "foo" will give that page a higher search result position when searching for "foo".
Using your example, you could do the following:
Use a descriptive text in the link:
Foo
<style type="text/css">
a.foo {
display: block;
text-indent: -999em; /* Hide the text, using a negative indent (only works on single lines) */
background: url(foo.png) no-repeat;
width: 329px;
height: 69px;
}
a.foo:hover {
background-position: 0 -69px; /* Using spites to switch between normal and hover state */
}
</style>
Use an image in the page:
<img src="foo.png" width="329" height="69" alt="Foo" />
<style type="text/css">
a.foo:hover {
background: url(foo-hover.png) no-repeat;
}
a.foo:hover img {
visibility: hidden; /* Hide the image on hover, so the background of the link is shown, but dimensions and page flow stay the same */
}
</style>
Which method you choose, depends on what you want to do with it. For example: if you're creating an print style sheet, using the image would be preferred, because background images won't be printed (by default).
You should provide either an image or text for the link. If you go the image route, be sure to have alternate text as well that describes the image and/or the link destination.
Failure to provide ANY context for the link, which is what you are doing now, having nothingness be a link, is poor usability as there is no visual hint for a user using a conventional browser or any way for a screen-reader to handle the link.
A better approach may be to put an image in the a tag; the a:hover CSS can still work with this (at least with some browsers). As a simple example,
a { color: #30f; }
a:active, a:hover {
text-decoration: none;
color: #F30;
background: yellow;
}
can cause a yellow bar to appear adjacent to an image in an a href.
In the terms of SEO, Atl tag is needed as long as it involves images.

Hyperlinking an image using CSS

I know this is probably the dumbest question ever, however I am a total beginner when it comes to CSS; how do you hyperlink an image on a webpage using an image which is sourced from CSS? I am trying to set the title image on my website linkable to the frontpage. Thanks!
Edit: Just to make it clear, I'm sourcing my image from CSS, the CSS code for the header div is as follows:-
#header
{
width: 1000px;
margin: 0px auto;
padding: 0px 15px 0px 15px;
border: none;
background: url(images/title.png) no-repeat bottom;
width: 1000px;
height: 100px;
}
I want to know how to make this div hyperlinked on my webpage without having to make it an anchor rather than a div.
You control design and styles with CSS, not the behavior of your content.
You're going to have to use something like <a id="header" href="[your link]">Logo</a> and then have a CSS block such as:
a#header {
background-image: url(...);
display: block;
width: ..;
height: ...;
}
You cannot nest a div inside <a> and still have 'valid' code. <a> is an inline element that cannot legally contain a block element. The only non-Javascript way to make a link is with the <a> element.
You can nest your <a> tag inside <div> and then put your image inside :)
If you don't want that, you're going to have to use JavaScript to make your <div> clickable:
Document.getElementById("header").onclick = function() {
window.location='...';
}
To link a css-sourced background-image:
#header {
display:block;
margin: 0px auto;
padding: 0px 15px 0px 15px;
border: none;
background: url(images/title.png) no-repeat bottom;
width: 1000px;
height: 100px;
}
<a id="header" href="blah.html" class="linkedImage">
The key thing here is to turn the anchor tag into a block element, so height and width work. Otherwise it's an inline element and will ignore height.
That's really not a CSS thing. You still need your A tag to make that work. (But use CSS to make sure the image border is either removed, or designed to your required spec.)
<img src="foo" class="whatever" alt="foo alt" />
EDIT: Taking original intent (updated question) into account, a new code sample is below:
<img id="header" alt="foo alt" />
You're still in an HTML world for links, as described by other answers on this question.
sorry to spoil your fun ladies and gentlemen, it is possible.
Write in your header: [link](http://"link here")
then in your css:
#header a[href="https://link here"] {
display: inline-block;
width: 75px;
height: 75px;
font-size: 0;
}
.side .md a[href="link here"] {
background: url(%%picture here%%) no-repeat;
}
then in your css
.titleLink {
background-image: url(imageUrl);
}
You still create links in HTML with 'a' (anchor) tags just like normal. CSS does not have anything that can specify if something is a link to somewhere or not.
Edit
The comments of mine and others still apply. To clarify, you can use JavaScript to make a div act as a link:
<div id="header" onclick="window.location='http://google.com';">My Header</div>
That isn't really great for usability however as people without JavaScript enabled will be unable to click that and have it act as a link.
Also, you may want to add a cursor: pointer; line to your CSS to give the header div the correct mouse cursor for a link.
CSS is for presentation only, not content. A link is content and should be put into the HTML of the site using a standard <a href=""> tag. You can then style this link (or add an image to the link) using CSS.
You have to use an anchor element, wrapped in a container. On your homepage, your title would normally be an h1, but then on content pages it would probably change to a div. You should also always have text in the anchor element for people without CSS support and/or screen readers. The easiest way to hide that is through CSS. Here are both examples:
<h1 id="title"><a title="Home" href="index.html>My Title</a></h1>
<div id="title"><a title="Home" href="index.html>My Title</a></div>
and the CSS:
#title {
position:relative; /*Makes this a containing element*/
}
#title a {
background: transparent url(../images/logo.png) no-repeat scroll 0 0;
display:block;
text-indent:-9999px; /*Hides the anchor text*/
height:50px; /*Set height and width to the exact size of your image*/
width:200px;
}
Depending on the rest of your stylesheet you may need to adjus it for the h1 to make it look the same as the div, check out CSS Resets for possible solutions to this.
Try this - use an H1 as the seat of your graphic instead. Saved my butt time and time again:
<h1 class="technique-six">
CSS-Tricks
</h1>
h1.technique-six {
width: 350px;
padding: 75px 0 0 0;
height: 0;
background: url("images/header-image.jpg") no-repeat;
overflow: hidden;
}
Accessible, and also solid across browsers IE6 and > . You could also link the H1.
HTML is the only way to create links - it defines the structure and content of a web site.
CSS stands for Cascading Style Sheets - it only affects how things look.
Although normally an <a/>; tag is the only way to create a link, you can make a <div/> clickable with JavaScript. I'd use jQuery:
$("div#header").click(function() {window.location=XXXXXX;});