Web component and shadow root - web-component

I create a web component with this code where I use template:
let tmpl = document.createElement('template');
tmpl.innerHTML =`<style>
div {
color: green;
display: inline;
margin: 3px;
}
p {
border: 1px solid black;
}
</style>
<p>
Hello my name is:
<div>Web</div>
<div>Component</div>
</p>`;
this.shadowRoot.appendChild(tmpl.content.cloneNode(true));
But in shadow root from console I see this content which not the same:

It has nothing to do with Shadow DOM or Custom Element.
Actually the same behaviour happens with normal DOM : you cannot insert a <div> element inside a <p> element. The latter only accepts phrasing content.
See SO question: Why <p> tag can't contain <div> tag inside it?

Related

Styling does not all apply [duplicate]

This question already has answers here:
Why can't I use a heading tag inside a p tag and style it with CSS?
(5 answers)
What's the difference between CSS classes .foo.bar (without space) and .foo .bar (with space)
(6 answers)
Closed last year.
I want to override the css of <h1> and <h2> using selector (specific using selector only) but it's not working. It's getting only applied to one class only <h1> color changes to green not <h2>.
Please help can someone tell me where I am wrong. Please help!
.temp {
color: blue;
}
.temp2 {
color: red;
}
p .temp,.temp2{
color: green !important;
}
<p>
hi there this is a test page
<h1 class="temp">heading inside p tag</h1>
<h2 class="temp2">2nd heading inside p tag</h2>
</p>
Try this:
.temp {
color: blue;
}
.temp2 {
color: red;
}
div .temp,
div .temp2{
color: green !important;
}
<div>
hi there this is a test page
<h1 class="temp">heading inside p tag</h1>
<h2 class="temp2">2nd heading inside p tag</h2>
</div>
.temp {
color: blue;
}
.temp2 {
color: red;
}
span .temp, .temp2{
color: green !important;
}
<span>
hi there this is a test page
<h1 class="temp">heading inside p tag</h1>
<h2 class="temp2">2nd heading inside p tag</h2>
</span>
Answer:
putting h1/h2 content inside p is invalid (You might have noticed in Stack overflow's snippet editor)
Imagine having a huge heading inside small paragraph
so change to span/div/etc (in html+css)
You have missed to mention the paragraph element for temp2
.temp {
color: blue;
}
.temp2 {
color: red;
}
p .temp,p .temp2{
color: green !important;
}
<p>
hi there this is a test page
<h1 class="temp">heading inside p tag</h1>
<h2 class="temp2">2nd heading inside p tag</h2>
</p>

Applying css to Django generated form objects for textarea

The following screenshot shows the forms.py code for generating the textarea input box on the right-hand side (which has placeholder text: "Your comment to the world").
The CSS however, is applied only to the pure HTML textarea box (to the left) and I cannot figure out how to get it to be applied to the Django generated textarea input box. You'll notice that the CSS has been automatically applied to the top 'Name' text input field.
The styles.css code is here:
body {
background-color: white;
}
h1 {
color: red;
text-shadow: 3px 2px grey;
font-family: Arial
}
p {
color: black;
font-family: Arial
}
input[type=text] {
width: 20%;
padding: 21px 20px;
margin: 14px 0;
box-sizing: border-box;
font-size: 33;
border: 2px solid red;
border-radius: 4px;
font-family: Arial
}
textarea[type=textarea] {
width: 20%;
padding: 21px 20px;
margin: 14px 0;
box-sizing: border-box;
font-size: 33;
border: 2px solid red;
border-radius: 4px;
font-family: Arial
}
forms.py (as shown above with the rendering of HTML) is below
from django import forms
class CommentForm(forms.Form):
name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'placeholder':'Your Name Please'}))
comment = forms.CharField(widget=forms.Textarea(attrs={'placeholder':'Your comment to the world'}))
And finally, the sign.html page (with the HTML for the relevant page) is below
{% load static %}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{% static 'guestbook/styles.css' %}">
</head>
<body>
<h1>Tell the world how you're doing!</h1>
<h2>Sign the guestbook</h2>
<form action="/action_page.php">
Enter your name:<br>
<!--<input type="text" name="name" placeholder="Your Name here">-->
{{form.name}}
<br>
Enter your comment:<br>
<textarea name="message" type="Textarea" placeholder="Your comment here" rows="10" cols="30"></textarea>
{{form.comment}}
<br><br>
<input type="button" value="Submit">
</form>
<p>If you click the "Submit" button, the form-data will be sent to a page called "/action_page.php".</p>
<p>Go to the guestbook itself</p>
</body>
</html>
Essentially, I would like to know how to simply create an HTML object (that is functional) and apply the CSS to it.
So If I am understanding the question correctly, you are having no issue applying CSS to HTML you hard code, and it is the HTML that is generated with Django's templating system that you are having trouble getting your CSS to stick to yes? I would inspect the rendered HTML of that django generated "comment" field. I think you will find that your CSS rules are not applying because the HTML is not what you expect. In other words, your selector: textarea[type=textarea] is not matching the comment field because it is probably not a textarea, or does not have a type=textarea attribute.
You can add attributes in the widget definition itself if you are having trouble getting a CSS rule to stick, but I use This library a lot. It let's you add attributes in the template.

