Proposal: use the `!important` CSS syntax for the `.force-underline`

Context

Since Loading... was merged in 16.3.0-rc1, the links in XWiki follow a more complex set of rules to determine whether they should be underlined:

  • Does the link have a .force-underline or .force-no-underline class?
  • What is the preference on the user side?
  • What is the default for this preference set by the wiki admin?
  • What is the default behaviour in the current Skin?

All of these come with their own CSS in XWiki Standard to manage the underlining of every link in different situations…

On the other hand, we have a codestyle that does not allow us to use the !important CSS keyword:
https://dev.xwiki.org/xwiki/bin/view/Community/CodeStyle/XhtmlCssCodeStyle/#HCSS

Problem

It’s pretty clear from their names, the .force-underline and .force-no-underline classes are expected to have priority over every other configuration on the wiki. This is supposed to be a convenient class for XWiki devs (mostly custom, XS devs should be able to rely on standard rules) to bypass this new parameter and force the underlining state of a link they use in their UI.

However, in practice, this class is not foolproof. E.g. when proposing a change to the recently, I realized it wouldn’t act as expected and I needed to update it so that it would “win” the priority comparison with some other CSS rules: XWIKI-23813: Link missing contrast in search result page by Sereza7 · Pull Request #4933 · xwiki/xwiki-platform · GitHub

Solutions

  1. Workaround the fact that we can’t have a “forced” style and just give a very high priority artificially to the style we want to force. This is the solution I went with by default when proposing my solution for XWIKI-23813: XWIKI-23813: Link missing contrast in search result page by Sereza7 · Pull Request #4933 · xwiki/xwiki-platform · GitHub
  2. Agree together to break the codestyle and use the !important CSS syntax here.

Explanation

I went with 1. first because this is pretty much how I implemented the class to work from the start in 16.3.0 . AFAIK, the rule of thumb for !important is “if you need it, it means that you’re doing something wrong in your CSS”. But I passed on this situtation quite a few times and I still can’t find a perfect solution without it. The existing solution kind of works but it’s not future-proof. AFAIU, we do need those “force” CSS classes for XWiki customizations/extension devs, there’s no way around it.
It seems to me like this is one of the rare cases where using !important is the choice that ends up creating the least tech debt. In addition, it matches very well the name/semantics of the class.

AFAIU, from an outsider’s point of view, the “error” we do here is to try to tie strongly a CSS style to an HTML class. This just blocks off the CSS cascade. But again, I don’t know how we could give devs a link by link control on how the link decoration is rendered. Technically, they shouldn’t need this, but:

  • our “inline link” selector is not perfect
  • in some situations, the theorical “best accessibility” choice does not work (e.g. the breadcrumb is a pretty clear example of inline links that we don’t need or want to underline).

Proposal

Use the !important CSS syntax for the .force-underline and .force-no-underline classes in XS (with a comment pointing to this discussion).

Conclusion

Here’s my +1 to this proposal.
Thank you to @surli for highlighting this problem :slight_smile:
@mflorea Do you see another solution to this situation that I did not find? Do you think it’d be worth voting in another topic for an update to the codestyle to allow an exception such as this one?

Thank you for your interest in the topic!
Lucas C.

I’ll close this topic in a week from now, on 2026-03-09T23:00:00Z .

+1 thanks

So the workaround is to put the force-underline CSS class on a container of the link as well? This is not nice. The code that generates the link (e.g. a UI extension) might not have access to the parent / ancestor element and might not be allowed to wrap the generated link in another element. In any case, it doesn’t feel right to have to “duplicate” the force-underline class.

I think !important makes sense here because the CSS selector needs to remain generic so that it can be used in different contexts. And if you can’t raise the priority through the selector (by making it more specific) then you’re left with the !important modifier. And, as you said, it matches the semantics of its naming. So +1 on my side as well.

Yes, I think we need to list some exceptions to the rule. One exception is for the use case we have here: a generic CSS class whose purpose is to force some styling (which cannot be forced otherwise than by using the !important modifier).

Thanks,
Marius

1 Like

Thank you for your feedback!
Closing the topic and taking the actions:

  • Update the codestyle to add the exception
  • Update the PR to use !important in the agreed place.