Select most inner of equivalent rules in CSS - css

In bootstrap there is this mixin that creates various background color classes.
I modified it to also change the text color automatically. Since this change is only applied to the same element that has the class, I added that huge selector that selects all headings and paragraphs within the parent class to fix the color.
#mixin bg-variant($parent, $color) {
#{$parent} {
background: $color !important;
color: color-yiq($color);
p, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, .display-1, .display-2, .display-3 {
&:not(.input-group-text) {
color: color-yiq($color);
}
}
}
}
There is a second mixin, but for gradients, called bg-gradient-variant.
But there is a problem when I have the following code structure:
<div class="bg-gradient-success">
<div class="bg-secondary">
<p>Some text</p>
</div>
</div>
The paragraph gets the color of bg-gradient-success, instead of bg-secondary, because the gradient mixin is defined after the normal mixin. Changing this order fixes this case but breaks others. Is there a way to automatically increase specificity in the inner class (not a hacky one use way) to make the color appropriate to the most inner class?

Related

Change colour of elements inside an Elementor container on hover

Please see this website: https://reasone29.sg-host.com/
The three boxes on the hero section, e.g. 'Full Conversion Packages', I want to change the colour of the elements (text and the button) when you hover over the container.
I can do CSS that changes the colour of the element when you hover over it directly, but I want it so all the elements change at the same time when you hover over the container and it turns blue.
I've tried various CSS codes but had no luck.
Thanks in advance.
Various CSS codes but no results:
.elementor-container:hover .elementor-element h1,
.elementor-container:hover .elementor-element h2,
.elementor-container:hover .elementor-element h3,
.elementor-container:hover .elementor-element h4,
.elementor-container:hover .elementor-element h5,
.elementor-container:hover .elementor-element h6 {
color: #ff0000 !important;
}
.elementor-container:hover .elementor-element h1,
.elementor-container:hover .elementor-element h2 {
color: #ff0000 !important;
I also tried the selector for the headings but still no luck.
I'm not sure as to what you want to achieve because the hex-code you're using in your code is red and not blue, as you indicated.
Either way, you can use IDs to make this work. Use the ID "opt-container" on the container that holds all 3 boxes and then the ID "opt-btn" on all 3 button elements. Then use the code below and this should make the text of all 3 boxes red and the button too, while the text color of the button remains white :)
Hover effect applies to all 3 boxes at once
#opt-container:hover h3,
#opt-container:hover h6
{
color: #ff0000;
}
#opt-container:hover #opt-btn
{
background-color: #ff0000;
border-color: #ff0000;
color: #fff;
}
If you want the entire box to change color on hover then you add the ID "opt-box" to each of the 3 containers and use the code below:
#opt-container:hover #opt-box
{
background-color: #26ABE2;
}
Hover effect applies to each box, individually
(In response to your comment:)
Use the 3 different IDs (classes would probably work too) for your boxes and call them "opt-box-1" "opt-box-2" and "opt-box-3". Also add the IDs (or classes) "opt-btn-1" "opt-btn-2" and "opt-btn-3". on the 3 button elements. Then use the code below to change the background on hover:
#opt-box-1:hover,
#opt-box-2:hover,
#opt-box-3:hover
{
background-color: #26ABE2;
}
The code below changes the font color (h3 and h6) on hover:
#opt-box-1:hover h3,
#opt-box-1:hover h6,
#opt-box-2:hover h3,
#opt-box-2:hover h6,
#opt-box-3:hover h3,
#opt-box-3:hover h6
{
color: #ff0000;
}

How to set a global/default font-family without universal selectors?

I am in a conundrum: the stylelint rule "selector-max-universal": 0 is required and, at the same time, I need to provide a default font family to text elements within a certain class.
Therefore I am not able to use this:
* { font-family: Somefont; }
And, at the same time, code review requested me not to use these kind of selectors (SCSS mixin):
#mixin setGlobalFontFamily($family: Somefont) {
button,
div,
h1,
h2,
h3,
h4,
h5,
h6,
label,
p {
font-family: $family, sans-serif;
}
}
// fonts are specific to certain classes
.theme-a {
#include setGlobalFontFamily;
}
.theme-b {
#include setGlobalFontFamily(Roboto);
}
//.theme-...
Theme classes are conditionally applied through JS to a container element, e.g.:
<body>
<section class="theme-b">
</section>
</body>
Additionnaly, these fonts families should be set globally in one file and only once per each theme class, guaranteeing that other theme font families are not shown...
Can anyone see a way to workaround this problem?
If I understood correctly you can just set the font families directly to .theme-a and .theme-b e.g.:
.theme-a {
font-family: 'Some Font', sans-serif;
}
.theme-b {
font-family: 'Roboto', sans-serif;
}
The children of those elements should inherit the fonts automatically if something doesn't overwrite them. There's no need of setting each element manually.

