Importing HTML and CSS
The previous examples 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 imported HTML files.
To make the CSS to affect only the template we have first to create a CSS with the extension
.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
| :local(.amazing-button) { /* (1)! */
--my-color: #f30000;
text-align: center;
& .card-header {
color: var(--my-color);
background-image: url("images/favicon.png");
background-size: contain;
background-repeat: no-repeat;
background-position-x: left;
}
}
|
- This will replace the classname
.amazing-button
with a local unique id
To enable the use of EJS-Variables in the HTML structure you have to create a file with the
extension .ejs.html
:
src/amazing-button.ejs.html
| <div class="card h-100"> <!-- (1)! -->
<div class="card-header">
<%= locals.myTitleVariable %> <!-- (2)! -->
</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="<%- require('./images/favicon.png') %>" /> <!-- (3)! -->
</div>
</div>
|
- The topmost div do not contain the class
amazing-button
as we will insert it later dynamically
- We replaced the title "Amazing Button" with an EJS variable
- In EJS Templates you have to change links to assets like images into a require statement! They
must start with
./
.
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.
Now we can write our new class:
src/amazing-button-variable.js
| import $ from "jquery";
import htmlTemplate from "./amazing-button.ejs.html";
import styles from "./amazing-button.module.css"; // (1)!
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 Variable Button");
$(element).html(htmlTemplate({ myTitleVariable: "Amazing Variable Button" })); // (2)!
$(element).addClass(styles["amazing-button"]); // (3)!
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");
}
}
|
- Import the stylesheet now as module instead of simple
import "filename.css"
- The variable
htmlTemplate
is now a function which can be called to get the final text
- This imprted CSS module offers all class names in the statement
:local()
as properties
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
.
Let's add another container in which we will start the new class:
src/index.js
| import createTestContainer from "./create-test-container";
import { default as MyVanillaApp } from "./amazing-button-vanilla";
import { default as MyPackagesApp } from "./amazing-button-packages";
import { default as MyImportApp } from "./amazing-button-import";
import { default as MySvgApp } from "./amazing-button-svg";
import { default as MyDynamicApp } from "./amazing-button-dynamic";
import { default as MyVariableApp } from "./amazing-button-variable";
import { default as MyVueApp } from "./amazing-button-vue";
import "./style.css";
createTestContainer("Testing Vanilla JS", "test-container-vanilla");
let myVanillaInstance = new MyVanillaApp(
document.getElementById("test-container-vanilla")
);
myVanillaInstance.maximumNumber = 99;
createTestContainer("Testing Packages", "test-container-packages");
let myPackagesInstance = new MyPackagesApp(
document.getElementById("test-container-packages")
);
myPackagesInstance.maximumNumber = 49;
createTestContainer("Testing Import HTML/CSS/Assets", "test-container-import");
let myImportInstance = new MyImportApp(
document.getElementById("test-container-import")
);
myImportInstance.maximumNumber = 79;
createTestContainer("Testing Import SVG", "test-container-svg");
new MySvgApp(document.getElementById("test-container-svg"));
createTestContainer("Testing Dynamic Imports", "test-container-dynamic");
let myDynamicInstance = new MyDynamicApp(
document.getElementById("test-container-dynamic")
);
myDynamicInstance.maximumNumber = 55;
createTestContainer("Testing CSS/EJS Variables", "test-container-variable");
let myVariableInstance = new MyVariableApp(
document.getElementById("test-container-variable")
);
myVariableInstance.maximumNumber = 45;
|
With npm start
you should see the running example in your browser. If you inspect the page you
will see an unique class name at the point where earlier amazing-button
was noted.