css :after content not underlined - css

To seperate the links in navigation I have set the following
#menu-main li a:after{
content: " * ";
}
The current item gets additional
text-decoration: underline;
my problem now is, that the " * " is also underlined, but shouldn't
I have tried to add
#menu-main li a:after{
text-decoration: none !important;
}
but it has no effect
Does anyone have an idea how to keep the text underlined but not the :after content?

In normal flow, the pseudo element expands the dimensions of the element, and what you see is the underline of the underline of the link itself. Add a:after {text-decoration: line-through;} to verify.
Here's a proposed solution: http://jsfiddle.net/Ronny/Smr38/
Basically, when using position: absolute for the pseudo-elements they no longer affect the dimensions of their parent elements, so the underlines are cut at the right place. You still need to take care of things like pointer events, hover state and focus rings, but I left at least the latter for you to figure out.

if you're in control of markup, you could insert a span in your link
<span>your link</span>
and use this css
a { text-decoration: none }
a span { text-decoration: underline }
doing so, the content injected into the :after pseudoelement won't be underlined
otherwise, you may apply the style to li:after (if it is possibile) like so
#menu-main li:after{
content: " * ";
}

It's an old question, but it's what you find using Google so I thought I'd share my solution when you need the pseudo-element to contribute to the size of the "parent" and absolute positioning is not an option for some reason:
#menu-main li a:after{
content: " * ";
display:inline-block; /* So we can set a width */
width: 0;
margin-left: 10px; /* "Size" of the Pseudo-element */
}
Since the width is 0, it does not display a text-decoration.
This also involves less code and less dependencies among your styles compared to the accepted answer.

In my case i don't even need the width, it just works adding inline-block.

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

Safari showing :after pseudo-element as if is :before

Safari is showing my :after pseudo-element as if is a :before
Chrome is showing it correctly, but Safari is not.
It is supposed to put a forward slash after every link on the navigation except the last one, but Safari is putting them before each one.
The css:
#site-header nav#main-nav #menu li:not(:last-child):after {
content: "/";
position: absolute;
margin-right: 7px;
line-height: 1;
bottom: 15px;
}
You CSS is overly complex. You just need to add the slash after before sibling of the original li. You don't need to use absolute positioning, and the :not pseudo class:
#menu li + li::before {
content: "/";
}
See this fiddle: http://jsfiddle.net/S93gy/
As an aside, you have incredibly specific selectors with multiple IDs and element selectors. This will make them very difficult to override if you ever need to. As an ID is unique, you in most cases just need to use that ID selector, rather than a long string before it such as #menu instead of #site-header nav#main-nav #menu

Why CSS selectors on links are tricky with underline with hover?

Here are two examples based on this HTML.
<a href="#">
<div class="foo">
hello
<span class="bar">world</span>
</div>
</a>
In the first one, I make the link not underline on hover, then make a sub-portion of the link underline, and that works fine:
a {
text-decoration:none;
}
a:hover {
text-decoration: none;
}
a:hover .bar {
text-decoration: underline;
}
http://jsfiddle.net/3qPyX/1/
In the second, I now reverse the selectors so that the second word should be un-underlined. However, now something strange happens. The entire link remains underlined even though the selectors seem like they should remove underline from the second word. <-- (this is the question. why does this happen?)
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
text-decoration: none;
}
http://jsfiddle.net/EAmwt/
Can someone explain what's going wrong in the second example? Inspecting with Chrome shows the span.bar has a computed style of text-decoration:none.
Update: a few answers explaining how to get around the problem, which is great except that's not really my question. What I want to know is why is this behavior different than, say, bold? For instance, if I try the 2nd example with bold, I get the expected results: http://jsfiddle.net/3qPyX/4/
Explanation:
The problem is that some properties (like text-decoration) get drawn to the whole parent inline element, whereas others - like font styling (that get inherited) - get overriden by the children properties.
Just for illustration: simmilarly, if you set a background color to a parent element it will paint the background of the parent ... and you would have to set another color to a child to lay it over (default - transparent - will still show the parent style through), but if you set font-weight at a child it will apply to the text inside the child element and override the parent settings.
You can find more detailed stuff on the text-decoration property in the CSS Level 2 and Level 3 Specifications.
A simple solution
withot changing the markup, you could just display .bar as inline-block.
Like so:
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
display:inline-block;
}
And the inline-block breaks out of the inline/text styling of the parent anchor element =) And you can then style it independently:
DEMO
When you do the text-decoration it is applied to the entire line at once. So the a:hover .bar doesn't cause any effect, because the underline is not being applied in the .bar but on the a.
Here is the specification: http://www.w3.org/TR/CSS21/text.html#lining-striking-props
UPDATE! (As #Cam suggested) :
You need the add in separate elements the parts of your text: http://jsfiddle.net/3qPyX/5/
The CSS:
.foo, a:hover .bar, a {
text-decoration:none;
}
a:hover .foo {
text-decoration: underline;
}

css: outrageous change in property when put inside this fieldset

My custom drop down menu has a really large change in top and bottom padding.
UPDATE Javascript, CSS & HTML included in fiddle [PHP removed]
First off, I didn't realise I could share a fiddle ^^
Pretty epic site.
I'ma keep debugging, but thought I'd post it here to see if anyone can spot where the problem is :)
In your fieldset css you are changing the line-height, which is also applied to the dropdown.
You have to set the line-height in the css for the dropdown:
.dropdown,
.dropdown li /* or whatever other selector is also needed */
{
line-height: 1em;
}
EDIT:
That seems to fit quite good:
.dropdown,
.dropdown li,
.dropdown span,
.dropdown a {
padding: 0;
line-height: 3em;
}

