Styling
John Peters
Posted on December 31, 2022
In the previous article we introduced the Display-Grid Web Component which supports markup like this:
<display-grid>
<grid-col>Column A
<p>Lorem ipsum...</p>
<a href="SomeURL">Go Here</a>
</grid-col>
<grid-col>Column B
<p>Lorem ipsum...<p>
</grid-col>
<grid-col>Column C
<p>Lorem ipsum...</p>
<p>Lorem ipsum ...</p>
</grid-col>
</display-grid>
Automatic Styling
The idea is to allow for automatic CSS Grid markup; which looks like this, for three columns.
The number of columns are based on the number of <grid-col>
subelements.
In the original article there was a bug related to the shadow root.
We Found a Bug
Not having a full understanding of
const shadowRoot = this.attachShadow({mode:"open"});
We created the shadowRoot the parent (display-grid) and one for each sub-element (grid-col).
The impact of this was indeterminate view rendering; which, was highly dependent on element and child element placement!
The fix was to not open up any shadowRoots!
The Fix
We wanted the parent (display-grid) to set all styling for itself and all it's (grid-col) children.
In the master (display-grid) element, we removed the shadowRoot code like this:
customElements.define(
"display-grid",
class extends HTMLElement {
constructor() {
super();
//const shadowRoot = this.attachShadow({mode: 'open'});
this.SetStyleByColumns();
}
SetStyleByColumns
Then we altered this styling for this (parent) element and all the (grid-col) elements.
/**Based on the number of grid-col elements set up the grid column count to match */
SetStyleByColumns() {
//grid-col is a custom element
let cols = document.querySelectorAll("grid-col");
// numberOfColumns returns something like "auto auto auto" for 3 columns
const textContent = this.getStyleByCols(cols);
this.style= document.createElement("style").textContent=textContent;
for (let col of cols) {
col.style = document.createElement("style").textContent = "padding:2rem;";
}
}
getStyleByCols(cols) {
var numberOfColumns = this.GetNumberOfGridColumnsToAdd(cols);
var style = `background-color:#444;
color:white;
display:grid;
grid-template-columns:${numberOfColumns};
`;
return style;
}
GetNumberOfGridColumnsToAdd(cols) {
var AutoCount;
cols.forEach((item) => {
if (AutoCount == undefined) {
AutoCount = "auto ";
return;
}
AutoCount += "auto ";
});
return AutoCount;
}
The result of the code above for the Display-Grid element:
And for each (grid-col) element:
The HTML Result
The Rendering
This taught us that we don't have a good understanding of how the shadowroot works. For now we don't need it and will study it later.
Other Information
This design is ok but not great. Due to specificity rules; by placing the styling at the element layer, there is nothing the user can do to override this except perhaps using the (forbidden?) !important keyword.
We could add a class style and test in lab to see if this opens a path for better user control.
No Binding
Another unforeseen issue in this design, is that it does not separate the data from the GUI, this means that something simple like sorting data (not needed for this example) is impossible. This current design re-renders all of the markup each time this page is reloaded.
In order for these components to be reusable, there must be considerations for easily styling this component for any situation. After all, Web Components are meant to be reused.
Posted on December 31, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.