While the container and link colors for contextual links is well defined, the contextual links have specific selectors like "div.contextual-links-wrapper ul.contextual-links", which are hardly ever overwritten by accidental CSS declarations. However, the actual link color has "ul.contextual-links li a", which is easily overwritten by more specific link color specifications. In my case, those would be simple "#footer a" or "#header a", which by the virtue of ID selectors overwrite the class selectors used in contextual.css.

The effect is that because I have white colors in the header, the links in the contextual menu will be white as well:

If we make the link color important to sidestep this specificity problem, the links colors will be right, and I can use the contextual menu again.

It's a very simple patch.

Comments

gábor hojtsy’s picture

Another option could be to add classes to the links inside the ul.contextual-links, so we can improve the specificity of these selectors. I did not try that. (The links already have plenty of classes but none of which is on all of them).

David_Rothstein’s picture

Component: base system » contextual.module
robloach’s picture

StatusFileSize
new690 bytes

It is usually not recommended and bad practice to use !important. It's also not implemented in IE7. A way around it is to add more selectors for the overriding property, or remove some not needed selectors on the original CSS definition.

Here's an attached patch that removes some selectors on the original property that we don't really need so that the overriding property take precedence. This means that themes don't need to drill down as deep as four selectors to override the property.

dries’s picture

Would be great if Gabor could test Rob's patch.

gábor hojtsy’s picture

Status: Needs review » Needs work

Rob did you try adding #footer a { color: #fff; } into your theme and place a block in the footer? The problem is that #footer a is already more specific then the contextual.css selectors, so making those selectors less specific does not sound right.

You seem to be advocating that themes fix this specificity problem, but why would they need to if we can provide more sensible defaults? As I've said, we could add one more class on all links and try to make the selector more specific with that.

gábor hojtsy’s picture

Rob?

ejort’s picture

I think the original approach from Gábor was correct. We want the contextual link styles to not be overridden in a way that makes the interface unusable in situations as common as adding a style such as #footer a { color: #fff; }.

While I agree that !importantis generally evil, I think this is a valid use case. The !important declaration in the original patch should also work as expected in IE7 (and even IE6, its bugs with !importantdon't stop the rule taking effect in simple cases like this). It's also still possible to override an !important style declaration from a theme by providing your own !importantstyle declaration with a higher specificity (for those who want to opt in to overriding these styles).

robloach’s picture

Status: Needs work » Needs review
StatusFileSize
new103.81 KB

Okay, I have a better understanding now. The problem is that it is too easily over-ridable by the theme. It was the opposite direction that I thought it was going. If we add another selector to the contextual.css definition, then that one will take precedence over other definitions that have three or less selectors in it and we can avoid !important.

Thanks all!

robloach’s picture

StatusFileSize
new749 bytes

Whoops, created the patch incorrectly. Haven't had coffee yet.

ejort’s picture

Hi Rob,

Unfortunately the last patch still doesn't fix the given problem with a selector such as #footer a { color: #fff; } (which is a common example). The specificity of a CSS selector is calculated as: (number of elements) * 1 + (number of classes) * 10 + (number of ids) * 100.

So, .contextual-links-wrapper ul.contextual-links li a has a specificity of 23, while #footer a has a specificity of 101.

We'd need to add 10 extra classes to the selector to equal the specificity provided by a single id. For this reason, and because it is undesirable to accidentally restyle these links I think !important is justified in this case. It can still be overridden easily by theme's if they want to, but protects against accidentally overriding the style and forcing theme developers to redeclare the contextual links styles throughout their themes.

gábor hojtsy’s picture

@ejort: does this mean RTBC for the first patch?

ejort’s picture

A short comment on the reason we're using !important in this place would be good as it can be a bit of a developer WTF. But other than that I think this is RTBC.

robloach’s picture

StatusFileSize
new591 bytes

That's a shame. I didn't know identifiers had such importance in the cascade. I thought it was just based on the number of selectors, but it seems I was wrong. Do you have any more information, or a link on how the weighting is made? Thanks!

gábor hojtsy’s picture

StatusFileSize
new678 bytes

Here is a version with a code comment as dicussed. It would be good to wrap this up and get it in :) We have bigger fish to fry.

robloach’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +D7TX

Works with me! It's unfortunate that we have to have !important CSS in Drupal core, but if it helps the Drupal 7 Themer Experience, then I'm alright with that.... #D7TX? ;-)

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

xmacinfo’s picture

Status: Fixed » Needs work

It's unfortunate that we have to have !important CSS in Drupal core...

Oh my, this is the first instance I see where we really need to set !important either in Drupal core or any theme I do. :-)

Adding an ID to each "contextual-links-wrapper", like we do for blocks, would make things harder.

xmacinfo’s picture

Status: Needs work » Fixed

oups

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

sun’s picture

Status: Closed (fixed) » Active

#730754: CSS coding standards: No !important in core/contrib modules, ONLY IN THEMES

So we've put an !important into core, just because someone wrote a buggy theme, which doesn't support the modules being installed?

eclipsegc’s picture

Yes this definitely looks like it's the responsibility of the theme, not the module. Set it back, the theme author should just have a #footer ul.contextual-links li a {} selector in his css file, or better yet a #page ul.contextual-links li a {} selector that will overwrite ALL of these links.

#page ul.contextual-links li a has a specificity of 1,1,3
vs
#footer a of 1,0,1

So the first will win for ALL contextual-links in the entire system at ALL times unless someone does something more specific (which is unlikely).

Eclipse

jacine’s picture

Yeah, EclipseGc is right. There are a few ways to resolve this, and it belongs in the theme.

gábor hojtsy’s picture

I'm glad people with better ideas came around. Patches are welcome :)

barraponto’s picture

@EclipseGc: please don't. You can't rely that #page will be there in the first place, the theme can override that (although they could re-implement this declaration, but what if we apply this approach elsewhere?). We can't use #identifiers for the links since they wouldn't be unique, so I guess we are doomed.

Sanity check: why are we using #footer id in the first place? I know it is unique within the scope of the document, but it would make more sense to preserve ids for things like #node-1234, where I might use it to override the default .node properties.

So I guess this would be: #page .selector for D7, rethink the usage of ids for D8. Also, RobLoach approach is right: if the selector is not needed, remove it. In the end, they should look like:

.contextual-links a {
...
.contextual-links a:hover {

I have just read the CSS Code Standards http://drupal.org/node/302199 and there's nothing about "removing unnecessary weight". So I don't know whether I should patch for that, even though the CSS file uses .contextual-links or ul.contextual-links randomly.

barraponto’s picture

Issue tags: -DTX

typo.

barraponto’s picture

Issue tags: +DTX

Adding DTX to avoid remember this bug even if it lingers until D8.

  • Dries committed dfb6710 on 8.3.x
    - Patch #675608 by Rob Loach, Gábor Hojtsy: fixed contextual link colors...

  • Dries committed dfb6710 on 8.3.x
    - Patch #675608 by Rob Loach, Gábor Hojtsy: fixed contextual link colors...

  • Dries committed dfb6710 on 8.4.x
    - Patch #675608 by Rob Loach, Gábor Hojtsy: fixed contextual link colors...

  • Dries committed dfb6710 on 8.4.x
    - Patch #675608 by Rob Loach, Gábor Hojtsy: fixed contextual link colors...

  • Dries committed dfb6710 on 9.1.x
    - Patch #675608 by Rob Loach, Gábor Hojtsy: fixed contextual link colors...

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.