webcomponents - how to apply external css class to webcomponent - css

I am using webcomponents-lite (Polymer) to create webcomponents.
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<link rel="stylesheet" href="styles.css">
<script type="text/javascript" src="/static/js/util.js"></script>
</head>
<body class="dark">
<main>
<edsp-login-form></edsp-login-form>
</main>
</body>
</html>
<edsp-login-form> is defined in js file where it uses lit-html. The definition as follows:
#Define('edsp-login-form', {
style: ``
})
export class Login extends LitComponent {
render() {
return html`
<link rel="import" type="css" href="styles.css">`
<div></div>
}
}
In this code, how do apply css classes from styles.css to a component <edsp-login-form> ?

Option 1: If you're using Shadow DOM, you can't apply external CSS to your component. A solution is to deactivate the Shadow DOM by implementing this in your component:
createRenderRoot() {
return this;
}
Option 2: If you still want to apply external CSS and use Shadow DOM, you can use CSS variables. In your external CSS you can instance the variable using something like:
name-of-your-component-tag {
--variable-name-color: #FFF;
}
and then in your component, you can use the CSS variable:
.my-class {
color: var(--variable-name-color);
}
Option 3: And if you're trying to apply a dark theme, you can use the CSS inside of your component considering the context. In your component you can use CSS like:
:host-context(.dark) .bg {
background: #000;
}

Related

Webcomponents css class not usable in slot

