Styling
Tags: webcomponents
Published: 2022-12-31 00:36:22

In the previous article we introduced the [Display-Grid](https://dev.to/jwp/web-components-display-grid-53f5) Web Component which supports markup like this:

```html
<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. 
 

![CSS for a grid with 3 columns](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sis39zq3450njkss4671.png)

The number of columns are based on the number of <code>&lt;grid-col&gt;</code> subelements.

In the original article there was a bug related to the shadow root.

###We Found a Bug 

Not having a full understanding of 
<code>const shadowRoot = this.attachShadow({mode:"open"});
</code>
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:

```js
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.

```js
/**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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ow1z8ibfhlus3mybpvwp.png)

And for each (grid-col) element:

![grid-col css](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9oq38e4at6tqnezgfnl.png)
 
###The HTML Result

![The HTML Result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9uho50o5ecupvhzu9fx.png)

###The Rendering 

![The Rendering of the Three Column Grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wactxalxu113t4vndu1g.png)

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.