Most efficient way to handle multiple descendant selectors? - html

I'm creating a site that has two sections; a largely static side that uses intricate designs with coloured backgrounds, and a dynamic blog that simply uses a white background.
I've specified in my _settings.scss (Foundation 5) file to use a dark text on white background for all text elements. This is working without issue, and applies to the blog and static side perfectly.
Where I am stumbling is finding an efficient way to manage the different coloured backgrounds and appropriate text styles for each background on the static side.
I have a "dark" & "light" section that use a dark and light blue background respectively, alternating down the page.
I have thus far been using each as a class name that acts as a wrapper around my content. i.e.
<div class="dark section">
<div class="row">
<div class="small-8 columns (etc.)>
<h1> Some Header </h1>
<p> Some text </p>
</div>
</div>
</div>
<div class="light section">
<div class="row">
<div class="small-8 columns (etc.)>
<h1> Some Header </h1>
<p> Some text </p>
</div>
</div>
</div>
That's my HTML. The text (p) is white for both, and I have no issues styling that (overriding _settings.scss). It's the headers that are giving me issue. I am struggling to find a method of targeting the headers in each coloured section without it spilling to the next, alternate coloured section; or without adding numerous classes to each and every instance of the header dependant on background colour.
Thus far I have been using: (colours simplified as I'm using SCSS variables)
.dark {
background-color: dark-blue;
colour: white;
}
.dark h1,h2 {
colour: orange;
}
.light {
background-color: light-blue;
colour: white;
}
.light h1,h2 {
colour: dark-blue;
}
.section {
*insert various padding here*
}
Now this to my mind, should work. However, I'm having the styles from the light class override the styles (where different) in the dark class. i.e. The dark sections have dark-blue headers, rather than orange. I can't seem to stop the selector from riding from one 'section' to another through the cascade.
I've probably made a stupidly simple oversight, but any help would be greatly appreciated.

Just use the descendant selector:
.dark h1 {
color: orange;
}
Here we have selected a class (.dark), and then selected an h1 that is a child at any level to the selected class. So this will apply to any <h1> elements within your <div class="dark section"> element, no matter what level.
If you want to use this descendant selector with multiple elements, you'll need to add the class to each side of the comma. Currently your selection of .dark h1, h2 is selecting all h1 elements that are children of class .dark (as I've explained above), and all h2 elements anywhere in your body, period... and likewise for .light. What you need is:
.dark h1, .dark h2 {
color: orange;
}
.light h1, .light h2 {
color: dark-blue;
}
Note that with your original code above, you are typing colour instead of color. The spec uses American English, so you'll need to fix these unless you have renamed them as variables or something using your pre-processor. Also note that you haven't added a closing " to your "small-8" class names.

Related

Css Identical classes differ in one parameter, how to solve

I have a class mainText, it stores the settings for the font, its size, color, etc.
In the first block, everything suits me, but in the second block, all the parameters are repeated, but the color is different.
What is the right thing to do in this situation?
Create a new class and duplicate all properties in it?
Use style on every element of the second block?
I don't understand why classes can't be inherited in css like
.secondText : mainText{
color: white;
}
Normally, you would give both elements the same base class and your second item the additional class:
<div class="base">
I am a div
</div>
<div class="base white">
I am a div, but white
</div>
For the css part
.base {
//base config
}
.white {
color: white;
}
There is no explicit class inheritance in css, yet you could look into mixins in scss or scss overall, because it provides some features css does not have. Hope this could help!
you could use the smame one and add a second class to change the color with high priority.
HTML:
<div class="firstText">Text</div>
<div class="secodText">Text</div>
.firstText, .secondText{
color: black;
:
:
:
}
.secondText{
color: white !important;
}
or you could place the css in the HTML code. for example:
<span class="firstText" style="color: white;">Text</span>
for more info check: Can a CSS class inherit one or more other classes?

How can I style elements in a div based on the div's class?

Basically, I'm creating a dark theme system for my website, and it adds the dark class to the html tag when the proper function is called. I'm using CSS variables like --light-theme-bg: white; and accessing them with var(--light-theme-bg);. How can I style specific elements such as hr based on if that dark class is attached to the html element. How can I do this?
Scoping is your friend. You'll need to add two rules to your CSS. One for the dark theme and one for the light one.
In those rules, you can define a --background var.
All child elements that reference that var will respect it.
.light {
--background: #f9f9f9;
}
.dark {
--background: #191919;
}
.first,
.second {
color: red;
background: var(--background);
}
<div class="light">
<div class="first"> I'm the first div</div>
<div class="second">I'm the second div</div>
</div>
<div class="dark">
<div class="first"> I'm the first div</div>
<div class="second">I'm the second div</div>
</div>
If you want to select an element inside a .class, use the css syntax .class element, so your code would be .dark hr to select it an hr element inside an element with the class of .dark.
As you mention It added "dark" class to the parent html tag. So considering dark as parent class you can use css to all element like
.dark elements(h1/div/p/others)

CSS one class to ignore another

