How to apply CSS from parent component? - css

There is a React component using Emotion called OtherComponent:
OtherComponent:
...
return <div css={otherComponentStyles}>
<div className='something'>
</div>
</div>
And another component called MainComponent that uses OtherComponent:
MainComponent:
...
return <OtherComponent css={mainComponentStyles} ... />
What happens in this situation is that OtherComponent properly uses otherComponentStyles. But it ignores mainComponentStyles.
But what I would like to do is to apply style to OtherComponent from the level of MainComponent.
I know i can wrap OtherComponent into a div, ad set css=... to the div. But it is a nasty fix of the problem.
Hence the question: how to apply CSS with Emotion from parent component aka MainComponent?

You are not applying those styles to any html tag, it's not <OtherComponent> which is rendering, it's the <div> which is rendering to the page, so you must apply styles to a valid html tag.

Related

Move a child element from shadow dom to light dom on document.ready

I defined a custom-element using web componenet:
<universal-form>
<slot name="inner-input">
</universal-form>
This custom-element itself is placed inside another shadow dom:
<my-dashboard>
#shadow-root
<div id="shadow-container">
<universal-form>
...
<input type="datepicker" id="to-be-exposed" slot="inner-input"/>
</universal-form>
</div>
...
</my-dashboard>
** note: for some of you might suggest putting the <universal-form> inside a slot of the <my-dashboard>, instead of placing it directly into the <my-dashboard> shadow-root, this route is ruled out because of some other implementation requirements.
Now I'd like to be able to style the input#to-be-exposed from the webpage's css file, so it needs to be accessible from the light dom when the document is rendered ready.
What is some best practice to achieve this?
An option would be to drop the shadowDom form the dashboard element in this case as an element that has a shadow attached doesn't have a light dom visible anymore.
The element won't mind that, things that are leaking in are exactly what you want, namely style from the parent window.
Implementation is simple, instead appending elements to the attached shadow append them directly in to the element.
Example of a shadowless element :
class MyElement extends HTMLElement {
constructor(){
super();
this.innerHTML = `elements here`;
}
}

How can I style a sub element of a Fluent UI component in React?

I am trying to style an HTML element inside the component from the Fluent UI React library.
What I want to do is put the "On" / "Off" text to the left of the toggle rather than on the left. When I look at my "compiled" code I can see that the component is translated into:
<div>
<label></label>
<div id="target-me">
<button>
<span></span>
</button>
<label></label>
</div>
</div>
I want to add an inline-flex to the target-me div and set flex-flow property to row-reverse in order to get the button element to the right of the label element. The problem is, I can't manage to target the "target-me" div in my code.
How can I achieve this without rewriting a custom component ?
Thanks!
Ok, well I found the answer to my own question so here it is:
<Toggle styles={{ container: { flexFlow: "row-reverse" } }} />
Essentially you can target different parts of the component (root, container, label..) by using the styles property. Use VS Code's Intellisense to find out what elements you can target inside the component and then just give it some regular CSS-in-JS that you want.

Why doesn't Svelte scope the tag under a class but use individual tag.class to style a component?

When a component has some CSS styles, it is natural to use
.my-component-01 h1 { ... }
.my-component-01 h2 { ... }
to scope the styles, but Svelte uses
h1.svelte-hlsza1{color:orange}
h2.svelte-hlsza1{background:yellow}
Is it more robust to actually scope it under a certain class (the top method) instead, because at least inside the HTML markup, the compiled code can just be:
<div class="svelte-hlsza1">
<h1> ...
<h2> ...
instead of repeating the class name every time. (and I think the specificity is the same: 1 class and 1 tag name).
Because Svelte doesn't require a single top level element.
<!-- no problem for Svelte -->
<h1>...</h1>
<h2>...</h2>
In fact it doesn't even require elements at all.
<script>...</script>
<!-- this is the end of the component (still no problem for Svelte) -->
Whatever... Without a root element, the single wrapping class strategy is not applicable.
Also, doing so would not scope only to the current component, but to the current component and its children. Consider this example:
<!-- Scoped.svelte -->
<style>
span { color: red }
</style>
<div>
<span>I should be red</span>
</div>
<slot />
<!-- App.svelte -->
<script>
import Scoped from './Scoped.svelte'
</script>
<Scoped>
<span>I should not be red</span>
</Scoped>
The <span> in App.svelte is not part of the Scoped component, but it is a child of it, in the DOM.
Note: if scoping to the current component and its children is what you want, the trick is to use the :global pseudo selector:
<style>
/* note that you do need a wrapping element, this time, to do that */
div :global(span) { color: blue }
</style>
The div selector style gets scoped, so we're only targeting children of this component (DOM wise), not above.
You're correct that the level of specificity is the same but this rule:
.my-component-01 h1 { ... }
is assuming that there is an element that wraps the h1, in Svelte this is never the case. There is no default parent HTML element to components and there should not be.
If you inspect this REPL for example; despite one of the h1 tags originating from an imported component both h1 tags are right next to one another in the compiled markup like so:
<body>
<h1 class="svelte-1k0q8ta">This is green</h1>
<h1 class="svelte-1wsvnfu">This is red</h1>
</body>
If the natural way were to be the case then Svelte would have to modify the compiled markup to be something like this:
<body>
<someelement class="my-component-01">
<h1>This is green</h1>
</someelement>
<someelement class="my-component-02">
<h1>This is red</h1>
</someelement>
</body>
This would cause unpredictable results when using css-flex or grid which depend on parent-child relationships. So although the repeated classnames for elements may be annoying for someone who inspects the browser often (most users don't) it's a necessary evil that allows CSS to work as expected.

Add a custom style to the component in Angular

I am still new in angular 7. I have a form with title directive and div. I am trying to set both of them in same row with 49% width in side the form. The div style work fine but in the title component doesn't take the style. the problem is i need to change the title directive only in the current form. is there any way to do that?
many thanks
<form #taskForm="ngForm" (ngSubmit)="onSubmit()">
<my-title [style.width]='49%' [title]="'title.page'" [wikiUrl]='wikiUrl' icon="work">
</my-title>
<div [style.width]='49%'>
<button>Save</button>
</div>
</form>
Add px which almost equals to 49%.
<div [ngStyle]="{'width.px': 490px}">
<button>Save</button>
</div>
If you want to set a width in percent you can also use the following syntax:
<div [style.width.%]="49">...</div>
The real problem however seems to be that the 'my-title' component is not responding to the width rule. This is probably because 'my-title' is not a known html tag and so there is no default rendering behavior in the browser for it.
If you want your component tag to behave like a block element (that is what a div element is rendered like) then you just have to apply the rule display: block; to it.
Since your component tag is not part of your template, but the wapper for it you can either apply the following style to the parent component that is using the 'my-title' component:
/* this will not work inside the css file of the 'my-title' component:*/
my-title {
display: block;
}
...or you can use the :host selector in the css/scss file of the 'my-title' component, which is probably better in this case:
:host {
display: block;
}

Override class of underlying React component

I'm using an existing React component (i.e. Paginate) which itself makes use of some components (ie. Button). Currently, the Button component sets its class to 'X' which is defined in a css file. I'd like to override the properties of 'X' when I'm using the Paginate component. Is there a way this can be done?
I haven't used react, but could you possibly stick a parent div around the paginate component and reference the css as .parent .x { attributes }?
Alternatively, you could provide your own over ride CSS file that's loaded after the react styles.
.parent .x {
/* news styles */
}
<div class="parent">
<div class="paginate">
<div class="x"> x </div>
</div>
</div>

Resources