CSS: span.test or .test? - css

Is there any difference in:
#example .test{margin-top:10px}
And
#example span.test{margin-top:10px}
.test is totally unique, no any class with that name exists. I have been trying to use like
<div id="example">
<label for="name">Name</label>
<input name="name" type="text" />
<span class="test">asdfghjkl</span>
</div>
The first css won't work, while the second works fine. Just wondering why first wont work?
Thanks
Edit:
I found out that in the input field (in above example), i had put float:left;, which was causing the problem. If anyone is interested, here you can see example. If you remove float:left;, it will work fine.
http://jsfiddle.net/CmXrX/1/

Yes, there is a difference. That difference is in specificity. If you have conflicting CSS rules -- two rules point to the same element but certain properties conflict -- the conflict will be sorted out by the rules about specificity.
Each type of selector has a certain number of "specificity points" For instance:
Selector type Points
-----------------------------
HTML selector 1
class selector 10
id selector 100
So if you had these two rules:
#example .test{margin-top:10px}
#example span.test{margin-top:20px}
the top margin would be 20px, because the second rule has a specificity of 111 (100 + 10 + 1) whereas the first has 110 (100 + 10).
My guess, therefore, is that you have a conflicting style somewhere that has 111 specificity.

There are two differences:
The latter will only apply, if the class test is applied to a span and no other element.
(and most likly more relevant in your case) the latter has a higher specificity than the former.
You probably have an other rule with a higher specificity then the first selector but lower than the second. That means this other rule will override the first rule, but not the second.

I found out that in the input field (in above example), i had put float:left;, which was causing the problem. If anyone is interested, here you can see example. If you remove float:left;, it will work fine. http://jsfiddle.net/CmXrX/1/

yes there is a difference :
<div id="example">
<label for="name">Name</label>
<input name="name" type="text" />
<span><div class="test">asdfghjkl</div></span>
</div>

Related

Tailwindcss: How to use peer pseudo-class to detect existence of peers?

I'm trying to create a generic input component that rounds it's corners based on what's around it. Normally this works using the first: and last: pseudo-classes but there is one case where the label is a peer to the input so it should be fully rounded.
I think what I need to do is identify what the peer element is and then styling according. How can I use the custom peer selector to identify if a peer exists in tailwind?
<div class="flex flex-col">
<label hmtlFor="email" className="peer-[label]">Email</label>
<input id="email" class="peer-label:only-of-type:rounded-3xl rounded-none bg-green-400" />
</div>
Tailwind Playground: https://play.tailwindcss.com/PzMukUDQuX
^ The playground shows what I'm fully trying to do, but for this question, just need to figure out how the custom peer syntax is supposed to work.
is this what you are looking for?
https://play.tailwindcss.com/erZse7TDD4
explanation:
I am not sure peer would work here because:
the span is not aways there
the label is not a peer of the input it is a peer of the parent container of the input.
I used a bunch of complex selectors which works but not sure it is the best solution here. I think you can do something similar via code when you render the items if you are using react.
Edit: improved code and further selector explanation.
One change I would make is wrapping everything with a div as the last 3 elements had and removing the rounded corners. that gives a generic html like below and we can focus only on the first and last child:
<div class="flex flex-col">
<!-- label -->
<div>
<!-- maybe a span here -->
<!-- there is aways an input here -->
<!-- maybe a span here -->
</div>
</div>
now we can take advantage of something called arbitrary variant values.
now we apply the below selectors directly to the wrapping div:
"[&>*:first-child]:rounded-l-3xl"
// which is apply rounder left (rounded-l-3xl) to any (*) first child (:first-child) directly descendant (>) of myself (&).
"[&>*:last-child]:rounded-r-3xl"
// which is apply rounder right (rounded-r-3xl) to any (*) last-child (:last-child) directly descendant (>) of myself (&).
the resulting is: https://play.tailwindcss.com/K3vSiUxa4V
EDIT2: without arbitrary values:
similar effect without arbitrary variants:
https://play.tailwindcss.com/Yup53pmaS4

Are multi-level :not selectors possible in CSS / JS querySelector?

