How to apply style to HTML subdocuments? [duplicate] - html

This question already has answers here:
How to apply CSS to iframe?
(28 answers)
Closed 6 years ago.
I tend to apply my own custom CSS documents to certain sites, since I prefer dark backgrounds with light text as opposed to the vice-versa standard, and very few sites have a "dark mode" or otherwise cater to that preference, this site itself being an excellent example.
However, I was recently stricken by something odd - an entire HTML document nested inside of another one. (I now understand this is achieved via use of an <iframe> and so it's nearly impossible to style without JS or something) I can only apply the custom stylesheet to the parent document, though.
So, long story short, I'm wondering what sort of selectors I would have to use to target elements of the nested document only - for example, selecting the <body> of the nested document. Would I refer to a body in a html in a !DOCTYPE that is also in a body? What about recursively nested documents?
Whether this nesting thing is poor practice or not does not immediately concern me -- there seems to be a valid use case for it and, regardless, I'm not building the site. What I DO care about is how to add styles to it externally.

Assuming you literally have a document that has been 'injected' into another document, you would simply target it with the expected identifiers:
To target elements unique to the sub-document:
body body [element] {
}
To target elements that exist within both documents, you would just use the standard:
[element] {
}
The above would apply the style to any desired element that is contained within either document.
Please be aware that you cannot style an iframe inside a document with CSS -- you'd either have to find a way to manipulate the iframe's CSS itself, or use JavaScript to target the desired elements with document.getElementById().
Hope this helps! :)

Related

Add html element that is "invisible" or skipped by CSS selector rules

I want to build an external GUI that operates on a generic HTML piece that comes with associated CSS. In order to enable some functionalities of the GUI, I would need to create some "meta" HTML elements to contain parts of content and associate them with data.
Example:
<div id="root">
<foo:meta data-source="document:1111" data-xref="...">
sometext
<p class="quote">...</p>
</foo:meta>
<p class="other">...</p>
</div>
This HTML is auto-generated starting from already existing HTML that has associated CSS:
<div id="root">
sometext
<p class="quote">...</p>
<p class="other">...</p>
</div>
#root>p {
color:green;
}
#root>p+p {
color:red;
}
The problem is, when adding the <foo:meta> element, this breaks CSS child and sibling selectors. I am looking for a way for the CSS selectors to keep working when encapsulating content in this way. We have tried foo\:meta{display:contents} style, but, although it works in terms of hiding the meta element from the box renderer, it doesn't hide it from the selector matcher. We do not produce the HTML/CSS to be processed, so writing them in a certain way before processing is not an option. They come as they are, generic HTML documents with associated CSS.
Is there a way to achieve what we are looking for using HTML/CSS?
To restate, we are looking for a way to dynamically encapsulate parts of content in non-visual elements without breaking child and sibling CSS selectors. The elements should only be available to DOM traversal such as document.getElementsByTagName('foo:meta')
If I understood your problem correctly.I would suggest using the space between the grandparent and the child instead of a '>'. Also your selector is an id and not a class.
The selector you have put in selects the next level child that is the children. But adding the space in between enables you to select grandchildren too!
so you have do is this
#root .quote {
color:green;
}
Let me know if this helped.
A working css is here
So, after much fiddling and research, we came to the conclusion that this can't be done, even with ShadowDom, as even that would require massive CSS rewrites that might not preserve semantics.
However, for anyone stumbling upon this question, we came to the same end by employing the following (I'll be short, pointers only):
using two comments to mark where the tag would start/end, instead of an XML tag (eg. <!--<foo:bar data-source="1111">-->...content...<!--</foo:bar>-->)
these pointers work more or less like the markup equivalent of a DOM Range and they can work together with it.
this approach has the interesting advantage (as opposed to a single node) that it can start and end in different nodes, so it can span subtrees.
But this also breaks the XML structure when you try to recompose it. Also it's quite easy by manipulation to end up with the range end moving before the range start, multiple ranges overlapping etc.
In order to recompose it (to send to a next XML processor or noSQL XML database for cross-referencing), we need to make sure we avoid the XML-breaking manipulations described above; then, one only needs to convert encapsulated tags to regular tags by using string manipulation on the document (X)HTML (innerHtml, outerHtml, XMLSerializer) to get a clean XML which can be mined and cross-referenced for content.
We used the TreeWalker API for document scanning of comments, you might need it, although scanning the document for comments this way can be slow (works for us though). If you are bolder you can try using xPath, ie. document.evaluate('//comment()',document), seems to work but we don't trust all browsers comply.

Is it possible to select an element's attribute with a CSS selector?

I'm looking for a way to use a pure CSS selector (not script) to select an element's attribute, not the element itself. I know XPath can do it but can a CSS selector?
Example, given:
<img alt="image" src="photo.jpg">
Can I get to the src attribute with a CSS selector?
Update:
I don't want to set any element's values, I just want to select the text "photo.jpg".
Because CSS selectors originated as a fundamental part of CSS, and CSS can only apply styles to elements (since attributes are just element metadata, not standalone objects), CSS selectors cannot match attributes alone within CSS.
But I suspect you're not actually asking about CSS here. You're asking about selectors alone. You're probably using a web automation tool such as Selenium or one of the numerous HTML parsing libraries out there that support either CSS selectors or XPath. Some of these libraries support non-element selectors in the form of pseudo-elements such as ::attr() (I don't remember which ones), you haven't mentioned which tool you're using so I can't tell you for sure if you could use it. Note that this is not the same thing as the CSS attr() function mentioned in the comments — that is a CSS function, which is a value, not a selector, and therefore it cannot be used in a selector.
But if your library doesn't have such a feature then you'll need to either select the img element directly and query its src attribute separately (again, how you do this depends entirely on what you're using, which is why it helps to be specific about this sort of thing), or use XPath if possible.
CSS Tricks has an article that I believe answers your question:
https://css-tricks.com/almanac/selectors/a/attribute/
If you are trying to set the value of a certain element attribute using css, I'm pretty certain that is impossible for anything other than the content property.
CSS is not a programming language and can't process data.
Its sole purpose it to tell the browser how a certain element should look like, like in coloring a text red.
To process data in a web page you use javascript, which can make use of CSS rules though, to grab a certain type of elements in a web page, for example this, which will return a list of all elements of type img
var imglist = document.querySelectorAll('img');
Now, having a list you can loop through it and get each src like this
Array.prototype.slice.call(document.querySelectorAll("img")).forEach(function(img) {
var imgsrc = img.src;
// imgsrc now holds the image url, in your case "photo.jpg"
});

Is it possible to select an element based on the current page using only CSS?

considering I have a single css file for my entire website (and that doing so is an usual technique), I was wondering if there is a way to select website-wide attributes like body (or any other attribute in fact) according to the current page using only css.
Something like
body:in('index.html') {
some properties;
}
body:in('contact.html') {
other properties;
}
Again, css only. I know the simple solutions using things like php, js, jquery...
Selectors have no information about the document beyond what is presented in the DOM tree, and the DOM does not expose information about the page according to its file name, URL, or any other such properties.
Historically there was a #document at-rule for querying the current URL, but it was removed from the Conditional Rules Level 3 module. The most likely reason for this is the lack of cross-vendor implementations, as the only known implementation exists in Gecko, as #-moz-document. It's so bad, that the only uses for it that you'll spot in the wild are not to apply CSS based on a certain page, but solely as a CSS hack for Firefox.
As you've stated, the simplest workaround for this is to have each page apply a unique class to the html or body element and select according to that class, whether via hardcoding, or dynamically.
you could add and id atribute to the body tag and style things inside it using:
body#contact div{
background:#376;
color:#857;
/*etc*/
}
more information about selectors in http://www.w3.org/TR/css3-selectors/

