How to apply css styles in embed widget - css

I create widgets for sites which I don't own.
After injecting html, I do the following to style the widget:
var style = document.createElement('style'),
stylesString = 'minified css with a prefix for each selector eg. .my-prefix p {... }',
rules = document.createTextNode(stylesString);
style.type = 'text/css';
if(style.styleSheet) {
style.styleSheet.cssText = rules.nodeValue;
} else {
style.appendChild(rules);
}
document.getElementsByTagName('head')[0].appendChild(style);
But on some sites my styles are overridden.
Is there a way to apply the styles more precisely?
I don't want (can't) to use:
iFrame
!important on every property

This is most likely caused by the elements in question either having inline styles on them (for which you will have to use !important to override, if you want to use your current method of adding styles), or having styles with a higher selector precedence.
My suggestion would be to make your selectors more specific by adding at least an id to them - although this is still no guarantee your selectors will still be the most specific. It is entirely down to the quality of the stylesheet on the original site.

Related

Add CSS class to empty paragraphs

Is there a way to add a css class name to empty paragraphs in ckeditor so I can target them with css?
Empty paragraphs in ckeditor are not really empty because they contain a br tag so I can not use :empty to target them.
From what I can see, the good thing is that those <br> inside empty paragraphs have an attribute which makes them easy to target.
In the future, you might use a pure CSS solution like this one.
p:has(> br[data-cke-filler="true"]) {
/* styles here */
}
For now, you either have to style the directly.
Depending on what you're trying to accomplish, maybe applying css to the <br> would suffice.
br[data-cke-filler="true"] {
/* styles here */
}
And if you are able to run javascript in ckeditor. This can easely be done today.
Examples : with jQuery
$( "p:has(br[data-cke-filler="true"])" ).addClass( "MyEmptyParagraphsClass" );
or
$( "br[data-cke-filler="true"]" ).parent().addClass( "MyEmptyParagraphsClass" );
Example : with Native Javascript
var brs = Document.querySelectorAll("br[data-cke-filler="true"]");
brs.forEach(function(br) {
br.classList.add("MyEmptyParagraphsClass");
});
In CKEditor 4, you can have a configuration file.
And you can add the custom config with the options here.
In your case, you might need these options :
config.ignoreEmptyParagraph = false;
config.fillEmptyBlocks = false; // Prevent filler nodes in all empty blocks.
Meanwhile in CKEditor 5, you can try these documentations about Block Widget :
Adding a css class to block elements
Inline and block content

Apply stylesheet to half a page with shadow-dom?

Can I apply an external stylesheet to a specific div/element with shadow-dom or via any other means? I've heard about shadow-dom and I believe it lets you constrain your styles, but that's about all I know.
Specifically, I want half the page to use bootstrap, and the other half to use MUI or something else. This is just to show how my library works nicely with different themes.
I don't want to modify the CSS in anyway to constrain it to a specific element, nor do I want to use iframes.
Yes, you can apply an external stysheet in a Shadow DOM using the #import url CSS rule.
div.attachShadow( { mode: 'open' } )
.innerHTML = `
<style>
#import url( './external-style.css' )
</style>
<!-- other elements -->`
NB: The #import rule must placed at the top of the <style> element.
You can then manipulate the Shadow DOM like a normal DOM:
div.shadowRoot.appendChild( firstSection.cloneNode( true ) )
If your content is already existing in the normal DOM, you can move it with appendChild(), duplicate it with cloneNode() as in the above example), or reveal it with the help of <slot> element:
div1.attachShadow( { mode: 'open' } )
div1.shadowRoot.innerHTML = `
<style>
:host { display: inline ; background: #cfc ; }
::slotted( span ) { color: red ; }
</style>
<slot></slot>`
<div id=div1>
<span>Hello</span> world
</div>
In the last case you'll need to use the ::slotted pseudo-element to change the style of the original DOM, so maybe you'll have to modify already existing stylesheet. The best solution depends on your use case.

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

Setting CSS style with dart

Is there an equivalent for the jQuery $.css function in dart?
I can read the (computed) style of an element, but as far as I can see there is no way of setting a style.
Using Element.style isnt enough ?
myDiv.style.backgroundColor = 'red';
myDiv.style.setProperty('-webkit-cssexperimental','value');
It's also working with a multi elements selector:
querySelectorAll('div').style.backgroundColor = 'green'; //color every div

Is it possible to modify the selectors of CSS rules in externally loaded style sheets?

On a web page that contains an eternal CSS style sheet (loaded via <link rel="stylesheet">), I would like to modify the selector of one of its CSS rules. I can reference the rule with:
var rule = document.styleSheets[…].cssRules[…];
(where … are numbers).
Once selected, I can read its selector and other values:
rule.cssText // 'em { color: red }'
rule.selectorText // 'em'
rule.style.color // 'red'
However, when I try to write one of these, it only lets me write the style object:
// These won’t work
rule.cssText = 'em.foo { color: red }';
rule.selectorText = 'em.foo';
// This will work
rule.style.color = 'blue';
Why doesn’t it let me write .cssText or .selectorText? From what I see in the spec, they are not readonly.
Update: I’ve checked for inline style sheets, too. It doesn’t work either.
At least Firefox implements them read-only.
https://developer.mozilla.org/en-US/docs/Web/API/CSSRule.cssText
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule/selectorText

Resources