why does my css render wrong in IE?

You will notice the :hover CSS for the links in the main nav area (grey bar under logo) for the site testing.ksischool.com works fine in Firefox, but IE7 chops off the bottom few padding pixels. Why?
I assume you're talking about the top navigation; you're padding an inline element (the <a> tag). When placing padding on an inline element, horizontal padding will push against other elements, but vertical padding will just increase the size of the element without affecting the layout around it. Likely Firefox is rendering the boxes above the elements below them in the source, but for whatever reason IE is rendering them beneath, which is why you're seeing parts of the box disappear.
To fix the problem, float all of the links left (which essentially turns them into block elements). You'll need to adjust your markup elsewhere to make it work (likely have some clearing problems if you just float straightaway), but that should fix that specific IE issue.
Edited for more detail:
As mentioned above, vertical padding on an inline element doesn't behave the way you would expect (it increases the element's height, but because the padding doesn't interact with other page elements the inline element often overlaps things in odd ways). So to fix this, you somehow need to make the padded element (the <a> tag) have display: block. To keep everything on the same line, floating left is your best bet. Here's the markup and styling that I would use:
<style type="text/css">
.mainnav {
font-size: 1em;
color: #999;
list-style-type: none;
/* zoom triggers hasLayout on IE, ignored by others
Necessary for the clearfix */
zoom: 1;
}
.mainnav:after {
/* This lets the .mainnav auto-clear its floated contents */
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.mainnav li {
float: left;
margin: 0 2px;
/* Place background (disc image) here w/ appropriate padding */
}
.mainnav li.last {
background: none;
}
.mainnav a:link, .mainnav a:visited {
display: block;
color: #fff;
text-decoration: none;
padding: 1px 1px 2px;
border: solid 1px transparent;
}
.mainnav a:hover {
color: #fff;
background: #999;
text-decoration: none;
padding: 1px 1px 2px;
border: solid 1px #ccc;
}
.mainnav a.selected, .mainnav a.selected:hover {
color: #B59B24;
background: transparent;
text-decoration: none;
}
</style>
<ul class="mainnav">
<li><a href="/" class='selected'>Home</a></li>
<li><a href="/About" >About</a></li>
<li><a href="/Admissions" >Admissions</a></li>
<li><a href="/Curriculum" >Curriculum</a></li>
<li><a href="/Home/VacancyList" >Careers</a></li>
<li class="last"><a href="/Contact" >Contact</a></li>
</ul>
Some things to note: I'm using a standard clearfix (Google this if you don't know what I'm talking about) to make sure the UL clears its floated contents. This will allow the parent nav elements to grow in size appropriately if the user sizes up their font.
Also, I removed the spacer · and recommend using a background image and .last class in the CSS. This is purely personal preference. (In an ideal world, you'd use the :after pseudo-class to inject the ·, but thanks to IE 6 not supporting it you can't do that and support all browsers.) My reason for recommending a background image rather than just leaving it in the markup is that it leads to cleaner markup and is far easier to change down the road (if your client decided they wanted a pipe rather than a dot, say).
The logic behind this markup/styling is that you need padding on the <a> for the border/background color to work which means it has to have display: block. Adding that would stick every link on a different line, though, so you need to float either it or its parent. Since it's part of a list, it's easier to float the li parent and use a clearfix to make sure the ul still has some presence on the page.
Obviously if you use this code you'll need to remove most of the #nav_banner element things lower down in the stylesheet, and you'll likely need to debug cross-browser again. Even if you don't, hopefully it will provide you with some ideas for easily constructing top navigation in the future.
Try adding display: inline-block to the a element. I'm not sure how compatible that is, but it works in IE7 and FF.
edit: One Crayon's solution is definitely better and the more common way of doing it.

Resources