24

I am using Bootstrap 3 and I have a table showing some data. in this table I have applied some JavaScript for conditional formatting, in the event that a condition is met, I set the element's class to "red"

.red {
background-color:red;
color:white;
}

the elements HTML is as follows:

<td class="red">0</td>

I now have a conflict on odd rows the text color applies but the background color is overridden by the following css from bootstrap.

.table-striped > tbody > tr:nth-child(odd) > td,
.table-striped > tbody > tr:nth-child(odd) > th {
  background-color: #f9f9f9;
}

how can I resolve this conflict and assure that the red class takes presedence?

0

7 Answers 7

52

Specificity

Your issue is most likely regarding specificity. Chris Coyier has a great article on CSS specificity. I would also suggest you check out this handy specificity calculator.

Using that calculator, we can see that .table-striped > tbody > tr:nth-child(odd) > td has a specificity of 23. As such, to override that, any new rule needs to have a specificity of something equal to or greater than 23. .red is at 10, so that isn't going to cut it.

In this case, it should be as simple as matching the existing specificity, and then adding your class to it. .table-striped > tbody > tr:nth-child(odd) > td.red gives us a specificity of 33. As 33 is greater than 23, your rule should now work.

See a working example here: http://bootply.com/91756

!important

In general, you should never use !important unless you never want that rule to be overridden. !important is basically the nuclear option. I am moderately confident in saying that if you understand specificity, you should never need to !important to make a custom rule work properly in a framework like Bootstrap.

Update

After a bit of thought, the rule I provide here is probably a bit too specific. What happens if you want to higlight a cell on a table that isn't stripped? To make your rule a bit more global while still having enough specificity to work in stripped tables, I would go with .table > tbody > tr > td.red. This has the same specificity as the Bootstrap stripping, but will also work on tables that are not zebra stripped. Updated example is here: http://bootply.com/91760

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this really great answer. What every Bootstrap developer needs to know.
5

Firstly, read Sean Ryan's answer - it is very good and informative, but I had to tweak his answer enough before implementing in my code that I wanted have a distinct answer that might help the next person.

I had almost the same question as the OP but also needed to be able to highlight the row, too. Below is how I enhanced(?) Sean Ryan's answer and turned it into my final implementation, which allows you to add a class to most any random element, including to a "tr" or a "td"

See this on bootply.com

CSS

    /* enable 'highlight' to be applied to most anything, including <tr> & <td>, including bootstrap's aggressive 'table-stripe'
see: http://stackoverflow.com/questions/19768794/custom-css-being-overridden-by-bootstrap-css

FYI: In the stack overflow question, the class is 'red' instead of 'highlight'
FYI: This is forked from http://www.bootply.com/91756

I used three different colors here for illustration, but we'd
likely want them to all be the same color.
*/

.highlight {
    background-color: lightyellow;
}


/* supersede bootstrap at the row level by being annoyingly specific 
*/
.table-striped > tbody > tr:nth-child(odd).highlight > td {
    background-color: pink;
}

/* supersede bootstrap at the cell level by being annoyingly specific */
.table-striped > tbody > tr:nth-child(odd) > td.highlight {
    background-color:lightgreen;
}

HTML

<table class="table table-striped">
    <thead>
        <tr>
            <th>Col 1</th>
            <th>Col 2</th>
            <th>Col 3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1hi</td>
            <td>hi</td>
            <td>hi</td>
        </tr>
        <tr class="highlight">
            <td>2hi</td>
            <td>This row highlights fine since it was an even row to begin with, and therefore not highlighted by bootstrap</td>
            <td>hi</td>
        </tr>
        <tr class="highlight">
            <td>3hi</td>
          <td>This whole row should be highlighted.</td>
            <td>hi</td>
        </tr>
        <tr>
            <td>4hi</td>
            <td>hi</td>
            <td>hi</td>
        </tr><tr>
            <td>5hi</td>
            <td class="highlight">Just a specific cell to be highlighted</td>
            <td>hi</td>
        </tr>
    </tbody>
</table>

Comments

3

Use

.table-striped > tbody > tr:nth-child(odd) > td.red {
    background-color:red;
    color:white;
}

to create more specific selector, or the !important keyword (as shown by Andrew)

Alternitvaly, and probably best, you can create a custom bootstrap configuration, which not includes table styling (Uncheck Tables in Common CSS)

Comments

1

You can add !important after each style in the .red class. Adding !important basically will give the CSS more weight which allows you to override other styles.

Your css would look like:

.red {
    background-color: red !important;
    color: white !important;
}

3 Comments

Despite all admonishments, I tried applying this solution and it still did not override bootstrap's striping. YMMV
@JJRohrer Why the downvote when two other people also suggested !important. !important does work, but if you are trying to add styles to random elements then my answer may not apply to you because that is not what the original question was asking.
you were right, (I've reversed the vote). I missed thAT OP only wanted to highlight a cell, and not a whole row. This bootly demonstrates how !important will highlight the cell when attached to td, but fails to highlight the row when attached to tr. bootply.com/c1bQH6iLNo
1

You need to apply !important after class style. because we use the selector is .table-striped > tbody > tr:nth-child(odd) > td, which is more specific than the class rule and will take precedence. So you need to override this with !important.

But there are two ways to fix this:

  1. Use !important to make a rule more "important". I'd avoid doing this because it is confusing when you have lots of rules spread out over several files.

  2. Use a higher-specifity selector for the td you want to modify. You can add an id and this will allow you to supersede the rule from the linked CSS file.

Read css Precedence

Comments

0

You can apply a value of !important after the value you want to take precedence.

Comments

0

I had a similar problem, also after using !important the problem stayed.

The problem depends on which browser we are using, in my case it was Chrome. Normally chrome stores frequently used sites and does not always fully page reload.

The issue was solved only after clearing the chrome history or Ctrl+Shift+R.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.