Polymer element without the shadow dom's styling encapsulation - css

I've written a few Polymer components so far and for my more complicated stuff I love how their styling is isolated from the rest of the page. It's been much easier to use them across multiple apps.
However, today I'm creating a super simple component, and I'm realizing that I'd really like to have the page's styles bleed in. I've got a component that packages up a bunch of logic, but just renders a basic <a href> link. Is it possible through CSS or other means to have that link inherit its styling from the rest of the page?

appyAuthorStyles used to be great for this. Unfortunately, it's no longer in the Shadow DOM spec.
Your two solutions are:
Create a small stylesheet (e.g. shared.css) that includes the common rules the page and component use.
Use ::shadow and /deep/ to style the link from the outside, the same way as the page styles its links.

Related

Best way to style non-MUI elements in MUI?

I'm new in React and a new dev in general;
I know that there are many ways to style elements in React itself:
importing CSS,
locally scoped CSS modules,
CSS-in-JS via Styled
Components or Emotion,
utility-first CSS like Tailwind statically
extracted CSS with libraries like "Compiled" and "Linaria",
inline styling
style object variable
and two current APIs to style MUI elements:
Styled and
SX
When it comes to customizing MUI components, it's obvious that it's best to use one of these two; it also seems that using MUI doesn't restrict the use of all non-MUI ways to style things.
So I guess I'm asking about the "best practice", or at least "an ok practice" of minimizing the amount of styling techniques used (so that the code doesn't become bloated).
This, in turn, raises questions that are not answered obviously in the docs:
what's the difference between MUI's styled API and the "styled components" (CSS in JS via emotion that we're talking about) ?
Are there absolutely no conflicts between any of React's styling techniques and MUI APIs ?
are there styling techniques that are conflicting with MUI styling APIs ?
if non-MUI elements shouldn't be styled with MUI APIs, is it then considered a best practice to just style with your one favorite way but stick to this minimum ?
whatever way is best, are there cases when it can't be used solely ?
Example: I need to deal with a non-MUI component: to put it simply, I'm trying to center an SVG which may be either too wide or too thin for the screen and this will change dynamically. All I need is for it to be either 100% height if it's tall or 100% width if it's wide; in such way so that scroll-bars never appear.
As reddit answer says: there turns out to be no conflicts between React's and MUI's ways of styling. You just have to ensure your style’s specificity order is how you want it to be. In large codebases it’s always good to stick to one type of styling, even with MUI. It’s very likely you will need to have some styling for non-MUI components. You could use MUI’s styled(), or css in js or SASS or LESS. There is no one perfect answer - readability, maintainability and performance are your main considerations.
So since MUI's styled() should work for all non-MUI components/elements, I would go with that.

Where is this style attribute on my Angular router-outlet element coming from?

So I've got an Angular app that has pretty basic routing, and I'm using flexbox to layout my components. The issue I can't figure out is with code like this:
<div fxLayout="column"
fxFlex
class="layout__right">
<router-outlet></router-outlet>
</div>
The child component that is routed to contains the following in its SCSS:
:host {
#include make-flex-container(column);
flex: 1;
}
That make-flex-container just applies some flexbox related styles, and works fine in many places of the app. What's happening in my case though is when routing to this particular child component I see a style tag applied to the ng-component element created by Angular. What's causing my problem is for some reason the style includes flexbox items that are overriding what I'm putting in :host:
You can see in the screenshot that my :host styles are being applied, but the styles on the ng-component tag are simply overriding them. For the life of me I can't understand why there's a specific style tag added here, so where the content within it would come from. Does anyone know why Angular would put style tags on the HTML generated for router-outlets? When I navigate to other components at this same routing level this style tag isn't present.
I assume this is an issue with my code, but I just can't run down where to look given what I see.
UPDATE
Here's a minimal reproduction of the issue on Stackblitz:
https://so-48451609-routing-flex-issue.stackblitz.io
In that example you can see how the element created next to the router outlet has styles applied to it. The only dependency added there is #angular/flex-layout, so it's gotta be doing something to cause this.
The fxLayout directive applies styles to child elements. It does this on the element itself to not interfere with other styles.
The #angular/flex-layout library's static API has directives that work either on a DOM container or DOM elements. fxLayout is an example of the former, fxFlex is an example of the latter.
See the docs here, note the two sections for elements and containers: https://github.com/angular/flex-layout/wiki/Declarative-API-Overview#api-for-dom-containers
THEY COME FROM VIEW ENCAPSULATION
I believe that these classes are part of view encapsulation that prevents angular elements from being styled from outside and to prevent interference between view components. At least that is what they say in official docs #angular.io.
As suggested #this SO post the '_ngcontent-c0' is naming of the first component within the host.
ANGULAR MATERIAL IS CAUSING TROUBLES
I have found a bunch of issues related to encapsulation at GitHub and they often seem to be related to using Angular Material, which seems to have encapsulation turned off sometimes somehow. Such as described here. Hence I conclude that your implementation of Angular Material might be at fault. For in depth analysis of what the mechanism of this unwanted interaction is, you might probably like to start by reading joh04667's answer to your question since it provides links to the documentation of the particular material you use.
PROPER STYLING
Common solution to those issues is overriding styles with /deep/ selector as described in both above shared links. A number of unofficial articles on styling Angular app is available as well, such as this one.
IDEA
So the idea is to overwrite the styles in your component with /deep/ like this:
:host /deep/ .your_flex_class {
#include make-flex-container(column);
flex: 1;
}
CONSIDER VALID CSS
Since I think that you use Scss, using /deep/ selector should be ok and should be compiled successfully (I use it quite often to style inline SVGs). However, in a fact, this selector seems to be deprecated as a whole bunch of things related to the issue of Shadow DOM. I believe the correct universal approach would be to use 'shadow-piercing descendant combinator':
:host >>> .your_flex_class {
#include make-flex-container(column);
flex: 1;
}
It should does all the same as /deep/ selector. To explain the mechanism, let me cite from official docs for CSS Scoping Module Level 1
When a >>> combinator (or shadow-piercing descendant combinator) is encountered in a selector, replace every element in the selector match list with every element reachable from the original element by traversing any number of child lists or shadow trees.
Basically, it does not care about the wrapper and bites down to your target to style it. So you have even one more option to try ...
Ok, once I created a working example of this I eventually found the culprit and a suitable work-around. What is happening is within my router child component I'm using fxFlex from #angular/flex-layout to flex the element. I'm applying the flexbox container CSS in the :host{} section of the components CSS, but flex-layout doesn't see this in the rendered HTML and applies the style tag to do a flexbox row layout automatically.
Here's an issue on Github with my comments and a suitable workaround of using !important in my :host{} CSS:
https://github.com/angular/flex-layout/issues/496#issuecomment-360870510

Using react; workflow method for overloading css

I am new to the React javascript framework and have a question about styling using CSS.
Using jQuery, my old workflow was to pick an element on the screen, inspect it in Chrome, note the selector/s that triggered the styling, change the element styling in the browser, and then save it to css/sass etc. If the widget had a hover-state I could make the element visible to see what it looked like.
However using React, and especially for components that someone else has coded, where the component does a 'pop-up' etc, I can't manipulate the DOM to see the component because it is removed from the DOM before I can inspect it.
Now of course I could read the external library code, work out how it works, but CSS inheritance means it would take some time to work out exactly is happening and this seems to be slower than what I was doing before - especially for a simple change.
So my question is, what is the preferred workflow for overloading the CSS for DOM elements that are removed before they can be inspected?

Using CSS animations in React.js

I've been working with React for a little while but animations is one thing that is confusing me.
Currently I use CSS in my react components. Each component imports a single css file that I use for styling instead of using inline css.
My question is: If I have a page like a landing page where there is no state being updated whether it is fine to use keyframe animations and similar things in css?
Side-question: Am I free to use keyframes for a non updating page like a landing page, or will it totally break for more complicated pages?
You are 100% safe to use any CSS you want in your pages. CSS is merely a language used for describing the style and presentation of your elements. React doesn't care about all that; it cares only for the DOM of your page - or at least the part of the DOM that React created/controls.
The Document Object Model (DOM) [...] provides a structured representation of the document as a tree.
CSS doesn't (cannot) interact with the tree structure of the DOM, nor do CSS animations. They just apply style properties to the elements which, depending on the animation, may give the impression that the layout of your DOM tree changes, but this is not the case.
So to answer both your questions: No css will break your code or otherwise interfere with React, regardless of implementation.

apply external CSS to specific area

I'd like to import an external CSS (eg. Bootstrap) into my site-- the problem is I'd like to apply the Bootstrap styles only to a specific region of the page. When I include Bootstrap, it applies its styles to the entire page, restyling all tables, divs, etc.
Is it possible to only apply Bootstrap to a region (say a parent div or something?)
Thanks
The only way to do this is to have a separate iframe for the content you want to style with Bootstrap (unless you want to edit the Bootstrap CSS, and add your outer div's selector to the beginning of EVERY rule).
HTML5 introduced the new scoped attribute, which is made specifically for your use case, but has not yet been implemented by any one of the major browsers.
If you are using jQuery (which you probably are, since all of Bootstrap's Javascript functionality is dependent upon jQuery), you might wanna try Simon Madine's jQuery Scoped CSS plugin.
Import Bootstrap before your own styles. That way your own styles will overwrite the changes made by Bootstrap where applicable.
I've only tried this locally and not given it any thorough testing but it seems to work fine. I created a div around the content and assigned it an id. Then prefixed all of the bootstrap selectors with the id I assigned the surrounding div. The prefixing was done with a couple of search and replace operations. Perhaps it can be done easier with less
Forgot to mention that the body selector of the bootstrap.css has to be replaced with the id and not prefixed like the other selectors.

Resources