Font-Awesome not displaying

I have checked and checked and I'm sure it's something simple I've overlooked but my font is not displaying.
The first paragraph is suppose to have quotes around it (you will see it has them right now because I did it without font-awesome); however, you will see the second full paragraph is suppose to have a quote at the beginning and it's not displaying. Please help
http://dev.healthcaresolutionsteam.com/agent/barbara-scott/
Your CSS specificity is being overridden by a style in style.css.
Font-Awesome only has:
.fa { font-family: FontAwesome }
Yet your style overrides the font-family (note the !important):
#fake, .menu, a.signin span, .balloon_text, #footer, #footer a, #signin_menu p a, #learning_center h2, #hst_blog h2, #carriers h2, #career_center h2, #learning_center, #hst_blog, #carrier_careers, .entry-title, #sidebar, #sidebar a, .breadcrumbs a, .breadcrumbs, #searchform input, .page-title, .entry-content, .entry-content a, .entry-utility, .read_more, #content h1, #content h2, #content h3, #content h4, #content h5, #content h6, .widget-title, #live_chat a, #hst_careers, #apply_online, #sales_revenue, #hst_compensation, #search_agents, #search_map, .agent_search, #search-results, #usca-intro-text, .usca-plan, #usca-form {
font-family: 'AllerRegular',Arial,Helvetica,sans-serif !important;
font-weight: normal;
}
Desired style being overridden:
Style actually being applied:
Check, if you use selector *
*{font-family: Arial}
in your default stylesheet.

Can I target all <H> tags with a single selector?

