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

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
}
}

Related

Changing checkbox layout without using label

Is it possible to change the layout of a checkbox without adding the label tag in CSS?
Things like this do not have any effect:
input[type=checkbox][disabled] {
background-color: green;
border: 10px solid red;
}
The only thing I found so far is how to change the opacity.
I'm not sure if this will be much use to you, but it does allow you to "style up" a checkbox without the need for a label. I've remove the disabled flag so you can swap between the different styles. Shouldn't be difficult to add it back in if this will work for you.
Fiddle is here.
input[type=checkbox]:checked:before {
background-color: green;
border: 10px solid red;
}
input[type=checkbox]:before {
content:'';
display:block;
height:100%;
width:100%;
border: 10px solid green;
background-color: red;
}
The above only works on Chrome, however, it seems like Chrome is in the wrong where the specification is concerned.
A fuller answer here: CSS content generation before or after 'input' elements
As of today there is no solution, if we assume a cross browser functional styling, to style the <input type="checkbox" > alone, other than a few properties like opacity, width, height, outline (and maybe a few more).
Using a label (or other content elements) is what you need to do that and here is a good (which this question is likely a duplicate of) post with lots of options: How to style checkbox using CSS?
Note: If you know more properties, feel free to update this answer.

CSS and Sprites for standard buttons

I want to use a standard set of buttons on a website regardless of what is written in them (i.e. submit, pay, go, spell correct) but for some reason I can not get the sprite image to show up. My codes is as follows:
HTML:
<div id="iconic">
Place Sprite button here <span><a class="button" href="#">Test</a></span>
</div>
CSS:
span.iconic a:link
span.iconic a:visited
{
display: block;
background-image:url('images/an_nav_btn.jpg');
width: 150px;
height: 45px;
}
span.iconic a:hover
{
background-position: 0 -50px;
}
span.iconica a:active
{
background-position: 0 -100px;
}
Any suggestions on how to get this to display with the text on top (in this case it will have the button with the word "test" on it.
Thanks in advance.
According to your posted css you are attempting to manipulate a link inside a span with the class of "iconic"... and that doesn't work with what you have in the html:
to get you on the right track, try
replacing all the span.iconic's
with #iconic span's
#iconic span a translates to "all <a>'s inside a <span> inside any element with the id of 'iconic' "
In CSS:
. is used for to prefix class names
# is used to prefix IDs.
Your element is a DIV, and you're specifying a SPAN in your CSS. You've got both of these mixed up.
The CSS declaration for <div id="iconic">
would be:
#iconic {
...
}
You may want to consider looking at Font Awesome, that handles a lot of this for you.

OOCSS Separation of Container and Content?

