CSS nth child selector - html

I have a problem with css selectors, I have 2 buttons rendered into HTML by a external javascript, and the buttons are at the bottom and at the top of my page.
So if I customize CSS with mutual class name one button looks fine but the other does not, so here is my idea:
select the first button of a xclassname and give it some CSS
do nothing to the other button leave its CSS as it is how can I do that
Here is how I failed to do it with CSS:
.xclassname:nth-child(1) {
⋮ declarations
}
Nothing happened, can anyone think of something that will work? btw, I use Prototype, not jQuery

That's a CSS3 selector. Are you using IE? Because that selector isn't goint to work there at all. It should work in Chrome, Safari, or a later version of Firefox.
The workaround that I would use would be to use JQuery to perform this operation instead. Use the nth-child() selector in JQuery to add a class which has the style declaration you want. It's a bummer that IE is so behind the times, but that's why it's the bane of the existence of every web developer around...

The accepted answer is wrong. The Prototype docs actually provide an nth child example and the OP actually mentions that he uses Prototype so he doesn't need to worry about IE.
This is the nth child example provided in the docs:
$$('table tbody > tr:nth-child(even)');
Given what you're trying to do though you could target the element like this:
$$('.xclassname').first().setStyle({
// some style here
});

Related

Is it possible to select elements that do not have a child of a certain type?

I'm trying to select <a> elements that are not the parents of <img> elements. (Note: if it's relevant some of the anchors I want to select are childless.) I tried this:
a > :not(img) {}
and this:
a:not(> img) {}
but neither of them seem to work. How would I accomplish this in CSS?
There is a spec, currently in draft, for a :has() pseudo-class. No browser supports it yet. If the spec is someday approved and implemented, you'd be able to do this:
a:not(:has(img)) {
// Styles
}
The MDN page says that :has would never work in stylesheets, only in JavaScript; but in saying that, it links to a section of the spec about a "dynamic selector profile" that apparently no longer exists.
I think the browser vendors typically have a problem with implementing CSS features that require knowledge of the DOM that only exists after the selected element is created, so I don't know if we should get our hopes up for this. Someone who follows the mailing lists or is generally smarter than me might offer a better prognosis.
Unfortunately, no. You'd need to use jQuery.
You could do some kind of workaround using CSS:
Assign a class to links that do not have child elements that are images and use that class to style the links as normal (e.g. a.class{color: red})
Assign a class to links that do have an image child element, and use a:not(.class){} to change their color
Reason: There is no parent selector in CSS. See:
Is there a CSS parent selector?, CSS Parent/Ancestor Selector

Shadow Dom and CSS3 :target selector

I should start off by saying that I don't really have an issue that I'm trying to work through. I just had an interesting thought about how Shadow Dom and the CSS3 :target selector might / should / currently do work together.
I know that HTML specification says that there should only ever be one element with a particular ID value in a valid HTML document. But when we start using webcomponents with shadow dom we could very easily find ourselves using multiple elements with the same ID. This is especially true when we use the same component multiple times in the same page. So the question that I have is this: what should happen to an element inside a shadow dom region that has an ID value which matches the current hash and which is styled with a :target rule?
For example, if I wrote a webcomponent (my-element) that contained
<style>
#debug {display:none}
#debug:target { display:block; background-color:yellow; border 2px solid red; }
</style>
<div id="debug">some debug data</div>
What should happen to all the instance of my-element that I put on a page and navigated to #debug on? Should the debug element in each component show? Should none of them show? Should only the first element's debug div show (the same one I'd expect the browser to try and navigate to)?
My opinion is that if the page does not have an element with an ID=debug value that no scrolling navigation should appear on the page. As shadow dom is isolated from the rest of the page's styles the browser shouldn't try to navigate to such an element nested in shadow dom. Each my-element instance should be able to see the current page's URL though and should apply any matching :target rules, such that each my-elements' debug div should be visible.
If this were the case it would make for some interesting possibilities for sharing page state across all components, such as the debug example above. However, I doubt that is how Chrome is currently implementing things. And I'm pretty sure this Shadow Dom polyfill isn't going to handle things correctly as it basically shoehorns everything into the page's Dom tree and that would break the html specification.
Just curious if anyone has an answer for how this should work and how it works today...
(edited from my pc to add formatting... hard to do from my phone)
I think you can see the shadow DOM like a nested document. CSS can't address elements inside the shadow DOM from the outside (previously existing shadow piercing CSS selectors were deprecated).
This also encapsulates ids and therefore multiple components that contain elements with an id won't cause collisions or duplicates.
If you have the CSS with the :target selector inside a components style, it should be able to address the element with the matching id, otherwise it shouldn't.
So the question that I have is this: what should happen to an element
inside a shadow dom region that has an ID value which matches the
current hash and which is styled with a :target rule?
Adding to Günter Zöchbauer above answer an alternative is to use the Custom Element object when the style is encapsulated, if the style is global it will work just fine. Use the define method to create a custom component as shown in the the docs. This will not encapsulate your elements so be aware that your styles can be shared across files.
So instead of doing this:
const shadow = this.attachShadow({ mode: "open" });
shadow.appendChild(pTag)
Use this:
this.appendChild(pTag);
both previous examples suppose you're in a HTMLElement class or a class that inherits it.

