Inheritance (specificity) problem regarding the width of a div element - html

I've got a more theoretical problem. Im perplexed why the width of a div element does not change after I specifically specify it in the class selector ".blue-box".
In the ".float-container div" selector, I have specified the width of a box of 100px, but the ".blue-box" selector does not overwrite it, even though it is a child element of a ".float-container div" selector
<div class="float-container">
<div class="red-box">Box 1</div>
<div class="blue-box">Box 2</div>
<div class="orange-box">Box 3</div>
<div class="yellow-box">Box 4</div>
<div class="green-box">Box 5</div>
<div class="pink-box">Box 6</div>
</div>
.float-container div {
border: 2px solid;
height: 75px;
width: 100px;
}
.red-box {
background: red;
}
.blue-box {
background: rgba(0, 0, 255, 0.493);
text-align: end;
width: 330px;
}
.orange-box {
background: orange;
}
.yellow-box {
background: yellow;
}
.green-box {
background: green;
}
.pink-box {
background: pink;
}
I know how to bypass it. Im just interested in the theory behind it.I am confused why the blue-box inherits the 100px width and does not apply its own 330px width. I know that class is more specific than the div element, so where is the problem?

It's not inheriting the width. The blue box is a subject of the .float-container div selector, which has specificity (0, 1, 1) which beats the specificity of .blue-box which is (0, 1, 0).

The styling from {.float-container div} has more specificity than that of {.blue-box}.
Look at it this way. Let's assume class selectors have a specificity of 10 and element selectors have a specificity of 1.
Then {.float-container div} would have a specificity of 10 + 1 = 11 because it contains both class and element selectors while {.blue-box} would have a specificity of just 10.
You can reference this article if you need more explanations.
https://medium.com/code-writers/understanding-compound-selectors-and-why-to-avoid-them-in-css-d969e60b71dc

Related

How to add padding on top of a div if there is another div above the current div?

I noticed that there is very little spacing between the AboutDogs and AboutCats divs. So I added some padding-top: 20px to the AboutCats to create some space between AboutDogs and AboutCats .
But let's say there is a scenario where I have only AboutCats and there is no other div on top of it. In that case, I don't want to add the padding-top: 20px since that will be unnecessary spacing on top.
<div class="MainContainer">
<main>
<div class="AboutDogs"></div>
<div class="AboutCats"></div>
</main>
</div>
Is there a way to address this scenario using CSS?
This is what the adjacent sibling selector is useful for.
You have some errors in your HTML code, by the way:
Don't have a space between class and the equals sign
Remember to close tags, as your main tag isn't closed
Here is an example of the adjacent sibling selector in use for you:
main {
background: lightgrey;
padding: 2em;
}
.about {
border: 1px solid red;
}
/*
* Adjacent sibling selector to add a top margin to any
* element with .about which follows another .about
*/
.about + .about {
margin-block-start: 1em;
}
<div class="main-container">
<main>
<div class="about about--dogs">Lorem</div>
<div class="about about--cats">Ipsum</div>
</main>
</div>
This is also very useful for setting up spacing on typography elements, such as paragraphs which follow another paragraph or a heading.
You also could have done this using CSS grid or flex, combined with the gap property. Here's an example:
main {
background: lightgrey;
padding: 2em;
display: grid;
grid-template-columns: 1fr;
gap: 1em;
}
.about {
border: 1px solid red;
}
<div class="main-container">
<main>
<div class="about about--dogs">Lorem</div>
<div class="about about--cats">Ipsum</div>
</main>
</div>
One modern solution which also is redundant for all potential cases is the usage of Flexbox. Change the flex-direction to column to maintain the normal block-level behavior. You can space apart elements within Flexbox by using the gap property.
main {
display: flex;
flex-direction: column;
gap: 20px;
}
/* for visualization only */
main > div {
border: 2px dashed red;
}
<div class="MainContainer">
<main>
<div class="AboutDogs">About Dogs</div>
<div class="AboutCats">About Cats</div>
</main>
</div>
An Alternative is the usage of the :nth-child() selector. With n+2 you can select all child elements starting from the 2nd element.
main > div:nth-child(n + 2) {
margin-top: 20px;
}
/* for visualization only */
main > div {
border: 2px dashed red;
}
<div class="MainContainer">
<main>
<div class="AboutDogs">About Dogs</div>
<div class="AboutCats">About Cats</div>
</main>
</div>

Update style of element based on other elements focus

I have a requirement where I need to set special style to an element of its children is focused. Issue is, the changes are not reflected if the element is not self of children of element in action.
In the below example, I'm using a variable --bg-color as background for Test1, Test3 and Test4.
This variable is update on hover for:
Test2 to Blue
Test3 to Black
If you notice,
Test1 never has an update
Test3 changes background on Test2's hover but not on Test4's hover
:root {
--bg-color: lightblue;
}
div {
height: 200px;
width: 200px;
}
.test1 {
background: var(--bg-color)
}
.test2{
background: red;
display: flex;
flex-direction: column;
}
.test3, .test4 {
background: var(--bg-color);
width: 100px;
height: 100px;
z-index: 1;
}
.test2:hover {
--bg-color: blue;
}
.test3:hover {
--bg-color: black;
}
<div class="test1">Test 1</div>
<div class="test2">
Test 2
<div class="test3">Test 3</div>
<div class="test4">Test 4</div>
</div>
So the question is, can we do this in anyway just by using CSS and is there a restriction for repaint?
Note: I'm aware I can use JS to add class to an element and update style based on it but CSS is faster and my usecase needs css approach. This is just a sample of problem

using nth-child() non recursive? [duplicate]