I'd like to target all h tags on a page. I know you can do it this way...
h1,
h2,
h3,
h4,
h5,
h6 {
font: 32px/42px trajan-pro-1,trajan-pro-2;
}
but is there a more efficient way of doing this using advanced CSS selectors? e.g something like:
[att^=h] {
font: 32px/42px trajan-pro-1,trajan-pro-2;
}
(but obviously this doesn't work)
No, a comma-separated list is what you want in this case.
If you're using SASS you could also use this mixin:
#mixin headings {
h1, h2, h3,
h4, h5, h6 {
#content;
}
}
Use it like so:
#include headings {
font: 32px/42px trajan-pro-1, trajan-pro-2;
}
Edit: My personal favourite way of doing this by optionally extending a placeholder selector on each of the heading elements.
h1, h2, h3,
h4, h5, h6 {
#extend %headings !optional;
}
Then I can target all headings like I would target any single class, for example:
.element > %headings {
color: red;
}
It's not basic css, but if you're using LESS (http://lesscss.org), you can do this using recursion:
.hClass (#index) when (#index > 0) {
h#{index} {
font: 32px/42px trajan-pro-1,trajan-pro-2;
}
.hClass(#index - 1);
}
.hClass(6);
Sass (http://sass-lang.com) will allow you to manage this, but won't allow recursion; they have #for syntax for these instances:
#for $index from 1 through 6 {
h#{$index}{
font: 32px/42px trajan-pro-1,trajan-pro-2;
}
}
If you're not using a dynamic language that compiles to CSS like LESS or Sass, you should definitely check out one of these options. They can really simplify and make more dynamic your CSS development.
The new :is() CSS pseudo-class can do it in one selector.
For example, here's how you could target all headings inside a container element:
.container :is(h1, h2, h3, h4, h5, h6)
{
color: red;
}
Most browsers now support :is(), but keep in mind that most browsers made before 2020 didn't support it without a prefix, so be careful about using this if you need to support older browsers.
In some cases, you may instead want to use the :where() pseudo-class, which is very similar to :is() but has different specificity rules.
SCSS+Compass makes this a snap, since we're talking about pre-processors.
#{headings(1,5)} {
//definitions
}
You can learn about all the Compass helper selectors here:
Here is my attempt to solve this problem with (modern) CSS only.
Context : Inside of Joplin (very nice note taking app, link), there is an userfile.css in which you can write your custom CSS for display and export of markdown notes.
I wanted to target all headings directly after (adjacent sibling) certain tags, namely p, ul, ol and nav to add a margin in between. Thus :
p + h1,
p + h2,
p + h3,
p + h4,
p + h5,
p + h6,
ul + h1,
ul + h2,
ul + h3,
ul + h4,
ul + h5,
ul + h6,
ol + h1,
ol + h2,
ol + h3,
ol + h4,
ol + h5,
ol + h6,
nav + h1,
nav + h2,
nav + h3,
nav + h4,
nav + h5,
nav + h6 {
margin-top: 2em;
}
WOW. Very long. Such selectors.
I then came here, learnt, and tried :
p + :is(h1, h2, h3, h4, h5, h6),
ul + :is(h1, h2, h3, h4, h5, h6),
ol + :is(h1, h2, h3, h4, h5, h6),
nav + :is(h1, h2, h3, h4, h5, h6) {
margin-top: 2em;
}
Hmm. Much shorter. Nice.
And then, it struck me :
:is(p, ul, ol, nav) + :is(h1, h2, h3, h4, h5, h6) {
margin-top: 2em;
}
Yay, this also works! How amazoomble!
This might also work with :where() or other CSS combinators like ~ or even (space) to create "matrix" of CSS selectors instead of very long lists.
Credits : all the answers on this page referencing the :is() selector.
Stylus's selector interpolation
for n in 1..6
h{n}
font: 32px/42px trajan-pro-1,trajan-pro-2;
The jQuery selector for all h tags (h1, h2 etc) is " :header ". For example, if you wanted to make all h tags red in color with jQuery, use:
$(':header').css("color","red")
July 2022 update
The future came and the :is selector is what you're looking for as described in this answer given in 2020 by #silverwind (now the selected answer).
Original answer
To tackle this with vanilla CSS look for patterns in the ancestors of the h1..h6 elements:
<section class="row">
<header>
<h1>AMD RX Series</h1>
<small>These come in different brands and types</small>
</header>
</header>
<div class="row">
<h3>Sapphire RX460 OC 2/4GB</h3>
<small>Available in 2GB and 4GB models</small>
</div>
If you can spot patterns you may be able to write a selector which targets what you want. Given the above example all h1..h6 elements may be targeted by combining the :first-child and :not pseudo-classes from CSS3, available in all modern browsers, like so:
.row :first-child:not(header) { /* ... */ }
In the future advanced pseudo-class selectors like :has(), and subsequent-sibling combinators (~), will provide even more control as Web standards continue to evolve over time.
Plain CSS
With plain css you have two ways. This targets all the heading elements wherever they are inside the page (as asked).
:is(h1, h2, h3, h4, h5, h6) {}
This one does the same but keeps the specificity to 0.
:where(h1, h2, h3, h4, h5, h6) {}
With PostCSS
You can also use PostCSS and the custom selectors plugin
#custom-selector :--headings h1, h2, h3, h4, h5, h6;
:--headings {
margin-top: 0;
}
Output:
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0;
}
You could .class all the headings in Your document if You would like to target them with a single selector, as follows,
<h1 class="heading">...heading text...</h1>
<h2 class="heading">...heading text...</h2>
and in the css
.heading{
color: #Dad;
background-color: #DadDad;
}
I am not saying this is always best practice, but it can be useful, and for targeting syntax, easier in many ways,
so if You give all h1 through h6 the same .heading class in the html, then You can modify them for any html docs that utilize that css sheet.
upside, more global control versus "section div article h1, etc{}",
downside, instead of calling all the selectors in on place in the css, You will have much more typing in the html, yet I find that having a class in the html to target all headings can be beneficial, just be careful of precedence in the css, because conflicts could arise from
Using scss you can loop through 6 and append to an empty variable $headings using a comma separator
$headings: ();
#for $index from 1 through 6 {
$headings: list.append($headings, h#{$index}, $separator: comma);
}
#{$headings} {
--default: var(--dark);
color: var(--default);
}
Thanks #steve

CSS First-child

"Set any content id-labelled element with a first-child descendant element of any of h1, h2, h3, h4, h5, and h6 as follows:"
The selector I've created is found below:
#content:first-child h1,
#content:first-child h2,
#content:first-child h3,
#content:first-child h4,
#content:first-child h5,
#content:first-child h6 {}
Is this correct? and if so can it be further simplified?
Thanks for the help everyone!
The description is a little but unclear, but, from what I can understand you want to either
select those h* elements and then the style would be like:
#content h1:first-child,
#content h2:first-child,
#content h3:first-child,
#content h4:first-child,
#content h5:first-child,
#content h6:first-child {}
Example
select the #container element itself in case the first child of it is one of h* family. Then you can not achieve this with pure CSS and need to add a simple JS like (using jQuery in this case):
$('#content').has('h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child, h6:first-child');
Example
You could add the class="header" to all of your h* tags. So your css now would be
#content:first-child .header { /* whatever */ }
The problem here is that you need to remember to put the class="header" to every tag you need

Resources