Should we be applying CSS to <body> vs. <html> elements? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should global css styles be set on the html element or the body element?
There's some really interesting discussion about applying CSS to <html> and <body> in order to get some cool effects — like two background images, one transparent (but CSS3 may render that useless).
However, for the standard cases, which element is most appropriate to use for appling page-wide CSS to?
Perhaps there's even some CSS properties that are better suited to one selector over the other? Thus, split among the two?
(This concerns things like cross-browser compatibility, as well as proper semantics according to spec.)
And we can also bring the wildcard * { } selector into this discussion.
Following Verandaguy's answer, http://www.w3.org/Style/Examples/011/firstcss.en.html applies the style to the body. It doesn't say why, but, that's what it says.
I believe that the W3C recommends that you apply any page-wide styles to the <body> element.
For creating a site with several pages it is best to use the CSS as an external linked page. That way each page can have access to it. But for a single page to page, it would be a "cool effect" on some browsers. But in the same effect other computers might see those effects in a different and less rendered method. Stick with uses the CSS mostly as an external link, and use style tags only as needed, or leave a note on the page of how and what browser they are supposed to view it on.

When functionalities of html attributes and css styles overlap

1) If inside CSS file we specify the following style:
td
{ text-align:center; }
While in a Html file we have
<td align=”right” … >
then value set in CSS file will take precedence over an inline html attribute and thus elements contained inside <td> cell will be aligned to the center.
a) Is same true for all html attributes? Meaning if a CSS rule and an html attribute functionalities overlap , will the CSS rule always take precedence?
BTW – I know we should usually prefer using CSS rules vs html attributes
thanx
Which set of definitions, HTML attributes or CSS properties, take precedence?
The textbook answer:
CSS properties take precedence over HTML attributes. If both are specified, HTML attributes will be displayed in browsers without CSS support but won't have any effect in browsers with CSS support.
(Reference: http://www.hwg.org/resources/faqs/cssFAQ.html)
The real-world answer:
It depends, if you want to be certain for a specific attribute or set of attributes, you will have to create a unit test and apply those tests to the specific browser(s) that you want to verify for compliance with the "textbook" answer, or compliance to your specification for the specific project you are working on.
You already imply that you know certain HTML attributes are deprecated, so I will not belabor that point here.