I have found many examples explaining how to use multiple :not selectors on an individual element. However, so far I have been unable to find any examples that use :not selectors on different levels within a single selection path in CSS / JS querySelector.
For example, given a HTML structure of:
<div class="anything_except_ignore">
<input type="text" id="a" />
<input type="hidden" id="b" />
</div>
<div class="ignore">
<input type="text" id="c" />
</div>
I wish to select JUST input#a.
I have tried the following in JS and it does not seem to work:
var elems = document.querySelectorAll("div:not(.ignore) input:not([type='hidden'])");
In this case it appears the first :not selector is ignored (so in the above example both input#a AND input#c are selected.
Have I made a mistake in the syntax or is this approach not possible to use :not selectors in this way to select just input#a?
I can work around this by looking a parent class in JS once the elements are selected, but I'd rather do it properly at the selector stage.
---UPDATE--- as suggested in one of the answers, my mistake was in not understanding that other DIVs further up the DOM can fulfil the :not(.ignore) criteria and so the input under the div.ignore element IS selected. If I remove other DIVs then the requested logic does seem to work as proved by this test:
var res="",elems = document.querySelectorAll("div:not(.ignore) input:not([type='hidden'])");
for(var i=0;i<elems.length;i++){
res = res + elems[i].id + "\n";
}
alert(res);
<div class="anything_except_ignore">
<div>
<input type="text" id="aa" value="a"/>
<input type="hidden" id="bb" value="b"/>
</div>
</div>
<div class="anything_except_ignore2">
<span>
<input type="text" id="dd" value="d"/>
<input type="hidden" id="ee" value="e"/>
</span>
</div>
<div class="ignore">
<input type="text" id="cc" value="c"/>
</div>
Sorry for any confusion, but at least this helps clarify how it should work as I could find no other examples of this in my searching.
---CONCLUSION---
As far as I can tell I have to either:
make sure that my inputs are always immediate children of the div I want to check and use the ">" syntax
after selection of all non-hidden inputs, use JS to check up the DOM tree of each, to check the class name of all DIVs up the tree.
If there is a better querySelector way to solve this particular issue then I'd love to hear it.
This is a common misunderstanding of how :not works in combination with other selectors.
Let me guess, there are actually more div elements than you have shown us, around these elements …?
div:not(.ignore) is not “ignored”, but the condition is just fulfilled by a different element than you thought - by some div element further up the tree. The space in between the two partial selectors is the descendant selector, so every input:not([type='hidden']) element that has a div ancestor that doesn’t have the class ignore anywhere above it in the DOM tree, matches the full selector.
If you change your selector to div:not(.ignore) > input:not([type='hidden']), this would only select such input fields if their immediate parent is a div without that class.

How to select css id's with numbers in them?

So I want to target multiple html element(s) like the below using a regular expression in a css selector:
<input id="something_stuff_013_work" />
<input id="something_stuff_016_work" />
The following CSS selector doesn't seem to work:
input[id*='[0-9]*_work']
I need to do something with digits in the regular expression because the inputs can be dynamically added and will be assigned ids with digits in them.
What am I doing wrong?
What about using the following selector:
input[id^='something_stuff_'][id$='_work']
It will get inputs with id starting with "something_stuff_" and finishing with "_work".
CSS does not support regexes in selectors. Use classes or starts-from and ends-with attribute selectors.
An approach to this problem would be to use classes instead of ids and have things that are styled the same to be classed the same. for example:
<input id="something_stuff_01_work" class="input_class">
<input id="something_stuff_02_work" class="input_class">
<input id="something_stuff_03_work" class="input_class">
Then select the class instead of the id.
.input_class {
sweetstyleofawesomeness;
}
Try prefixing the numeric id with \3.
I came across this today, it was the selector generated using chrometools, I'd not seen it before, and it works using Chromium Webdriver:
#\37
Full selector used is "#\37 > div > div.cell-text".
This was a selector to select an element with id = "7".
It (prefixing with \3) seems to work throughout the document I am looking at automating, with my current setup.

CSS Contains Selector with a NOT qualifier?

I'm using the following in some selenium code:
WaitForElement(By.CssSelector("#document-count:contains(<number greater than 0>)"));
Specifying the number greater than 0 is where I'm stuck. Is there any way to use only css to check and see if an element's innertext has something other than 0?
:contains was deprecated in CSS3. Since WebDriver ties directly into the browser, it's unable to use that pseudo-class.
Is there any way to use only css to check and see if an element's innertext has something other than 0?
Unfortunately not. CSS really screwed Selenium users over with their deprecation of both :contains and :nth
As Arran said, you can use xpath, or - if you are willing to experiment with C# and CSS together (not just css as you state) then you can come up with something to loop x amount of times checking the text.
Per Chris Coyier at CSS Tricks:
Deprecated
:contains() - As far as I know, this is gone. The current
CSS3 spec has removed it. I don't know the story, let me know if you
do. At a glance, it looks ridiculously useful (being able to select
objects based on the textual content they contain). It may be because
of problems, or having content in selectors being undesirable. My
preference would be to have it select by elements rather than text,
like p:contains(img), but alas, no such luck.
That said, if you were to set the value properties, you may be able to use :not([value="0"]):
See jsFiddle demo
HTML
<div id="doc">
<input type="text" value="0" />
<br />
<input type="text" value="1" />
<br />
<input type="text" value="2" />
</div>
CSS
#doc input[value="0"]
{
background: red;
}
#doc input:not([value="0"])
{
background: green;
}
Result

What does this css selector do?

I spotted this (to me) curious css style in the default Site.css file of an ASP.NET MVC project:
.text-box.multi-line
{
height: 6.5em;
}
Is .text-box.multi-line just the name of a class that happens to have a dot in the middle of it, or is this a nesting of two classes? Or is it something else entirely? Can you explain?
And can you provide a usage example?
Edit
Thanks for all the answers. This seems to be an omission from the w3schools css reference page.
it matches an item with both classes, ie.
<textarea class="text-box multi-line"></textarea>
It will not match if the item only has 1 of the classes.
It will match if the item has those two classes plus additional ones.
It means that the element has both classes.
It will select an element with the class text-box that also has the class multi-line
This would be the same:
.multi-line.text-box {}
.text-box[class~="multi-line"] {}
An example:
<p class="multi-line text-box some-other-class"></p>
It's selecting an element like this:
<* class="text-box multi-line"></*>
Any element that has both the text-box and multi-line classes.
It will select this element:
<textarea class="text-box multi-line" />
Or any element with both the text-box and multi-line classes for that matter.
Here's a quick little fiddle to show the difference:
http://jsfiddle.net/sGn2v/
basically it'll match an element having BOTH classes!

Resources