:hover:before text-decoration none has no effects? - css

As title, I'm adding icons using .icon-*. When adding an icon to an hyperlink:
Email me!
The content inserted by content property shows the underline text-decoration on hover. I'd like to disable the text-decoration only for the content before:
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: 'IcoMoon';
font-style: normal;
speak: none;
}
.icon-mail:before {
content: "\37";
}
[class^="icon-large-"]:before, [class*=" icon-large"]:before {
font-size: 48px;
line-height: 48px;
}
a[class^="icon-"]:before, a[class*=" icon-"]:before {
margin-right: 5px;
vertical-align: middle;
}
I've tried this but it's not working (decoration is still visible):
a[class^="icon-"]:hover:before, a[class*=" icon-"]:hover:before {
text-decoration: none;
color: white;
}

Insert display:inline-block; in your css. Something like the one below:
.icon-mail:before {
content: "\37";
display:inline-block;
text-decoration:none;
}
Here is the JS FIDDLE:
http://jsfiddle.net/73p2k/18/

As the :before pseudo-element is rendered as a descendant box (more specifically, just before the first child content box) of its generating element, it obeys the same rules its normal descendant boxes do with respect to text-decoration:
The 'text-decoration' property on descendant elements cannot have any effect on the decoration of the ancestor.
See these answers for more details:
CSS text-decoration property cannot be overridden by child element
How do I get this CSS text-decoration override to work?
There isn't any good way around this... the only alternatives that come immediately to mind are:
Wrap the text in its own span element, then apply text-decoration to that span, as shown by skip405. The disadvantage is, of course, extra markup.
Use an inline block background image instead of inline text in an icon font with your :before pseudo-element (I've also corrected the inconsistencies with your class selectors):
[class^="icon-"]:before, [class*=" icon-"]:before {
display: inline-block;
width: 1em;
height: 1em;
background-size: contain;
content: "";
}
.icon-email:before {
background-image: url(icon-mail.svg);
background-repeat: no-repeat;
}
.icon-large:before {
width: 48px;
height: 48px;
}
a[class^="icon-"]:before, a[class*=" icon-"]:before {
margin-right: 5px;
vertical-align: middle;
}
The advantage this has over skip405's solution is that you don't have to modify the HTML, but given that it uses SVG vector background images and background-size, it won't work in IE8.
If you do need IE8 support, then you have to fall back to bitmap images:
.icon-email:before {
background-image: url(icon-mail.png);
}
.icon-email.icon-large:before {
background-image: url(icon-mail-large.png);
}

A pseudoelement selector must be the last item in a selection chain.
You can apply a style to element:hover:before but not to element:before:hover.

You can set height & overflow:hidden for :before element, and text-decoration will not be visible :)

Tried some things using just the a tag as a markup, but alas. A possible workaround for you may be to inner wrap the link in another element, a span, for instance. Thus you can have the underline on this element (instead of a pseudoelement) - which is perfectly controlled by css.
A live example is here: http://jsfiddle.net/skip405/fQHUH/

This solution worked for me. It excluedes the pseude-elements.
But for this you need to wrap the content of the <a> tag into an extra element.
a:hover { text-decoration: none; }
a:hover > * { text-decoration: underline; }
<span>content</span>

Related

How to change the CSS style of first-letter when hover over a parent element?

This is likely something I am just stupidly overlooking, but would you please tell me why hovering over the second division element doesn't cause the background color of the first letter to change to rgb(50,50,50) from rgb(150,150,150)?
Hovering over the first division, which starts out with no styling on the first letter, reacts to the style changes upon hover. But the second division, which starts out with the same styles that the first displays upon hover, does not change to the darker background upon hover.
I'm using the latest version of Firefox developer edition. I see now that it works in Chrome; so must be a Firefox issue.
Thank you.
div > p:before { content: 'This text.'; }
div:nth-child(2) > p::first-letter,
div:first-child:hover > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:nth-child(2):hover > p::first-letter
{
background-color: rgb(50,50,50);
}
<div><p></p></div>
<div><p></p></div>
This snippet works in Firefox. It seems that to get the ::first-letter to be styled both without and with :hover a letter has to be there apart from the content added by :before or :after.
div > p:after { content: 'his text.' }
div > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:hover > p::first-letter
{
background-color: rgb(70,70,70);
color: white;
}
<div><p>T</p></div>
I applied #Sydney Y's solution to the above snippet just to show that it works in Firefox. I don't think it is an isue of the :hover not being recognized because the snippet above recognizes it. It appears to be an issue of not including the text added through :before { content: ... } such that there is a first letter to which to apply the style. But adding no content on :hover using :after seems to alter that and works for variable content.
I realize that this of little interest to anyone who doesn't want to use drop caps and change their style based on hover.
div > p:before { content: 'This text.' }
div > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:hover > p::first-letter
{
background-color: rgb(70,70,70);
color: white;
}
div:hover > p:after { content: ''; }
<div><p></p></div>
Yep, just some mix-ups, your accessors are correct. Each block of CSS needs to apply to both divs:
div > p:before { content: 'This text.'; }
div> p::first-letter {
padding: 0.5rem;
background: red;
}
div:hover> p::first-letter{
background: black;
}
div:hover > p:after { content: ''; }
Thanks for the snippet, that's cool!
Edit: getting closer! Code is updated. Still attempting on Firefox.
Edit: Solved, kind of. It works, but it's kind of a hack. The
issue: In Firefox the hover doesn't trigger a repaint in this specific
instance, so I added an empty bit of content on hover because the
:after or content seem to have a kind of a hook. You may be able to
achieve the same thing with a different hack other than content.
But good news is: this works in both Chrome and Firefox.
Awesome problem. I can't imagine ever coming across this issue again, but it was super interesting to troubleshoot.
There is a bug in firefox that nth-child() is not going to work on syntax that's why it is not working. Anyway if not want the same functionality as first one with different color this can be done with you just need to put hover in front of this code
"div:nth-child(2) > p::first-letter,div:first-child:hover > p::first-letter ". I hope this will help. https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child