Say i have the following css file:
.testClass{
color:red;
}
And the following index.html file:
<html>
<head>
<meta charset="utf-8">
<title>Portal Demo</title>
<link rel="stylesheet" href="test.css">
<script type="module" src="../build/portal-app.js"></script>
<style>
p {
border: solid 1px blue;
padding: 8px;
}
</style>
</head>
<body>
<i class="fa fa-times"></i>
<portal-app>
<p>This is child cosntent</p>
</portal-app>
</body>
</html>
And inside of the portal-app i have the following code:
import 'sdk-button'
#customElement('portal-app')
export class PortalApp extends LitElement {
render() {
return html`
${this.renderWidget()}
`;
}
renderWidget() {
import("./views/my-test-element");
return html`
<i class="fa fa-times"></i>
<sdk-icon-button text="hello marc"><p slot="icon" class="testClass">hello</p></sdk-icon-button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'portal-app': PortalApp;
}
}
When i run this the color of the .p tag is not red and i can't see the style. however i just add a normal p tag to html the color correctly turns red.
But it seems that inside my slot i am unable to pass the css class that is defined in the index.html can anyone tell me why?
This is expected behaviour as per Web Components Shadow DOM specifications.
In your code
<p slot="icon" class="testClass">hello</p>
This template is part of PortalApp Web Component. Which means this markup is in the Shadow DOM of Portal App web component. No css styles from outside (index.html) in you case can get applied to this markup. vice- versa is also true, i.e, no CSS leak from the component to outside of component will happen

Laravel Mix extract all vue component css to single app.css

I use Laravel Mix to compile and extract component css to single file such as app.css. For example I have a component like this:
<template>
<div class="text"> </div>
<template>
...
<style>
.text{ color: red; }
</style>
In webpack.mix.js is:
mix.autoload({
jquery: ['$', 'window.jQuery','window.$'],
quill: ['window.Quill','Quill']
});
mix.options({
extractVueStyles: 'public/css/app.css',
});
mix.js('resources/assets/js/app.js', 'public/js')
.sourceMaps()
.version();
and I put this code in master..blade.php
<link rel="stylesheet" href="{{ url(mix('/css/app.css')) }}">
But app.css is empty and my component css put in html>head as inline style:
<html>
<head>
...
<style>
.text{ color: red; }
</style>
</head>
...
</html>
What should I do to extract and put all component css in app.css?

How do I apply a custom style to a specific element only?

I'm developing a theme-able Polymer web component. As per the custom-style documentation I'm doing the following:
<link rel="import" href="themes/my-element-theme.html">
<style is="custom-style" include="my-element-theme"></style>
However, this is a blunt instrument as it applies the custom theme to all my elements.
One solution is to scope all my theme styles to a CSS class as follows:
:root custom-element.my-element-theme {
font-family: 'Noto Sans', 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
}
However, this makes it difficult to apply a custom style to a whole document.
Is there a way to apply custom styles to elements more selectively, say using CSS selectors? What is best practice?
You definitely can use selectors to selectively apply styles to your themeable elements.
It's best to use custom properties and mixins and set their values to targeted elements. Here's an example:
<!DOCTYPE html>
<html>
<head>
<link href="http://polygit.org/components/polymer/polymer.html" rel="import" />
<style is="custom-style">
.container1 my-elem {
--my-elem-span: {
color: red;
}
}
.container2 my-elem {
--my-elem-span: {
color: blue;
}
}
</style>
</head>
<body>
<div class="container1">
<my-elem>hello red</my-elem>
</div>
<div class="container2">
<my-elem>hello blue</my-elem>
</div>
<dom-module id="my-elem">
<template>
<style>
:host { display: block; }
:host span {
#apply(--my-elem-span);
}
</style>
<span><content></content></span>
</template>
<script>
Polymer({
is: 'my-elem'
});
</script>
</dom-module>
</body>
</html>
And you can externalize you styles like you did by placing the css rules in a separate styles module.
<dom-module id="my-elem-theme">
<template>
<style>
.container1 my-elem {
--my-elem-span: {
color: red;
}
}
.container2 my-elem {
--my-elem-span: {
color: blue;
}
}
</style>
</template>
</dom-module>
You then import the way you do:
<link rel="import" href="my-elem-theme.html">
<style is="custom-style" include="my-elem-theme"></style>

Sass bootstrap unable to set height of textarea

I have an admin page like this:
<div class="admin_page">
<div ng-repeat="user in users">
<div class="my-form-group">
<textarea class="my-form-control">{{user}}</textarea>
</div>
</div>
</div>
This is my main.scss file:
.my-form-group {
#extend .form-group;
.my-form-control {
#extend .form-control
}
}
#import "./admin.scss";
This is my admin.scss:
.admin_page {
textarea {
height: 200px;
}
}
The height of text area is not set.
I tried <textarea class="my-form-control" style="height:200px">{{user}}</textarea> and it works.
Why is the sass version not working?
Edit:
this is my heading:
<!--underscore-->
<script src="/node_modules/underscore/underscore-min.js"></script>
<!--jquery-->
<script src="/node_modules/jquery/dist/jquery.min.js"></script>
<!--bootstrap (keep the css although duplicate in bundle, since some may depend on it)-->
<script src="/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
<!--font-awesome-->
<link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css">
<!--summernote-->
<link rel="stylesheet" href="/node_modules/summernote/dist/summernote.css">
<!--<link rel="stylesheet" href="/node_modules/summernote/dist/summernote-bs3.css">-->
<script src="/node_modules/summernote/dist/summernote.min.js"></script>
<!--angular-->
<script src="/node_modules/angular/angular.min.js"></script>
<script src="/node_modules/angular-resource/angular-resource.min.js"></script>
<script src="/node_modules/angular-route/angular-route.min.js"></script>
<script src="/node_modules/angular-sanitize/angular-sanitize.min.js"></script>
<!--angular-summernote-->
<script src="/node_modules/angular-summernote/dist/angular-summernote.min.js"></script>
<!--bundle-->
<script src="/public/script/bundle.js"></script>
<link rel="stylesheet" type="text/css" href="/public/style/bundle.css">
Note that I imported sass version of bootstrap in main.scss, which means inside bundle I have the bootstrap css.
The reason I include the original non-sass version bootstrap is for summernote, which depends on bootstrap.
Edit 2:
I tried the following:
.admin_page {
.my-textarea {
#extend .my-form-control;
height: 500px;
}
}
which has a specificity of 0,0,2,0 (2 classes), it doesnot work
Also this:
.admin_page {
textarea.my-form-control {
height: 200px
}
}
which has a specificity of 0,0,2,1 (2 classes + 1 element), it works. Why is the previous one not working?
It is not problem of sass. It is clearly the problem of specificity.
You just need to mention high specificity css. Since you have a class to the textarea, you can do like this:
textarea.my-form-control{
height: 200px;
}
Read this to understand how specificity works in css.

Is it possible to inline a class definition of CSS inside an xhtml file?

Is it possible to inline a class definition of CSS inside an xhtml file?
I mean, to put someting like:
p.first{ color: blue; }
p.second{ color: red; }
Inside my page, not in a separate CSS file.
I think you're trying to put your CSS in the HTML page, not inline.
You can put CSS in an HTML page (usually in the head) by surrounding it in style tags:
<style type="text/css">
p.first{ color: blue; }
p.second{ color: red; }
</style>
Sure, here's an example. However, it is best practice to keep your styles in a separate css file.
<html>
<head>
<title>Classes</title>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
<style type="text/css">
img {
padding:10px;
margin:5px;
border:1px solid #d5d5d5;
}
div.thumb {
float:left;
}
div.caption {
padding-left:5px;
font-size:10px;
}
</style>
</head>
<body>
<div>your page code etc..</div>
</body>
</html>
You can also put css inside the p tag.
<html>
<body>
<p class="first" style="color:blue;"></p>
<p class="second" style="color:red;"></p>
</body>
</html>
The nice thing about CSS is it works in any file not just an HTML,XML file. You just need to define the syle block like this anywhere in the page
<style type="text/css">
<all my styles goes here>
</style>
In HTML and HTML/XHTML, the standard is, you will put this block in the head section. If it is other type of file for example .aspx, or .php, the block still works, even it is not in head block.
Example
<?php
/* mytest.php file */
<style>
<my styles>
</style>
?>
the same is true for ASPX file.
You can also define inline CSS which means CSS goes right in the element tag. The syntax is
<p style="<all my styles>"> My paragraph contain inline CSS</p>
Yes, you can insert CSS styles in the HTML file. For example:
<p>...</p>
<style type="text/css">
p.first { ... }
</style>
<div>...</div>
As you'll find in the literature, it's not considered a good practice though.

Resources