Skip to content

Importing HTML and CSS

The previous example works well but maybe you noticed that all the CSS was loaded into the global scope. The classname amazing-button would affect all elements of the page.

Furthermore we want to show how to use EJS features in the HTML file.

To make the CSS to affect only the template we have used we have to do these steps:

Step 1: Rename src/amazing-button.html to src/amazing-button.ejs.html.

With this you enable the use of EJS-Variables in the HTML structure. We remove here the class amazing-button as we will insert it later dynamically. Then we replace the title "Amazing Button" with <%= locals.myTitleVariable %>.

src/amazing-button.ejs.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div class="card h-100">
  <div class="card-header">
    <%= locals.myTitleVariable %> <i class="fa fa-magic"></i>
  </div>
  <div class="card-body">
    <h5 class="card-title">Click on the button to see the miracle</h5>
    <p class="card-text">
      <button class="btn btn-secondary">Press Me</button>
    </p>
    <div class="result border border-primary mb-2">No Result</div>
    <img src="logo.png" />
  </div>
</div>

Info

By the way: You can use here also include statements with <%- include another-file.html %>. But you have to pay attention that changes in included files will not be detected by the webpack devserver and the automatic rebuild will not include the new content.

Step 2: Rename src/amazing-button.css to src/amazing-button.module.css.

This enables the compilation of the CSS into a CSS Module. Now you can use local class names.

For this we replace the topmost classname .amazing-button with :local(.amazing-button). This makes this class later available over module properties and the class name will be replaced by a random value.

src/amazing-button.module.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
:local(.amazing-button) {
  & .card-header {
    --my-color: #f30000;
    color: var(--my-color);
    background-image: url(logo.png);
    background-size: contain;
    background-repeat: no-repeat;
    background-position-x: left;
  }
  & .card-title {
    text-decoration: underline;
  }
}

Step 3: Load all the new files in your JavaScript file.

You have to change the import statements and the way on how the resulting HTML will be added to the element.

We import the stylesheet now as module called styles. This module offers all class names in the statement :local() as properties. In our case we can access the class name amazing-button with styles["amazing-button"]. This will return the local class name replacement value which we can add to our topmost div.

The HTML structure will also imported as module. The variable htmlTemplate do not contain anymore just the text of the file. It is a function which can be called to get the final text. As argument you can provide an object. All properties of the object are accessible in the EJS template as properties of the object locals.

src/amazing-button-bootstrap.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import $ from "jquery";
import htmlTemplate from "./amazing-button.ejs.html";
import styles from "./amazing-button.module.css";
export default class {
  #maximumNumber = 9;
  #button;
  get maximumNumber() {
    return this.#maximumNumber;
  }
  set maximumNumber(value) {
    this.#maximumNumber = value;
    this.#button.html(`Show number from 1 to ${this.#maximumNumber}`);
  }
  constructor(element) {
    console.debug("Starting Bootstrap Button");
    $(element).html(htmlTemplate({ myTitleVariable: "Amazing Button" }));
    $(element).addClass(styles["amazing-button"]);
    $(element).css({
      border: "1px solid red",
      textAlign: "center"
    });
    this.#button = $(element)
      .find("button")
      .html(`Show number from 1 to ${this.#maximumNumber}`)
      .on("click", () => {
        this.resultDiv.html(Math.floor(Math.random() * this.#maximumNumber));
      });
    this.resultDiv = $(element).find("div.result");
  }
}

Now you should see the running example in your browser as before. If you inspect the page you will see an unique class name at the point where earlier amazing-button was noted.