I have something like this
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
<a href="#" class="ignore">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
<a href="#">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
And CSS that does this
.text-holder {
color: green;
}
a {
color: red;
other css
}
.ignore {
other css
}
Is there a way that the link can ignore the css style for the global a style, and just use the ignore? I don't want to use !important because there will be other instances of text-holder that will want to use the global a style.
EDIT
Thanks for all the replies, but let me be a little more clear so hopefully you understand better. (Not the best at explaining)
The problem is text-holder has it's text styling from global p, h2 and etc. Which are above a in the hierarchy of the stylesheet. so p, h2, a, .ignore, .text-holder etc
a has a lot of info on it, hover, visited, focus, color, font-weight and etc. Now for all the divs I wanted to ignore this info I was looking to see if there was a simpler way of just creating an ignore rule, rather than for all the divs I want to ignore it to overwrite them with all the rewritten information.
CSS doesn't support "ignoring", but part of its nature (the Cascading part of Cascading Style Sheets) supports "overwriting"; Newer CSS properties will overwrite older CSS properties of the same name, so you just need to give .ignore a different color value than your previous a selector's color value.
Is there a way that the link can ignore the css style for the global a style, and just use the ignore?
No. If a selector matches then all applicable rules in it will be applied.
.ignore is at least as specific as all preceding rules, so you just need to set the properties you want to override to the desired value.
Yes, basically what you're trying to do is already how CSS works.
The key to understand is the concept of specificity.
CSS rules applied through the style="" attribute have a weight of 1000.
Rules applied against an #id selector have a weight of 100.
Rules applied against a .class selector have a weight of 10.
And rules applied against an element tag name or :pseudo-selector get a weight of 1.
So for example, if you have...
a { color: red; }
.ignore { color: black; }
The weight of the red links is 1, while the weight of black text is 10, so the black has higher specificity and would win.
The important concept is that .ignore doesn't tell it to ignore its old assignment, it is instead a way to override the assignment.
EDIT
I should also add that cascading rules have no weight, so any definition in a child element will override them.
For example:
a { color: red; }
.ignore { color: black; }
div { color: blue; }
<a class="ignore"><div>hello world</div></a>
The text will be blue, not black, because the div tag has a rule applied to it which overrides the cascading black from the .ignore class.
You can try:
:not(.ignore) .text-holder {
color: green;
}
Or if you move your ignore class to .text-holder element
.text-holder:not(.ignore) {
color: green;
}

Style (h and p) tags inside div. Only access inside <body>

I need to style h1, h2, h3... and p tags inside a div but I only have access to the content area.
If it where possible, this would be what I'd use:
<div style="h1{padding:0;}p{font-size:1.4em;color:#000}">
Is there a solution to do this ? Apart from adding the style to every element.
Thanks
Although HTML syntax restricts style elements to the head part, this requirement is not enforced in practice. It works inside body, too. You just need to take into account that the effects are global to the document. Thus, to limit the effect to elements inside a certain element, you need to use suitable selectors. Example (I have added a color setting because the effect of just padding: 0 as in the question in not noticeable: it equals the default):
<h1>Heading outside the div</h1>
<p>A paragraph outside the div.</p>
<div class=mydiv>
<style>
.mydiv h1 { padding: 0; color: green; }
.mydiv p { font-size: 1.4em; color: #000; }
</style>
<h1>Heading inside the div</h1>
<p>A paragraph inside the div.</p>
</div>
There isn't a good solution.
Style elements may only appear in the head.
Inline style only applies to the element the attribute appears on.
The closest you can come is to use JavaScript to dynamically modify the stylesheet.
You would be better fixing whatever problem is preventing you from modifying the head section.
To avoid unwanted changes inside divs i will be using to divs with 2 unique id's:red and green
If you want different style for specific divs:
<div id="red"><h1>red</h1><p>red</p>
<div id="green"><h1>green</h1><p>green</p>
body #red > h1,body #red >p{
color:red;
}
body #green > h1,body #green > p{
color:green;
}

Apply CSS to any element except for certain class descendants?

Is it possible to apply certain CSS to any element, except descendants of a certain class?
Here's a fiddle: http://jsfiddle.net/68jgdthm
As you can see I want everything on the page to be dark except elements which are descendants of the light class. The trick here is that one can't know if the element is a direct descendant, e.g. it might be this:
<div class="light">
<p>Element</p>
</div>
but it might also be this:
<div class="light">
<div>
<div>
<p>Element</p>
</div>
</div>
</div>
The dark class is almost always added to the body element and will always be a parent of any light classes.
One might say:
Just make the body "light" and add dark classes to any elements you need. - But I actually need the opposite, I need everything to be dark and certain elements to be light.
Then add "light" styles and add the light class to elements you need. - I already have the dark styles, so I'm looking for an easier "excluding" solution (I'm using LESS, so prefixing etc. is quite easy).
You will not be able to exclude descendants this way without writing a separate selector. You won't be able to do this even using :not(), for the reasons stated here.
Fortunately, the fact that .light elements will only ever occur within the context of a .dark element and not vice versa makes this a little easier. Since you have a body CSS rule already, just add .light p to that rule, and move the entire ruleset underneath .dark p so .light p will take precedence:
.dark p {
color: #000;
}
body, .light p {
color: #ccc;
}
Updated fiddle
Alternatively if you want to keep the body rule on top, you could bump up the specificity of .light p to ensure it will take precedence:
body, body .light p {
color: #ccc;
}
.dark p {
color: #000;
}
Color is an inherited property. Therefore just by declaring .dark and .light to have the wanted color is a good thing. You can make a default by assigning it to the body. I think atomic design like this is a good practice, as you don't add too much specificity in your CSS.
You could do this:
body {
color: #ccc;
}
.dark {
color: #000;
}
.light {
color: #fff;
}
Demo: http://jsfiddle.net/68jgdthm/1/