Angular parent form-control Bootstrap / CSS is not applied to child component

I created a autocomplete child component that I am using in parent. In parent when try to apply the validation using Bootstrap form-control it's not getting applied to this child component - which is an input box with a list, although it's getting applied to other controls which are not child.
Child component HTML:
<div class="searching">
<input type="text" class="form-control" (input)="getFilteredData(inputBox.value);" class="form-control" [formControl]="inputBox">
<div id="search" tabindex="0" >
<ul class="suggestionList">
<li *ngFor="let result of filteredResults | async" (click)="onUserSelected(result)" >{{result[displayField1]}} | {{result[displayField2]}} {{result[displayField3]}}</li>
</ul>
</div>
</div>
Parent component:
<app-auto-complete formControlName="requestorId"
[ngClass]="{ 'is-invalid': submitted &&
requestorId.errors }"></app-auto-complete>
<div *ngIf="submitted && f.requestorId.errors" class="invalid-feedback">
<div *ngIf="f.requestorId.errors.required">Requestor ID is required</div>
</div>
Child CSS:
.searching {
width: inherit;
position: relative;
}
.searching input {
margin: 0;
padding: 0;
width: 100%;
height: 30px;
}
.suggestionList {
background-color: #fff;
width: 100%;
position: absolute;
padding: 0;
left: 0;
z-index: 1000;
}
.suggestionList li {
list-style-type: none;
border: 1px solid #c5c5c5;
cursor: pointer;
left: 0;
font-family: Arial,Helvetica,sans-serif;
font-size: 1em;
text-align: left;
}
I have several workaraounds in mind, so I hope any helps.
As mentioned in the comments, add in your parent component decorator the property 'encapsulation' (same level as 'selector' and such) with ViewEncapsulation.None.
Be aware that this approach makes styles of the parent component penetrate the whole app, so be wary with doing this unless you have the parent selector be really specific such as .my-specific-parent-selector-which-isnt-gonna-be-repeated
use #Input property on child component to pass the validation boolean, and apply the class directly according to the Input passed.
add a .parent-selector .is-invalid selector to parent, and then add behind it a ::ng-deep .parent-selector .is-invalid making that specific styling penetrate child classes. Be wary that this approach is deprecated though, so it might stop working in the future (although unlikely)
Note:
also note that you are applying the is-invalid class to a selector.. if you inspect with chrome web browser you will see that this selector usually is a different element that where you try to add your class... so maybe your best approach is using inputs