Question: Is the second OOCSS principle really valid?
According to the OOCSS second principle you're not supposed to have location dependent styles:
Quote from https://github.com/stubbornella/oocss/wiki
Essentially, this means “rarely use location-dependent styles”. An object should look the same no matter where you put it. So instead of styling a specific h2 with .myObject h2 {...}, create and apply a class that describes the h2 in question, like h2 class="category".
Lets take a practical example of this. Say I have a standard 2.0 setup with a normal body (white background) and a huge footer (black background). In the body we have black links and in the footer of course we need white. Isn't the simplest and most intuitive way to achieve this simply to:
a{ color: #000; }
.footer a{ color: #FFF; }
If I where to follow OOCSS principles I'd have to first create a class:
.inverted{ color: #FFF; }
Then proceed to add that class to every link I want inverted. That seems like a hassle.
Isn't the purpose of the whole language that styles are made to Cascade?
Am I misunderstanding something here?
I think you are right in the sense that yes, in your specific example.. perhaps doing it your way would be easier. But then again, if you look at the first sentence in the OOCSS page:
How do you scale CSS for thousands of pages?
In that context.. the second principle makes perfect sense.. so using your same example (ie let's assume we implemented your solution).. let's say that a year down the road your company decides to create light grey buttons in the black footer having black text:
<!-- inside footer -->
<a class="button lightGrey">link</a>
in this case.. all the a tags will be white because they're covered by your cascading. So then we will have to go create another sytle just to undo what your solution did:
.footer a.button.lightGrey {
color: #000; /* huh? but i thought we did this before with a {color: #000;} ?*/
}
where as if we simply made a decision that all a tags by default are black (see last note):
a{ color: #000; }
then in the footer we will create a special type of link that are supposed to be white:
.footerLinks { color: #FFF }
then a year later some of the links are still white.. others within the greyLight button will be black:
<a class="button lightGrey">link</a>
then here we don't have to worry about undoing anything.. a tags have a default color.. and that's it. if 2 years later someone decides that the links inside the lightGrey buttons (anywhere on the site, not only withen the footer.. which is the whole point of OOCSS) should be red.. then this would be the OOCSS approach:
.redLink {
color: red;
}
and the html will be
<a class="button lightGrey redLink">link</a>
in this case it won't matter if we take out the .lightGrey class, or we can have this code within or not within a footer .. it's all the same.. it results in more predictable and re-usable code.. which is OOCSS (I'm very glad that they're finally formalising this.. thanks a lot for the post btw).
One last note: To be pure OOCSS, one shouldn't change the default color of a ie a {color: #000;} is wrong!, it should be left to it's default color (which is blue).. whenever anyone wants to change that color.. then they must specify it ie
<a class="redLink">..</a>
so in this case it's more like the default a is the parent class.. and everything else subclasses it and overrides its default behaviour..
update - response to comments:
reputable site argument:
such initiatives are almost always driven by the community then adopted by reputable companies.. and even when they are adopted by larger companies it usually happens from the bottom up through enthusiastic developers who advocate for such change.. I for one was such an advocate when I was working in Amazon. And even when it's adopted.. it's usually at a small scale and not across all units in the org. it wouldn't even be a good idea for the Googles and the Amazons and the facebooks etc to enforce such a rule b/c there will always be a difference of opinion.. not to mention that such micromanagement would constrain the engineer's creativity.. there could be a guideline in a wiki for a team (ie we had one for the Amazon Kindle Touch app store) but to enforce that rule across 10,000 engineers working across the company wouldn't be practical nor desirable.
So in short if you see value in OOCSS, and start implementing on your site, and advocating it to your fellow web devs, and then it becomes a trend, that's when it eventually becomes an industry wide best practice and that's when you can expect to see it on facebook etc.
example:
take a look at this:
simple: http://jsfiddle.net/64sBg/
a bit more detailed: http://jsfiddle.net/64sBg/2/
without going too much detail (I'm sure you will see the pattern) you can see that the granularity in css descriptions allows for subtle changes without any redundancy in style definition. So notice the left arrow vs right arrow.. also the .red and .blue styles can be subsequently applied to tables etc..
also notice that there isn't a single cascading in my css.. so my styles can be completely independently applied (ie implementing the rule An object should look the same no matter where you put it)
lastly.. there is still use for cascading.. you can definitely use it in your jQuery selectors for example.. also cascading happens by default (ie without you having to explicitly set it in your css styles).. so if you take look at the css below.. you will notice that the font properties of body has cascaded down to all the buttons.
<a class="button blue dark">
<div class=" arrowDownWhite rightArrow">Analytics</div>
</a>
<a class="button red dark">
<div class=" arrowDownWhite leftArrow">Actions</div>
</a>
<a class="button grey light">
<div class=" arrowDownRed leftArrow">options</div>
</a>
and css:
body
{
font-family: Trebuchet MS,Liberation Sans,DejaVu Sans,sans-serif;
font-size: 15pt;
}
.button
{
padding: .5em 1em;
display: inline-block;
text-decoration: none;
}
.dark {
color: white;
}
.light{
color: #E40E62;
}
.blue
{
background-color: #51C8E8;
}
.red
{
background-color: #E40E62;
}
.grey
{
background-color: #E0E0E0 ;
}
.arrowDownWhite
{
background-image:url(http://s2.postimage.org/ywam7ec4l/small_Arrow_Down_White.png);
background-repeat:no-repeat;
}
.arrowDownRed
{
background-image:url(http://s2.postimage.org/je5743t2d/small_Arrow_Down_Red.png);
background-repeat:no-repeat;
}
.leftArrow
{
padding-left: 1em;
background-position: left center;
}
.rightArrow
{
padding-right: 1em;
background-position: right center;
}
It is worth the hassle of separating your skin from the container.
Lets look beyond colors. I wish Nicole Sullivan provided better examples than she does. I have 23 web sites that an contain
Menus
Tabs
Toolbars
Horizontal and Vertical Lists of Links
All of them are Skins of the Nav abstraction
I started off created an abstraction class to handle the common code between all of them. I added a few modifiers to change the orientation from horizontal to vertical, and also the floated position of it. I kept all colors out of the abstraction as well as css rules that can change based on the skin I apply to it.
/* Object */
.nav
{
margin-bottom: 1.5em; margin-left: 0; padding-left: 0; list-style: none;
}
/* Modifier */
.nav--stack .nav__item
{
display: block;
}
.nav--right
{
float: right;
}
/* Elements */
.nav__item
{
float:left
}
.nav__item__link
{
display:none;
}
Menu Skin
I needed a skin that made the .nav abstraction look like a sidebar menu. In case you are wondering, I did not put the padding for .nav_item_link above is because it can change based on the skin. The tabs skin has it set for 2px.
/* Object */
.menu
{
}
/* Elements */
.menu .nav__item--current.nav__item__link
{
color: #fff; background: blue;
}
.menu .nav__item__link
{
padding: 4px; border-radius: 4px;
}
.menu .nav__item__link:hover
{
background: #eee
}
Notice to keep things location-independent - I have 0 tag names. I don't style li and a children on .nav like bootstrap does. This code could be used on dls or even divs and has better performance based on how selector engines read rules.
To me the benefit of just having to skin the objects I have for all 23 sites I have is worth any hassle.

css - user menu - two issues

when I hover the mouse over it, the cursor doesn't change into hand until you actually over over the text. (For example, if you pay attention to SO navigation, your cursor changes into hand as soon as you touch the gray area. I am talking about Questions, Tags, Users, Badges, Unanswered navigation)
when I click on it, it borders the link-text.. like it's dotted border or something by default. How do I get rid of that?
There are two ways of getting the hand cursor on the entire area; either you make the link take up the entire area (perhaps by being the entire area), or you add the style cursor:pointer; to the area. (Making the link cover the whole area is usually the better option, as that also make the entire area clickable.)
To get rid of the dotted border on links when they‘re clicked:
a:active {
outline: none;
}
For SO navigation, it is done in following way:
<li class="nav">
Questions
</li>
.nav a {
padding: 6px 12px;
}
The gray area you see is actually the link itself (achieve by setting the padding). To get rid of the border, you should specify by a:link:
.nav a:active { outline: none; }
For (1), use the <a> around your whole <div>, not just the text, and that will make the cursor change to the hand cursor when entering the div. Another way is to change the <a> to have a style similar to
a { display: block; width: 300px; height: 100px; background: orange }
the background is just for trying it here. It can be removed.
For (2), use
a { outline: none }
Try using the following in your CSS.
a:focus {outline: none;}
However, I believe older versions of IE will not honor this code.

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