How to get list of custom CSS properties - css

I'm looking into custom CSS properties and have come up with the code below.
If I put the CSS inline using a STYLE attribute on the canvas tag (like this: style="--rgLinewidth: 3" ) then I can get the custom CSS values using the script shown below.
But using a tag, as below, then it doesn't show the custom CSS properties.
Is it possible to? And if so how?
<html>
<head>
<style>
canvas#cvs {
--rgLinewidth: 3;
background-color: red;
}
</style>
</head>
<body>
<canvas id="cvs" width="600" height="250">[No canvas support]</canvas>
<script>
canvas = document.getElementById("cvs");
styles = window.getComputedStyle(canvas);
alert(styles.getPropertyValue('background-color'));
alert(styles.getPropertyValue('--rgLinewidth'));
for (var i=0; i<styles.length; i++) {
if (canvas.style[i].indexOf('--rg') === 0) {
var value = styles.getPropertyValue(canvas.style[i]);
alert([canvas.style[i], value]);
}
}
</script>
</body>
</html>

It does not work because you query for computed style and then attempt to retrieve values of corresponding properties from the inline style, where they do not exist -- your canvas does not define an inline style. You need to query the values through the same styles object where you find the properties.
Consider the following function which when passed an element, will search through its computed style and return the value of the first CSS variable whose name starts with --rg:
function find_first_rg_value(el) {
var styles = getComputedStyle(el);
for (var i = 0; i < styles.length; i++) {
if (styles[i].startsWith('--rg')) {
return styles.getPropertyValue(styles[i]);
}
}
}
(Use like find_first_rg_value(canvas))
The difference between my approach and yours is, as I said, that you attempt to fetch the value from canvas.style[i], but canvas.style is effectively empty. Use styles instead.
Computed style (getComputedStyle), as the name implies, contains "summary" style computed per CSS cascading, inheriting, and so on, with inline style, if any, applied on top (overriding priority). Assigning inline style therefore affects the computed style, but querying inline style only gives you inline style you assigned, no more.
This means that in most cases like yours one would want to use getComputedStyle. Additionally, since CSS variables cannot be queried using style.fontName syntax, you need to use getPropertyValue function for these (all dashes intact in the passed property name), regardless if you are dealing with an inline or computed style object.

Related

What CSS should I write in html template to generate a pdf of a particular height & width

I am generating a PDF using nodejs with pdf-creator-node and I got success.
My requirement is I need to generate a PDF with Height X Width = 926px X 1296px.
I don' know what css I should write to generate this dimension pdf.
right now if I set div or body height and widht with above mentioned dimension I am getting 3 pages
this is what I tried
#page {
width: 1296px;
height: 926px;
}
<div
class="parent-div"
style="
width: 1296px;
height: 926px;
background-color: #faf0e6;
border: 1px solid red;
"
></div>
jsPDF is able to use plugins. In order to enable it to print HTML, you have to include certain plugins and therefore have to do the following:
Go to https://github.com/MrRio/jsPDF and download the latest
Version.
Include the following Scripts in your project:
jspdf.js
jspdf.plugin.from_html.js
jspdf.plugin.split_text_to_size.js
jspdf.plugin.standard_fonts_metrics.js
If you want to ignore certain elements, you have to mark them with an ID, which you can then ignore in a special element handler of jsPDF. Therefore your HTML should look like this:
<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Then you use the following JavaScript code to open the created PDF in a PopUp:
var doc = new jsPDF();
var elementHandler = {
#ignorePDF': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
'width': 180,'elementHandlers': elementHandler
});
doc.output("dataurlnewwindow");
**For me this created a nice and tidy PDF that only included the line 'print this to pdf'.
Please note that the special element handlers only deal with IDs in the current version, which is also stated in a GitHub Issue. It states:**
Because the matching is done against every element in the node tree, my desire was to make it as fast as possible. In that case, it meant "Only element IDs are matched" The element IDs are still done in jQuery style "#id", but it does not mean that all jQuery selectors are supported.
Therefore replacing '#ignorePDF' with class selectors like '.ignorePDF' did not work for me. Instead you will have to add the same handler for each and every element, which you want to ignore like:
var elementHandler = {
#ignoreElement': function (element, renderer) {
return true;
},
#anotherIdToBeIgnored': function (element, renderer) {
return true;
}
};
From the examples it is also stated that it is possible to select tags like 'a' or 'li'. That might be a little bit too unrestrictive for the most use cases though:
We support special element handlers. Register them with a jQuery-style ID selector for either ID or node name. ("#iAmID", "div", "span" etc.) There is no support for any other type of selectors (class, of the compound) at this time.
One very important thing to add is that you lose all your style information (CSS). Luckily jsPDF is able to nicely format h1, h2, h3, etc., which was enough for my purposes. Additionally, it will only print text within text nodes, which means that it will not print the values of textareas and the like. Example:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>

Reading class names in a stylesheet

