2

I have browsed several topics about the CSS inheritance but no one gave me an answer to a specific use case which is producing an unwanted behavior.

Reproduction of the problem with a simple example

<html>
    <head>
        <style>
        #content a { color:red; }   /* Theme selector (unmodifiable) */
        a.child { color:blue; }     /* Plugin selector */
        </style>
    </head>
    <body>
        <div id="content">
            <a class="child" href="http://www.stackoverflow.com">
            stackoverflow
            </a>
            <a class="child" href="http://www.stackoverflow.com">
            stackoverflow
            </a>
        </div>
    </body>
</html>

As you know, the ID is more prior than the CLASS, so the second rule is ignored.


Description of the real use case issue

Unfortunately, I have encountered this inheritance problem in a more complex use case, which includes WordPress CMS.

Indeed, WordPress contains a functionality called a theme. A theme is a kind of package which the developer is not very likely to modify. Besides, WordPress CMS contains plugins that are pluggable on the theme.

Let's imagine the CSS rules #content a is defined in the theme StyleSheet and cannot be modified (I don't want to change the style of the theme and change #content for .content for example...). Then, the second rule a.child is defined on my plug-in, which is, in contrary to the previous rule, modifiable.

In other words, the problem is the following:

  • I want to override the first rule #content a by applying a style to the <a class="child"> element with a clever selector. The real question is whether we will manage to find, together, a workaround to break the ID priority.

I definitely do not want to use :

  • Hacky solutions (like !important)
  • #content selector on the overriding child selector, which will totally break the modularity of my plugin. Indeed, the following selector works but its usage is totally unthinkable in my code : #content a.child { color:blue; }

I'm sorry for the complexity of my use case, but please, help to find a solution

Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
  • how does `#content a.child { color:blue; }` break the modularity in your code? – AmmarCSE Jun 26 '15 at 18:51
  • @AmmarCSE: It creates a dependency on there being an element with ID `#content` in the host HTML, which is something a plugin shouldn't have to care about. – BoltClock Jun 26 '15 at 18:53
  • @BoltClock, I see, but then whats wrong with `#content a.child, a.child`? – AmmarCSE Jun 26 '15 at 18:54
  • @AmmarCSE: How would you account for every other possible ID? There is no generic ID selector. And you can't assume the most specific rule targeting that element would only contain one ID and one class selector either. – BoltClock Jun 26 '15 at 18:59
  • 1
    Having worked with styling WordPress themes before, I feel your pain. The problem stems from the original author styling the element based on the ID in the first place. I've almost always had to resort to using `!important` to get around these types of issues. – Jeff Clarke Jun 26 '15 at 19:06
  • You could add an inline CSS style, which will override the ID priority, but that leaves your plugin not styleable from an external CSS stylesheet. – Jeff Clarke Jun 26 '15 at 19:14
  • @AmmarCSE In some words, put `#content` in the child selector involve to create a dependency to an element of the theme... If the plug-in contains this kind of selector, and tomorrow I have to migrate to another theme, I'm not sure to have a theme with a `#content` div. Indeed, the `#content` is not a standard wrapper name on a theme... – Pablo PRUDHOMMEAU Jun 26 '15 at 19:14
  • @PabloPrh, good example. Thanks – AmmarCSE Jun 26 '15 at 19:16
  • CSS-Tricks post on use of [the `!important` rule](https://css-tricks.com/when-using-important-is-the-right-choice/). – Joseph Marikle Jun 26 '15 at 19:35

1 Answers1

4

I know you said no !important, but the below code would limit its use to if the parent container has an id. I too have experienced this problem when styling CMS themed sites.

#content a { color:red; }   /* Theme selector (unmodifiable) */
a.child { color:blue; }     /* Plugin selector */

[id] > a.child { color: blue !important; }
<div id="content">
    <a class="child" href="http://www.stackoverflow.com">
        stackoverflow
    </a>
    <a class="child" href="http://www.stackoverflow.com">
        stackoverflow
    </a>
</div>
Jacob
  • 2,212
  • 1
  • 12
  • 18