Can't use children with :not pseudo selector

I'm having trouble using some relatively simple CSS selectors using :not. Namely, the following selector is giving me an error:
a:not(.ebook_document *)
I am trying to get all <a> elements that are not children of the element with class ebook_document. This also fails:
a:not(.ebook_document > *)
As well as this:
a:not(.ebook_document, *)
Putting the selectors on their own, not in a :not section works fine. What have I done wrong?
:not only takes a simple selector. (For now, CSS 4 expands that to a selector list.)
Plus, https://developer.mozilla.org/en/docs/Web/CSS/:not -
This selector only applies to one element; you cannot use it to exclude all ancestors. For instance, body :not(table) a will still apply to links inside of a table, since will match with the :not() part of the selector."
What you want is not possible using :not.
You can only go about it the other way around - format all "normal" links, and then apply different formatting for the links inside the target element(s) using .ebook_document a { ... }
So that means rather than not applying styles to those links in the first place, you might need to overwrite the styles you don't like for those links again.
(Or use initial/all to actually reset styles, but browser support for that is still lacking AFAIK.)
Hmm shouldn't it just be a:not(.ebook_document)? I didn't test it but it seems that that should reference all the a tags that don't have a .ebook_document tag.

Find out all elements a given CSS class is applied to?

Does Firebug / Web Developer Tools or any other extension have a function to show me all elements that have a given CSS class attached / applied?
So when I select a CSS class from the source (lets say, in Firebug), I would like to see all elements that have this class applied.
Are you looking for this: https://developer.mozilla.org/en-US/docs/Web/API/document.querySelectorAll ?
Basically you may find elements matching a certain selector like this: document.querySelectorAll('.firstclass.secondclass')
There are two native DOM functions you can use to achieve this:
document.getElementsByClassName()
document.querySelectorAll()
Both are supported by all major browsers for quite some time now.
Examples:
document.getElementsByClassName("firstClass secondClass")
document.querySelectorAll(".firstClass.secondClass")

Having trouble with attribute != selector

The question is simple, the answer maybe not.
I'm trying to apply several styles to all input elements without an specific id. I use this selector in my CSS stylesheet: input[id!='move'] but unfortunately it's not working either in IE10 or in Chrome.
The curious thing is that this block: input:not(#move) works perfectly in both.
I'm lost because the first block of code is supposed to work as far as I understand how these kind of selectors work.
Any ideas?
That is a non-standard attribute selector invented by jQuery. It's not part of the Selectors specification, so it won't work anywhere outside of jQuery (this includes things like document.querySelectorAll()).
Strictly speaking, the direct equivalent of jQuery's input[id!='move'] in standard selector syntax is input:not([id='move']), with an attribute selector. But since you're looking to match elements without a specific ID, input:not(#move) is fine.