Pass :after content attribute with html attribute

I have a number of div's, each needing a different content attribute in the :after element.
It is not possible for me to style each div individually, because the amount of div's is rather large.
My question: Can I pass the attribute in the html tag itself?
Say I have
Engels
With an :after styling like
content: "this needs to change";
display: inline-block;
color: #A9B0BB;
float: right;
font-style:italic;
How can I pass on the this needs to change string in html? Is there a better way to do this? (preferably without using js)
You could use an attribute for it:
<a title="this will be displayed in the :after">test</a>
CSS:
a:after {
content: attr(title);
display: inline-block;
color: #A9B0BB;
float: right;
font-style: italic;
}
Fiddle

How to adjust spaces between lines

In my site , there is a big space between each line . This is the css portions of that section. I have tried line-height but it is not working there.
#site-generator a {
color: #5D45A3;
font-weight: normal;
text-decoration: none;
}
You can check the site here . Check the footer area 'Latest News'. I would like to reduce the space between each post names.
Seems like you need to remove the height property from here:
.widget-area ul li {
font-size: 11px;
/* height: 23px; */ /* <- remove */
}
and here:
.widget ul li {
font-size: 11px;
/* height: 16px; */ /* <- remove */
}
Or set these heights as auto
Simply adapt the height value in your stylesheet to your needs.
Line-height should work to adjust the space between two lines.
.widget-area ul li {
font-size: 11px;
height: 16px; /* example */
line-height: 0.8em;
}
Press F12 in your favourite browser to access the developer console (I believe this works in the latest version of IE, FF and Chrome). Inspect the a element that has such an abnormal height. This shows that:
You are setting a line-height of 2.2em on #site-generator in style.css. If that style is deleted, it uses a line-height of 1.625 for body, input, textarea in style.css.
The distance between two li's in that menu is defined by .widget-area ul li and is 23px. If that style is deleted, the css for .widget ul li is used instead with a height of 16px.
You'll need to alter the first one to put the text of one link closer together. You'll need to alter the second one to put the different links closer together.
For the post titles use
#site-generator .widget_recent_entries a{
line-height:14px;
}
in
.widget-area ul li {width:auto !important;line-height:18px;}

CSS class order

i have a main "div" with multiple divs and "a" tags and i wanted to set a "template like" css to make them all look the same, but some of the A tags need to be different so i thought about making it like this:
<div class="main">
CLick A
<br/>
CLick B
<br/>
CLick C
....
</div>​
and on the css:
.main a{
/* Links Scheme */
}
.exception{
/* particular link css */
}​
But the browser gives preference to my "template" instead of the particular class. shouldn't the class be the most important or am i missing something?
FIDDLE Link
PS: without the use of "!important" tag please
This is an issue of specificity. Since .main a includes a class and a tag name, it is more specific, and thus gets higher precedence than just a class name.
So, to solve it, use .main .exception for your exception.
.main a is more specific then .exception. I think what you are going for is:
.main a{
/* Links Scheme */
}
.main a.exception{
/* particular link css */
}​
In css, orders are also determined by how specific the selector is, so try changing .exception to .main a.exception.
jsFiddle: http://jsfiddle.net/jdwire/DFNyW/2/
you can use :not() pseudo-class, The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class. so you can fix code like this:
.main a:not(.exception){
color: #3b5998;
outline-style: none;
text-decoration: none;
font-size: 11px;
font-weight: bold;
text-decoration: none;
}
.exception{
color: #0498ba;
font-family: Verdana, sans-serif;
font-size: 30px;
letter-spacing: 2px;
margin: 0 0 0;
padding: 0;
font-weight: bold;
text-decoration: none;
}
<div class="main">
CLickA
<br/>
CLickB
<br/>
CLickC
</div>

Why does :before only seem to work once in my code?

I am using :before to display webfont icons before menu items. For some reason :before is only working on one class and is completely ignoring the other class. If I change both classes on the two li's that should have icons before them to the working class name, the icon shows up.
Ideas?
Here is an example:
http://jsfiddle.net/bigdmachine/erxjE/1/
I'd rather update the CSS to;
nav#al-top-menu .log-out a:before,
nav#al-top-menu .setting a:before {
content: "X";
margin-left: 15px;
margin-right: 5px;
font-family: 'WebSymbolsRegular';
font-size: 14px;
color: blue;
}
I don't think you can create "free" pseudo-elements inside of an <ul> like that, the list should only contain list items.

Resources