styling a customElement like an existing element - css

How to style a custom element like an existing element? (For example, apply the document <pre> style to a <special-pre> custom element)
BACKGROUND
typical custom elements are based on the generic HTMLElement, in parts because the is="special-pre" attribute is not supported in all browsers (ie. iOS).
page css detailed rules are not always accessible through code, for example when the main page uses a stylesheet through a CDN (CORS restriction)
I've tried through javascript to filter applicable pre style selectors and create a new rule for the new custom element but I hit a wall with CDN provided stylesheets - CORS restriction prevent access to individual rules.
I also thought of inserting a dummy element and use getComputedStyle(preElement) but it feels like a hack and messes with the user's HTML markup.
Other solutions (::part, css custom properties) require advance knowledge of the document style that will use the custom element.
Note that <pre> is just an example. Looking for a solution in general to make a customElement use a defined user style so that a customElement can be generic enough to be used in different pages with different stylesheets.

Related

How do I "inject" a CSS-class into a lit-element?

lit-element completely encapsulates CSS and the only way to style components is via custom CSS variables.
When using tailwindcss all styles are applied via classes, and I currently don't see a way to inject those classes from the outside world.
What I would like to achieve is to make the custom lit-component completely unaware of tailwind. It should only do the most basic styling but leave the customisation up to the user of the component.
The only solution I see right now is to provide the classes via a property and then apply them using classMap. But I don't know where users would like to apply those classes and adding them to each element is unfeasible (and unmaintainable). In addition, I have my doubts that tailwind would even work in that case due to the style-encapsulation.
It sounds like you want your users to be able add classes to specific parts within the custom element you authored?
If it works with what your component's trying to do, the best way to achieve that would be to place slots in your component and have the user provide the element to fill those slots as children to your component. That way the user directly controls what classes they want to put on it and the styling will apply as the children would be part of the light DOM.
As you've said, providing classes via property would be clunky API and styling won't apply unless you forego using shadow DOM by overriding createRenderRoot which is not recommended.
CSS custom properties are not the only way to allow users to style parts of your component as you can also add part attributes letting the user use ::part() pseudo-element to style them. If your users can write CSS instead of providing tailwind classes, that would be the way to give users some control of styling your component. See https://developer.mozilla.org/en-US/docs/Web/CSS/::part

Gatsby.js: I set up a css rule for body for a template but it works throughout the entire app

I set up a background image with css (background-image) in the body tag of the template so that only shows in the pages generated with it, however that's affecting all 'body's in the entire gatsby.js website.
This is normal behavior. It's not a Gatsby issue. It's how React's templating/code-splitting works.
You are defining a CSS rule in your isolated CSS but it's bundled when the project is compiled (because of webpack) and because of the specificity, it affects all body tag. In the end, your template will be also injected into the output HTML so all the imports in it will also merge in the final output.
The easiest and most straightforward solution I think is to define a <section> (or another tag) just as a direct child of the body for each template/page you want to customize and give a specific class name to apply the CSS only to that template/page. Increasing the specificity is the easiest way to apply.
Soon, in the new Chromium version (99) we will be able to define layered components in order to enhance the specificity and improve that kind of behaviors you've described.

Remote Content - Blocking CSS Overrides

I am working on a system that will allow users to embed content into a web page that they have access to.
Conceptually the user would create a div with a specific id (let's call it "myId") on their page, and include a JavaScript file that I control which would basically inject markup into "myId".
The markup returned would include divs with inline styles to them. I can't allow the users who are embedding this content into their page override the CSS styles.
I've read hundreds of articles and threads about CSS Specificity, !Important, etc. It seems the only true way to block users from overriding your styles is to use iFrames.
Below are three articles a few co-workers and I have been bouncing around.
http://weblog.bocoup.com/3pjs-css-defense/
https://speakerdeck.com/antonkovalyov/achieving-harmony-with-third-party-javascript
http://weblog.bocoup.com/3pjs-css-delivery/
One of the concerns is that iOS will stop supporting iFrames, and honestly we've all been told for years not to use iFrames. While it seems like the perfect and only solution it really does sound "hacky".
Does anyone have any insight into any other solutions? I looked at how linkedIn embeds their "connect with linkedIn button" and they are simply wrapping every property value with an !important (which a) seem super hacky and b) doesn't account for undeclared properties and values).
Your main concern with !important is that they can still override it with a later declaration using the !important keyword.
You are right about iFrames.
So you are not left with a lot of options:
one option is to prepend your own CSS declarations with a custom non-generic package-like name so that the chances the user will override them will be very slim:
.content h1
will become
.my-custom-css .content h1
the other option is to modify their css markdown instead of yours. Prepend each of their declarations with a specific css class and use that class for their div container so it applies to all of its contents.

CSS gets messed when script is injected

I built an extension which, whenever user visits some specific sites, I inject my script on the top of there web pages. I used
document.body.insertBefore(wrapperDiv, document.body.firstChild)
to do so.
Now problem: CSS of injected script gets messed up for each and every site(differ from one site to another).
How should I maintain single css structure for all sites?
You should be able to solve this problem by using unique IDs for your html tags with CSS.
That is, if your DIV CSS properties are interfering with their DIV CSS add a #uniqueNameHere ID to your DIV and set the CSS for the #ID.
This page on the use of the !important keyword may be useful too.
http://css-tricks.com/9462-when-using-important-is-the-right-choice/
Use unique selectors for your elements (be it classes with specific prefix or similarly constructed IDs), but you probably try to include CSS along with your script, which may not be a good idea.
In some cases the inline styling is the best idea - it will overwrite all the styles for your elements and will make sure the outlook of these elements is consistent across different pages.
So, I would say, go with inline styling.
For documentation on how the styles are overwritten in CSS 2.1, please see the following page: http://www.w3.org/TR/CSS21/cascade.html#specificity

wikia template style attribute

I have made some templates on wikia.com, which contain only CSS code (key:value;).
My problem is having another template use these style templates in a style attribute tag.
style="{{MyTemplateStyle}}"
This code does not evaluate as expected. The CSS code is outputted before the element and the style attribute is not included inside the element.
Am I trying something not possible for a wiki ?
I merely want to be able to change styling on certain templates in one place, like regular HTML & CSS pages.
CSS styling specified from the style="" attribute always takes priority over any other css, even if you use !important in a CSS specification.
Therefore any edits you make to your CSS on Wikia will not ever override the CSS specified inside an attribute.
Kim, you were right to switch to classes instead of embedding in-line styles via templates.
The very idea of using templates suggest that this was going to be re-used in more than one place, applying styles to a group or, in fact, a class of elements.
This approach is much simpler to read and maintain (as you only have one, central place to edit), and also, if done right, will enable you to seamlessly change the colour scheme via Special:ThemeDesigner.

Resources