:not selector does not work for nested elements - css

I have special styles for user generated content, which comes from RTE. And I got some custom components inserted in the user generated content via tags in RTE. Those components should have totally different styles and should not inherit user content styles.
I am trying to achieve this with :not css selector like shown in the snippet below. This works for 1st child of a class, inserted in :not, but not for its children. The third 'Hello' should not receive the red color styling (as I think), but it does. Am I doing something wrong? Is it expected behavior? How can I achieve what I am after?
.user-content :not(.component) p {
color: red;
font-size: 50px;
}
<!-- Styled user-content inside some wrapper -->
<div class="user-content">
<div class="wrapper">
<p>Hello!</p>
</div>
</div>
<!-- A component inside user-content should be unstyled -->
<div class="user-content">
<dov class="component">
<p>Hello!</p>
</dov>
</div>
<!-- But nested elements of a component still recieve styling -->
<div class="user-content">
<div class="component">
<div class="wrapper">
<p>Hello!</p>
</div>
</div>
</div>

Your :not condition is met as true for your class="wrapper" elements, because they are not with component class. Using :not will apply to each element seperatly, without parent-child relationship:
<div class="user-content">
<div class="component"> :not(.component) is false
<div class="wrapper"> :not(.component) is true, so rule applies.
<p>Hello!</p>
</div>
</div>
</div>
To create parent-child relationship, use > in your rule:
.user-content > :not(.component) p

Your selector is getting a correct result, you need to use > instead of space to get your expected result .user-content > :not(.component) p
.user-content > :not(.component) p {
color: red;
font-size: 50px;
}
<!-- Styled user-content inside some wrapper -->
<div class="user-content">
<div class="wrapper">
<p>Hello!</p>
</div>
</div>
<!-- A component inside user-content should be unstyled -->
<div class="user-content">
<dov class="component">
<p>Hello!</p>
</dov>
</div>
<!-- But nested elements of a component still recieve styling -->
<div class="user-content">
<div class="component">
<div class="wrapper">
<p>Hello!</p>
</div>
</div>
</div>

Related

Is there a way to show/hide an element based on existence of a parent class in Tailwind?

Is there a way to tell Tailwind: If a parent has a certain class then show a certain HTML element, if not hide it? Or can this not be done in Tailwind?
<body>
<div class="hidden">Hello</div>
</body>
<body class="show">
<div class="block">Hello</div>
</body>
Yes!
You can use and arbitrary value on the parent, if you conditionally add the class it will show the children like so:
Demo: https://play.tailwindcss.com/0pCtnVrAh7
<!-- hidden -->
<div class="">
<div class="hidden item">Hey!</div>
</div>
<!-- Show if class "[&_.item]:flex" is added-->
<div class="[&_.item]:flex">
<div class="hidden item">Hey!</div>
</div>
<!-- Coming soon -->
<div class="group should-show">
<div class="hidden group-[&.should-show]:block">Hey!</div>
</div>
In a future update, hopefully tailwind will allow us to use the group modifier to style based on if the group has an additional class.
No. Tailwind is a css framework. To use conditional statements, you can either use Tailwind with javascript or php or any other languages.
Actually, there is.This is a css solution, but it can be achieved in tailwind as well:
.hidden {
display:none
}
.parent .hidden {
display:block
}
<div class="hidden">Text that doesn't show up</div>
<div class="parent">
<div class="hidden">
Text is visible
</div>
</div>
html

select nth-of-type with the html markup order