I have an HTML document that uses multiple style tags. One of those styles has the following content
<style id='pstyle'>
.p0010, .p0016, .p0022, .p0028, .p0032,
.p0034, .p0038, .p0042, .p0044, .p0046,
.p0048, .p0050, .p0052, .p0054, .p0056,
{
max-width:100%;
background-size:100%;
background-image: url('sprites.png');
}
</style>
document.styleSheets allows me to access the full set of stylesheets used by the document. From there - once I have grabbed the right stylesheet - I can use the cssRules array attribute to access the selectorText attribute of each contained style. However, I have been unable to figure out how to find the "right" style sheet. Whilst I can give the stylesheet an id this does not turn up as an attribute of the document.styleSheets[n] object.
I do a great deal of DOM manipulation but it is mostly with the visual elements in the document. I'd be much obliged to anyone who can tell me how I go about identifying the "right" stylesheet
A plain English version of the task
a. Find the style element - bearing in mind that there will be others - with the id pstyle
b. Read the class names defined therein and do whatever
I'm not sure to understand if you want to get the stylesheet associated with the <style> element, or if you want to retrieve the element from the stylesheet.
So here you'll get both :
// from the element
console.log(pstyle.sheet === document.styleSheets[2]);
// from the stylesheet
console.log(document.styleSheets[2].ownerNode === pstyle);
<style id='pstyle'>
</style>
note that in the snippet it's [2] because stacksnippet does inject stylesheets
And now to get the cssRules and selectorText, you just have to read it from the selected styleSheet:
var pstyle = document.getElementById('pstyle');
// from the element
console.log(pstyle.sheet.cssRules[0].selectorText);
// from the stylesheets
for(var sheet of document.styleSheets){
if(sheet.ownerNode === pstyle){
console.log(sheet.cssRules[0].selectorText);
}
}
<style id='pstyle'>
.p0010, .p0016, .p0022, .p0028, .p0032,
.p0034, .p0038, .p0042, .p0044, .p0046,
.p0048, .p0050, .p0052, .p0054, .p0056
{
max-width:100%;
background-size:100%;
background-image: url('sprites.png');
}
</style>

Dynamically change element styles via custom properties?

For example, you can change the ink colour in paper-tabs by changing --paper-tab-ink: var(--accent-color);. Is it possible to change the value of the CSS custom properties dynamically similar to how you can toggle a class or change the style in JS?
There are different ways to do this, but a simple answer is to use the Polymer.updateStyles() method after making your class changes.
For example, let's say your styles are:
<style>
.yellow x-example {
--light-primary-color: #fdd85f;
}
.red x-example {
--light-primary-color: red;
}
</style>
and you want to make the component use the styles in the .red class. You simply add it as you normally would in javascript, then be sure to also use this function to actually update it on the page.
<div class="yellow" onclick="this.className='red'; Polymer.updateStyles()">
<x-example></x-example>
</div>
Yes, first get the object of your custom element. Then get the customStyle object. Add a style to that object. And then run element.updateStyles();
t.clickListener= function(e) {
var t = Polymer.dom(e).localTarget; //retarget if needed
t.customStyle['--the-color-etc'] = 'pink';
t.updateStyles(); // mandatory for the CSS variables shim
};
See the docs

How can I apply an external CSS class to a span created with dojo.create?

I'm creating a span in my web page with dojo.create, and need to apply CSS to it. I can see how to apply a style to it in the dojo reference, but I'd rather apply it via the external stylesheet (there's quite a few attributes I need to set and I'd rather not do it inline).
So given the example code below, how would I apply the CSS for the printSpan class?
var node = dojo.create("span", {innerHTML:_text, id:"printSpan", class:"printSpan"}, map);
You can write this in your external stylesheet:
.printSpan { color: red; }
This is called the class selector.
By the way, your code should be:
{ innerHTML : _text, id : "printSpan", "class" : "printSpan" }
Notice the colon was inside the "class" string, though it should be outside and printSpan is a different string.

How to know if element height or width was set in javascript/css?

Is there any way to know if an element height or width was set (not auto) in javascript/css ?
elm.style.height will only return a value if the height is defined inside the element attribute list : <div style='height:200px' .... ></div>, otherwise it will always return an empty string even if you define the height inside a style tag or a css file : .myElmCss{height:200px}.
On the other hand, using window.getComputedStyle() or elm.currentStyle will always return a value even if no height was defined neither inside the element attribute list nor in a css file/style tag.
Thanks.
Check this post How do you read CSS rule values with JavaScript?
To do what you're looking for it appears to be a matter of iterating over the stylesheets to find declared properties. You would probably also cross reference with inline styles like you mentioned in your question.
from #InsDel's post:
function getStyle(className) {
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
for(var x=0;x<classes.length;x++) {
if(classes[x].selectorText==className) {
(classes[x].cssText) ? alert(classes[x].cssText) : alert(classes[x].style.cssText);
}
}
}

Resources