Polymer 2 styling an element's child node from an outside stylesheet

Let's say that I have a custom web element called <my-course> with its own style defined in the <style> tag inside the definition and I do not want to alter this element's file at all as it's an external dependency of my project.
This <my-course> element has a <div> child defined in the <template> tag.
Example:
<dom-module id="my-course">
<template>
<style>
::host {
padding: 5px;
background: rgba(0,0,0,.2);
}
div#progress {
height: 20px;
width: 100%;
background: red;
}
</style>
<h1>This is my custom course element</h1>
<div id="progress"></div>
</template>
<script>
class MyCourse extends Polymer.Element {
static get is() {
return 'my-course';
}
}
window.customElements.define(MyCourse.is, MyCourse);
</script>
</dom-module>
I want to make the div#progress green with "background: green;" (it's red by default) via an external stylesheet that is loaded in the same page as the custom element is attached/used.
I tried to do:
my-course div#progress {
background: green;
}
But it does not work, the progress div keeps being red. There seems there is no way to style the shadow dom from outside the element itself, I've tried my-course::content div#progress, and has no result (/deep/ and ::shadow are deprecated) I previously achieved this using ::shadow.
Anyone can help? Thanks
You should use CSS variables, such as:
::host {
--progress-background: red;
padding: 5px;
background: rgba(0,0,0,.2);
}
div#progress {
height: 20px;
width: 100%;
background: var(--progress-background);
}
And to overrride it:
my-course {
--progress-background: green;
}
More info here: https://www.polymer-project.org/2.0/start/first-element/step-5

Should module child elements be nested in module modifiers?

When writing css using BEM if you need to make changes to a module element when it is in a sub-module do you nest the module-element in the sub-module or create a new class name for the module-element?
Creating a New Class
Creating a new class name(i.e. module--modifier__element) seems to be more in the spirit of BEM. It prevents unnecessary specificity. But it also adds a lot of extra work adding an extra class to each element within the module.
Nesting
Nesting the existing element class within the module modifier(i.e. module--modifier module__element {} will add some extra specificity but saves you a lot of work(at least for large modules) and makes the markup easier to maintain. For example if you needed to change the modifier of a module you would only have to change it one place in the markup rather than having to change it on every child element.
In addition to that if not all of the child elements change then you will have to refer to the css to figure out which child elements need a class added to them.
EXAMPLE CODE
.module {
display: block;
width: 90%;
height: 2rem;
margin: 2rem auto;
padding: 0.5em;
background: #fff;
border: 2px solid #333;
}
.module--modified1 {
background: #333;
border: none;
}
.module--modified2 {
background: #baa;
border: 3px solid #8f8;
}
.module__element {
color: #333;
text-align: center;
}
/* Option 1 */
/* In sass this would actually be nested within the module_modified1 block */
.module--modified1 .module__element {
color: #fff;
}
/* Option 2 */
.module--modified2__element {
color: #fff;
font-size: 1.3em;
}
<div class="module">
<div class="module__element">Module</div>
</div>
<div class="module module--modified1">
<div class="module__element">Module Modifier 1</div>
</div>
<div class="module module--modified2">
<div class="module__element module--modified2__element">Modulue Modifier 2</div>
</div>
Both options are valid. Reduce the specificity is a good practice, but make the code simple is also a good practice.
However, BEM blocks have to be context-free. If a block can be recursively included into itself, then cascades must be avoided. For example, a generic block fun-rounded-block could be recursively reused like this:
<div class="fun-rounded-block fun-rounded-block--blue-version">
<div class="fun-rounded-block__content">
<div class="some-block-here">
<div class="fun-rounded-block">
<p class="fun-rounded-block__content">element in the sub-block here</p>
</div>
</div>
</div>
</div>
In this example, you cannot use a cascade for styling elements because the selector .fun-rounded-block--blue-version .fun-rounded-block__content would interfere with the sub-block.

Resources