The html markup may vary as in the following example .menu is illustrated:
<div id="main">
<div></div>
<div class="menu"></div>
<div class="menu"></div>
</div>
for this I could use .menu:last-child but if this is like this:
<div id="main">
<div></div>
<div class="menu"></div>
<div>
<div class="menu"></div> <!--- selecting this----->
</div>
</div>
Or, say like this:
<div id="main">
<div></div>
<div class="menu"></div> <!-- count as 1--->
<div>
<div>
<div class="menu"></div> <!--- selecting this-----> <!-- count as 2 ---->
<div class="menu"></div> <!-- count as 3---->
</div>
</div>
</div>
So, I want to target the .menu whether it is parent, children or siblings anything but lastly marked up html or say like nth-of-type. Is there any idea for this?
I mean I want as the type of the class name.
The nth-of-type will give you the nth sibling of the same type as the selected element.
This should be used when you are dealing with different element types in the same parent, and you want to select the 1st/last or nth element of a specific type only.
Unfortunately there isn't any such pseudo-class to select a specific element(At a particular position) in the sequence of the elements with the same type in the context of the whole BODY of the document. Hence in this particular set of examples you cannot select the 2nd of all the elements with the same specification i.e. in this case with class=menu in the context of the whole document but it is possible with all such elements under a single level of the object hierarchy of the DOM tree i.e. under a single parent.
So the only way is through JS:
Code
<script>
onload=function()
{
obj=document.getElementsByClassName('menu')[1];//index=1 to access the 2nd object
/*
Do something with 'obj'
*/
}
</script>

CSS Content Property after element

I have this:
<div class="block3">
<div class="surround">
<div class="s_title">
<h3>Title</h3>
</div>
<div class="block_content">
<div class="content"> </div>
</div>
</div>
</div>
In my example I can't add content directly in HTML (blocks rendered by default in PHP), so I need to add in CSS.
The hard part of this is that I need to add text only in block3 element, after <h3> (.s_title:after will affect all s_title, so it will not work for me.)
Is there any way to do this?
Just add .block3 in front of your selector like how you would limit selection of any other element to some container element:
.block3 .s_title:after

CSS first-child not working as expected

I am using the following CSS to try and remove the left-border on the first child div of any element with the class called, "tblRow"
.tblRow div:first-child{
border-left: none;
}
<div class="tbl">
<div class="tblRow">
<div class="tblCell">Lower limit QTY</div>
<div class="tblCell">Upper Limit</div>
<div class="tblCell">Discount</div>
</div>
<div class="tblRow">
<div class="tblCell">1</div>
<div class="tblCell">5</div>
<div class="tblCell">25%</div>
</div>
</div>
This only removes the left-border from the first child div in the first row. It does not remove it in the second row. Any ideas?
I generally only use the :first-child and :nth-child psuedo selectors when I have little or no control over the elements or they are populated dynamically where I cannot rely on an order. Additionally, since :nth-child is CSS3, you can't rely on complete browser compatibility. If you can do without this psuedo selector, my advise is to create a secondary class for this purpose.
.tblCell.firstCell{
border-left: none;
}
<div class="tbl">
<div class="tblRow">
<div class="tblCell firstCell">Lower limit QTY</div>
<div class="tblCell">Upper Limit</div>
<div class="tblCell">Discount</div>
</div>
<div class="tblRow">
<div class="tblCell firstCell">1</div>
<div class="tblCell">5</div>
<div class="tblCell">25%</div>
</div>
</div>
It seems to work on the fiddle, so you probably have a (hidden) text node somewhere there. Therefore I suggest using .tblRow div:first-of-type { ... }, if possible from browser support point-of-view.

Why sibbling div elements are rendered as children of one of them

For some reason div elements change their parents during rendering in unexpected way, reproducible in Firefox and Chrome.
E.g.
<div class="main">
<div class="slot"/>
<div class="slot"/>
</div>
<div class="footer"></div>
Firefox debugger will show as this at runtime as:
<div class="main">
<div class="slot"><div class="slot"/></div></div>
<div class="footer"></div>
</div>
When I remove .slot elements(see the code attached), everything renders as expected(#footer place in tree after rendering is same as in the source).
Code:
http://pastebin.com/3j3aQFdh
The problem is that you use empty divs: like that
<div />
You should try to change your code to use valid divs with empty content:
<div></div>

Resources