I use Mui (material ui) List and in the ListItem I have a custom component that's a bit complex (has other components + states, can collapse or expand, etc.).
I use react-jss (injectSheet(styles)(component)), and I see that for every element that I am adding in the list, there is a new Css that's injected into the page header.
I thought that there is a caching added in react-jss but it looks that I was wrong.
Could you please advice how can I cache the Css using react-jss? Also, if this is not an option, and I have to use jss + plugins then an example of jss setup with caching plugin will help.
Thanks for the help!
Static styles injected through react-jss are reused between all component instances. If you use function values (dynamic styles) there will be no reuse as you can have different values on each element.
Related
I want to create a web component using svelte. To create a web component it's necessary to include the svelte tag option
<svelte:options tag="{"my-custom-component}"></svelte:options>
It creates a custom component with that name but doesn't work properly because we have to provide this tag for all the child components as well! I added it to all the child components but it still doesn't work, turns out I use third-party libraries and I don't know any way to have that option there!
Is there a way to create the custom components with svelte which includes third-party libraries?
You can use regular svelte components (including third party) ones inside your component.
But you'll need to compile those with different compiler settings in your rollup/webpack config.
And due to the nature of scoped styling in web components (Shadow DOM) the css won't work in these components. So it depends on the library if it still works.
You might be able to turn off scoped styling in the future:
Issue #1748: Custom element without shadow DOM
But scoped styling could have been the reason why you wanted/needed webcomponents in the first place.
This is one of those "what should we do about this"-questions. As you know, web components are supposed to be small, contained applications for websites. However, sometimes these needs to be styled depending on the site they're embedded on.
Example: "Sign up to our newsletter"-component. This component would have a few key items:
An input box
A button
Maybe recaptcha
A method that talks to your service once the button is pressed (passing in the email)
We're going to use Google and YouTube as examples. Google's color scheme is blue (let's imagine that) and YouTube's color scheme is red. The component would then be something like <newsletter-signup></newsletter-signup> on the page you're embedding it in. Both Google and YouTube have this.
The problem comes in, when the component needs to inherit the styles from Google and YouTube. A few deprecated CSS selectors would be great for this, because Google and YouTube's style sheets could simply enable colors for the Shadow DOM, so we wouldn't have to copy/paste the styles. The component should theoretically not know anything about the styles from the host, because we want it to inherit from the host (Google and YouTube).
At the moment, I'm creating a web component using Angular 6, which has a lot of styles, because it has a lot of elements. I'm copy/pasting styles, Bootstrap, icons, and so on from the host site, then styling them based on <newsletter-signup brand="google"></newsletter-signup>. So if the brand is Google, the colors should be red, for example.
This is really bad, because of a few reasons:
Styles have to be updated on both the web component and on the host
Duplicated code is never a good idea
If all the styles are copied 1:1, the amount of bytes required for styles is doubled
How would I, as a developer, take this into account? How do I make styles on the host, then apply them on my web component (call it inheritance)? I'm sure someone has had the exact same problem with Shadow DOM as I am experiencing. Thanks for reading.
I realize you do not want to write same kind of rules for your common component(selector)
i.e. you want to do styling as where your common selector is placed.
Things you can do to handle this:
1. Create your own logical css framework
Write most commonly used CSS rules in global css.For example if you have integrated bootstrap and you want to override bootstrap, you will write most common overrides in app.css which overrides bootstrap.
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles/app.scss"
],
This app.scss should be written in way to which you can override.
Send Rules as input
send custom rules Obj and use in elements you want to override.
<newsletter [input]="customRulesObj"></newsletter>
component.ts
customRulesObj = new CustomRulesClass();
customRulesObj.color = 'red';
You can send rules in input in various component by creating a common class
as you know where you are embedding this component.
Extend this component from a common component
If you are too concerned for css you can extend your component from a common component which provides you with css logic as per need.
export class NewsLetterComponent extends CSSComponent implements OnInit
{
}
css-component.ts
In this component can logically define css as per host, current routerlink and
other multiple if else condition.
You can define rules by switch case conditions and bind those rules to component you have extended.
One of the biggest must-do's of web components is: My host (page where I'm embedding my web component) should not depend on the web component nor know about the web component.
What this basically means: Styles of my web component should not be shared with the host.
If my host decides to update the styles, it should affect my web component. Not the other way around. To solve this, I imported the external styles from my host directly inside the CSS file using #import. Here's an example:
import url("https://my-host.com/styles/core.css");
my-component {
//all styles goes here
}
I did this using SASS but can be done using regular CSS.
This is not a great solution at all, but it does what I want: Inherit the styles from the host. Although I would have to import every stylesheet there is, it still works.
A downside to my solution: When I load the page, it will send a request to the style from the <link> element inside the <head>-tag my host, but also to the style inside my import. So the styles are loaded twice. For our application, which is internal use only, it doesn't matter if we request additional ~200 KB data.
This question is a few years old and the situation has changed. The way to share styles with web components is now to use link tags to a shared stylesheet.
Inside each component:
<link rel="stylesheet" href="https://my-host.com/styles/core.css">
Reference:
https://github.com/WICG/webcomponents/issues/628
I have a jsp page which I want to style using Materialize framework, but as soon as I add the href to materialize.min.css in my page (or in the entire project from the beginning), it overrides my existing styles from all the application and I want to be able to call Materialize only when I need it, not to change the whole style because it becomes a mess.
It's also the first time I'm using Materialize, so maybe I'm missing something.
That's how CSS frameworks work, generally. Most of them will normalize and apply a base style to your website, even if you are not using framework specific class names.
I usually work the other way around: I let my framework of choice control all of my UI, and when I want to override something, I use custom CSS styles. To do that, make sure you add a link to your own styles on the tag after the Materialize CSS link.
I'm working on a web application which is using Materialize as a front-end framework along with Kendo UI for the grid component.
I'm hitting problems in cases where both Kendo UI and Materialize have styles for the same element - for example they both override the styling on check boxes - this results in a broken layout due to the clash.
One option I realize is to pick either Materialize or Kendo UI and drop the other... however I would like to avoid this if possible as they in the most part have complemented each others weaknesses well.
If it was simply one element here or there putting specific overrides in would be an option however with the scale of the two frameworks this would be a maintenance nightmare as when one changed the overrides would possibly have to be refactored.
Are there any ways to solve this issue that I am missing?
One way to workaround such a clash is to build your MaterializeCSS to include only the parts you so need for your project.
For instance, if you do not need the buttons styling of MaterializeCSS, you could simply, via sass, compile the materialize.scss and cherry pick buttons out of the file.
If going down the path of building your custom .css of Materialize is a long short for you, you can try using materialize.khophi.co (Disclaimer: I built it).
Find more about how to customize your MaterializeCSS: http://materializecss.com/getting-started.html
I know it's usually suggested not to duplicate code, and you want to try steering away from overrides, but would it be possible to find the section of css you like (i.e. select box from materialize) and copy that in to a new custom css file, renaming the selector so you can use it seperately from Materialize/Kendo UI?
You can manually edit the stylesheet of eighter party. Take the non-minified CSS, and prepend every base path with a short prefix:
.card {
....
}
becomes
.mat.card {
....
}
That way, for every materialize style, you use .mat before anything. Or, if you mainly use materialize, do the same thing for Kendo UI.
This is a lot of pain, but would solve your issue.
I'm looking for suggestions or pointers to best-practices for segregating classes used for browser styling from those used for dom manipulation.
More specifically, we're creating a single-page, backbone.js webapp that utilizes jQuery extensively for updating page elements dynamically (adding, hiding and appending new content to the page). The problem we're running into seems to originate with the overloading of the class attribute - it's used for styling presentation, AND for identifying page elements for GUI app logic via jQuery. This causes problems when it comes to modifying styles as there is no obvious way to know whether a given class (or DOM element for that matter) is required by the underlying javascript application.
In other words, if someone naively changes or removes a class on a tag, assuming they are only modifying presentation, it breaks the application. I'm looking for a way to separate these concerns - to keep the classes used for jQuery selectors separate from those used for CSS styling. I'm assuming this is a 'solved problem' as we're obviously not the first to write a javascript heavy webapp. Is there a standard way to deal with this? Am I missing something obvious?
The good way to do it probably not to use css classname for binding JavaScript logic at all. HTML5 introduces a way to add custom user-defined attributes for tags. To do it you simply add attribute to tag but start it's name with "data-" prefix. For example:
John Doe
jQuery, starting from 1.4.3, have build-in methods to work with such attributes using .data() function. You can read about it in more details here: http://api.jquery.com/data/#data-html5
If it is necessary for your app to use classnames as pointer for some reason, then you can make following convention:
Classnames starting with "js-" prefix are only used buy scripts to identify html elements, and you can't use them for styling. So this way your elements will have multiple classes on each element (some for styling, some for logic):
John Doe
This way classes without prefix can be removed without concern, and you can be pretty sure that you will broke something if you remove class with prefix.