This question already has answers here:
Is there a CSS selector for the first direct child only?
(8 answers)
Closed 7 years ago.
Is it possible to use parent child:nth-child() and only apply to child's?
The html is the following:
<body>
<div>div 1</div>
<div>
div 2
<div>div 2.1</div>
<div>div 2.2</div>
</div>
</body>
And I wanted to select with CSS: div 1 & div 2, I used:
body div:nth-of-type(1) {
background: red;
color: white;
}
body div:nth-child(2) {
background: blue;
}
But div 2.1 & 2.21 got selected too. JSFiddle
Is it possible to do a non recursive selection? If not I guess the only solution are clases or id's..
You can put a > between body and div to select only direct children of body:
body > div:nth-of-type(1) {
background: red;
color: white;
}
body > div:nth-child(2) {
background: blue;
}
<body>
<div>div 1</div>
<div>
div 2
<div>div 2.1</div>
<div>div 2.2</div>
</div>
</body>
You can use the ">" character to indicate a parent-child selector. Since 2.1 and 2.2 by default are transparent this doesn't solve the coloring problem so you should style them differently:
https://jsfiddle.net/evccpeeL/1/
div {
background: white;
}
body > div:nth-of-type(1) {
background: red;
color: white;
}
body > div:nth-child(2) {
background: blue;
}
You don't actually need to use pseudo-classes here.
You can do this with the direct child selector > alone
body > div {
background: red;
color: white;
}
body > div > div {
background: blue;
color: white;
padding-left: 1em;
}
<body>
<div>div 1</div>
<div>
div 2
<div>div 2.1</div>
<div>div 2.2</div>
</div>
</body>
You might find this article useful The 30 CSS Selectors you Must Memorize

Puting <div>s next to each other

I have been searching for a way to put divs next to eachother and found one that "worked" but there is an issue
float: left;
it worked! but it also popped them out of the parent div and it looks silly. the background of the parent div no longer cares about them.
How can I put two divs, side by side, while in another div?
Remove your float and try :
display: inline-block;
Floating elements doesn't normally affect the size of their parent. You can change this by changing the overflow style of the parent.
Example:
.parent { background: red; overflow: hidden; }
.child { float: left; margin: 5px; background: yellow; }
<div class="parent">
<div class="child">child 1</div>
<div class="child">child 2</div>
<div class="child">child 3</div>
</div>
To prevent floated blocks from "popping out" of the parent container, you need to trigger a block-formatting context, which you can do by specifying:
overflow: auto
for the parent container.
.wrap {
border: 1px dotted gray;
background-color: beige;
overflow: auto;
}
.wrap div {
float: left;
width: 200px;
height: 200px;
border: 1px dotted blue;
margin: 10px;
}
<div class="wrap">
<div>One</div>
<div>Two</div>
</div>

Space between two divs

My issue is that I have two (or more) divs of the same class, that need to be spaced from each other. I cannot directly use margins however, as the last or first element would also have the margin applied, which I do not want.
-Green is where I want the space
-Red is where I don't want it
As the only solutions I can think of are complicated / involve hard-coding a value, I am hoping that someone can think of a clever, simple solution to this problem.
Details: Sometimes these divs would be by themselves, and on a rare occasion floated.
Any advice on how above ideas could be better, any new ideas, or just help in general would be greatly appreciated ;)
You can try something like the following:
h1{
margin-bottom:<x>px;
}
div{
margin-bottom:<y>px;
}
div:last-of-type{
margin-bottom:0;
}
or instead of the first h1 rule:
div:first-of-type{
margin-top:<x>px;
}
or even better use the adjacent sibling selector. With the following selector, you could cover your case in one rule:
div + div{
margin-bottom:<y>px;
}
Respectively, h1 + div would control the first div after your header, giving you additional styling options.
If you don't require support for IE6:
h1 {margin-bottom:20px;}
div + div {margin-top:10px;}
The second line adds spacing between divs, but will not add any before the first div or after the last one.
Why not use margin? you can apply all kinds off margins to an element. Not just the whole margin around it.
You should use css classes since this is referencing more than one element and you can use id's for those that you want to be different specifically
i.e:
<style>
.box { height: 50px; background: #0F0; width: 100%; margin-top: 10px; }
#first { margin-top: 20px; }
#second { background: #00F; }
h1.box { background: #F00; margin-bottom: 50px; }
</style>
<h1 class="box">Hello World</h1>
<div class="box" id="first"></div>
<div class="box" id="second"></div>​
Here is a jsfiddle example:
http://jsfiddle.net/baXmu/2/
REFERENCE:
http://www.html.net/tutorials/css/lesson10.php
DIVs inherently lack any useful meaning, other than to divide, of course.
Best course of action would be to add a meaningful class name to them, and style their individual margins in CSS.
<h1>Important Title</h1>
<div class="testimonials">...</div>
<div class="footer">...</div>
h1 {margin-bottom: 0.1em;}
div.testimonials {margin-bottom: 0.2em;}
div.footer {margin-bottom: 0;}
A slightly newer solution to this problem is to put the divs in a container that is display: flex or display: grid and to use the gap css property which will only add a space between elements inside the container, but not before/after.
flex solution:
.wrapper {
display: flex;
flex-direction: column;
gap: 20px;
}
header, footer {
background: red;
color: white;
}
<header>header</header>
<div class="wrapper">
<div>section 1</div>
<div>section 2</div>
<div>section 3</div>
</div>
<footer>footer</footer>
grid solution:
.wrapper {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
header, footer {
background: red;
color: white;
}
<header>header</header>
<div class="wrapper">
<div>section 1</div>
<div>section 2</div>
<div>section 3</div>
</div>
<footer>footer</footer>