1

How can I write this code more effectively? I don´t want to write .btn:hover every time.

.btn:hover .glyphicon-minus,
.btn:hover .glyphicon-ok,
.btn:hover .glyphicon-remove,
.btn:hover .glyphicon-trash,
.btn:hover .glyphicon-arrow-left,
.btn:hover .glyphicon-arrow-right,
.btn:hover .glyphicon-eye-open,
.btn:hover .glyphicon-floppy-disk,
.btn:hover .glyphicon-print
.btn:hover .glyphicon-pencil{
 color: black !important;
}
Johannes
  • 64,305
  • 18
  • 73
  • 130
  • If you have a lot of `.glyphicon-*` classes and you wants to style a few of them differently, I would suggest you to add a class on desired elements and override styles in CSS. – Mohammad Usman Jan 05 '18 at 13:32
  • If you want `.glyphicon-*` classes to match, you should consider the answer of @AndreiGheorghiu below.. But if it's more complex and you only want to match specific classes, I think you should use SASS/LESS instead. But if you don't want to use SASS/LESS, I suggesst you add an additional class to your elements and then match that class instead, i.e `.btn:hover .hover-black`? – xGeo Jan 05 '18 at 13:43
  • @Geoman, I wanted to add a small consideration about your suggestion of using SASS. While I recommend ***everyone*** to use SASS at all times, I feel it's not a decision you make based on whether or not you have a case like the above. Anyway, my *"small"* consideration got so fat I had to add it as a note to the answer. Best regards and happy coding! – tao Jan 05 '18 at 14:31

5 Answers5

3
.btn:hover [class*='glyphicon-'] {...}

... matches all elements children of .btn:hover that contain glyphicon- inside their class attribute. If they are always immediate children, you should use the direct descendant operator:

.btn:hover > [class*='glyphicon-'] {...}

... so it doesn't apply when .glyphicon-* is not immediate child of .btn.


Note: (@Paulie_D) In principle and for the general case, this is safer than using [class^="glyphicon-"], because when the matched children have more than one class and the one being matched is not the first, the selector won't match. For example:

<a class="btn"><i class="glyphicon glyphicon-floppy-disk"></i>Old devices</a>

Note: (@GeomanYabes, on the suggestion to use SASS). Using SASS (or not) usually has to do with the stack of the team/company you work in, with personal choice as a developer or with project/client requirements rather than with writing less code in a particular case in a particular project (like the one above). I mean you don't choose to use SASS if you have a case like the above and drop it if you don't. The decision is based on larger considerations and taken regardless. As a rule of thumb I tell everyone: if you write CSS, do use SASS. Getting back to your suggestion and the question, please note SASS produces CSS and that CSS is not necessarily more efficient, which is what OP seems to ask for, intentional or not.
In terms of efficiency, such as rendering speed and browser performance, I must say I'm really not sure which code is more efficient between the two (specifying each case or a pattern). I'm assuming a pattern should be a little heavier on the parser and the extra weight might not justify the characters saved by the shorter syntax.
In any case, the differences are so tiny they don't really matter in like 99,99% of cases. Regardless, if you decide to pursue this issue, I'm genuinely interested in any results/tests. Let's just say I choose to regard CSS more like a hobby than a job, which is the opposite of how I feel about JavaScript these days.
If efficiency is measured in characters typed, I guess the pattern wins. If it's measured in time spent to code, it varies from person to person and has more to do with knowledge than syntax.

tao
  • 82,996
  • 16
  • 114
  • 150
  • This assumes that OP wanted to match all `.glyphicon-*` classes which I think is not the case since OP iterated all classes he wanted to match in his question. – xGeo Jan 05 '18 at 13:44
  • @Geoman, I think it's a perfectly valid assumption, since they did not specify in their question there are other classes with the same pattern than need not to be matched. I formatted my answer disregarding the specific library being used, but for the more general case of `parent [childPattern]` which, from my POV, is a more likely interpretation of the question being asked. If they wanted to exclude any classes they'd have added the markup and specified: *This needs to be excluded. How do I do it?* – tao Jan 05 '18 at 13:47
  • @Geoman, nonetheless, if you feel the question is lacking specificity and needs clarifications, you should ask for them commenting on the question itself. Overall, I think my answer has a proper chance at helping many other users, besides OP, optimize their CSS and I think that's the biggest benefit of this question + provided answers. – tao Jan 05 '18 at 13:55
3

Try:

.btn:hover [class^="glyphicon-"]

This targets all classes that start with glyphicon-

The carat symbol. It's most commonly used in regular expressions to designate the beginning of a string.

The 30 CSS Selectors You Must Memorize

Community
  • 1
  • 1
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
1

You can use LESS or SASS for that. It allows you to nest classes/tags/IDs and other selectors inside each other. With that you could write

.btn:hover {
  .glyphicon-minus,
  .glyphicon-ok,
  .glyphicon-remove,
  .glyphicon-trash,
  .glyphicon-arrow-left,
  .glyphicon-arrow-right,
  .glyphicon-eye-open,
  .glyphicon-floppy-disk,
  .glyphicon-print,
  .glyphicon-pencil {
    color: black !important;
  }
}
Johannes
  • 64,305
  • 18
  • 73
  • 130
1

The answers recommending CSS Regex will definitely solve your problem if you don't need to be selective about which glyphicons are being impacted.

In the event you need it to be specific though, unfortunately CSS' limitation stops there and you should consider looking into a preprocessor like Sass or a postprocessor like PostCSS to help with inefficient coding time.

.btn:hover {
     .glyphicon {
        &-minus,
        &-ok,
        &-remove,
        &-trash,
        &-arrow-left,
        &-arrow-right,
        &-eye-open,
        &-floppy-disk,
        &-print
        &-pencil {
            color: black !important;
        }
    }
}

Would give you the same output if you were using Sass.

bencodezen
  • 1,023
  • 7
  • 17
0

try .btn:hover:matches(.glyphicon-minus, .glyphicon-ok, .glyphicon-remove, .glyphicon-trash, .glyphicon-arrow-left, .glyphicon-arrow-right, .glyphicon-eye-open, .glyphicon-floppy-disk, .glyphicon-print .glyphicon-pencil) {/*your css*/}

Bariq Dharmawan
  • 755
  • 4
  • 16
  • 26