Blog

Construct an internet site web page configurator with CSS & JavaScript

To construct our web page configurator, we’ll mix old-school CSS methods with trendy CSS options like customized properties and container queries. 

What We’re Constructing

With out additional ado, let’s check out the ultimate challenge. Click on the setting icon to the left of the display screen to entry the controls panel:

1. Start with the panel markup

Start by defining a toggle button and the panel configurator. Contained in the panel, we’ll place 5 kind wrappers—we’ll go over every of them later.

Right here’s the beginning markup:

1 class=“btn-toggle-panel” sort=“button” aria-label=“Toggle panel configurator” title=“toggle panel configurator”>
2 class=“fa-solid fa-screwdriver-wrench” aria-hidden=“true”>
3
4
5 class=“panel”>
6 class=“control-wrapper”>

7 class=“control-wrapper”>

8 class=“control-wrapper”>

9 class=“control-wrapper”>

10 class=“control-wrapper”>

11

Purely for stylistic causes, we’ll embody the Font Superior icon library in our challenge.

2. Toggle the panel

By default, the configurator panel will sit off-screen. As quickly as we click on the button, it’ll glide easily from the left aspect.

Our page configuratorOur page configurator

Listed below are the associated kinds:

1/*CUSTOM VARIABLES HERE*/
2
3.btn-toggle-panel,
4.panel {
5 place: mounted;
6 left: 10px;
7 z-index: 1;
8 colour: var(–vampire-black);
9 background: var(–anti-flash-white);
10}
11
12.btn-toggle-panel {
13 prime: 10px;
14 font-size: 18px;
15 width: 54px;
16 top: 54px;
17 border-radius: 50%;
18}
19
20.panel {
21 prime: 70px;
22 font-size: 16px;
23 line-height: regular;
24 padding: 30px 20px;
25 border-radius: 30px;
26 rework: translateX(calc(-100% 10px));
27 transition: rework 0.4s;
28}
29
30.panel.present {
31 rework: none;
32}

And the related JavaScript code:

1const togglePanelBtn = doc.querySelector(.btn-toggle-panel);
2const panel = doc.querySelector(.panel);
3
4togglePanelBtn.addEventListener(click on, operate () {
5 panel.classList.toggle(present);
6});

3. Web page customizations

Let’s now talk about in additional element what customization choices our configurator will permit. 

For simplicity, we’ll skip many of the CSS stuff and present solely the important elements.

Font-Household

By default, the challenge will use the Arial font household. Nonetheless, we are able to go for one of many following Google Fonts:

  • Fira Sans
  • Inter
  • Lato
  • Montserrat
  • Raleway
  • Roboto
  • Ubuntu

Notice that we received’t obtain all fonts collectively however upon request by following the Google Fonts API. That’s why you’ll see an on the spot flickering occur the primary time you choose a brand new font. You may verify the downloaded font information in your browser’s Community tab.

The HTML half:

1 class=“control-wrapper”>
2 for=“font-family”>Choose font
3 class=“internal”>
4 id=“font-family” identify=“household”>
5 worth=“Arial”>Arial
6 worth=“Fira Sans”>Fira Sans
7 worth=“Inter”>Inter
8 worth=“Lato”>Lato
9 worth=“Montserrat”>Montserrat
10 worth=“Raleway”>Raleway
11 worth=“Roboto”>Roboto
12 worth=“Ubuntu”>Ubuntu
13
14

15

The JavaScript half:

1const html = doc.documentElement;
2const fontFamilySelect = doc.querySelector([name=”family”]);
3const fontSizeInput = doc.querySelector([type=”number”]);
4
5fontFamilySelect.addEventListener(enter, operate (e) {
6 const worth = e.goal.worth;
7 if (Arial === worth) {
8 html.model.setProperty(–font-family, worth);
9 return;
10 }
11 const hyperlink = doc.createElement(hyperlink);
12 hyperlink.rel = stylesheet;
13 hyperlink.href = `https://fonts.googleapis.com/css2?household=${worth.replaceAll(
14 ,
15 +
16 )}:wght@400;700&show=swap`;
17 doc.head.appendChild(hyperlink);
18 html.model.setProperty(–font-family, worth);
19});

Font Measurement

The bottom font measurement will likely be 18px. We will lower or enhance it through buttons or typing contained in the goal enter. At any level, the bottom font measurement can’t be lower than 18px or larger than 36px. 

Discover that we outline an preliminary measurement within the root aspect, after which, utilizing the rem models, we apply the specified font measurement throughout the goal parts.

The HTML half:

1 class=“control-wrapper”>
2 for=“font-size”>Font measurement
3 class=“internal”>
4 class=“btn-font-size btn-decrease” sort=“button” aria-label=“lower font-size” title=“lower font-size”>
5 class=“fa-solid fa-minus” aria-hidden=“true”>
6
7 id=“font-size” sort=“quantity” worth=“10”>
8 class=“btn-font-size btn-increase” sort=“button” aria-label=“enhance font-size” title=“enhance font-size”>
9 class=“fa-solid fa-plus” aria-hidden=“true”>
10
11

12

The JavaScript half:

1const html = doc.documentElement;
2const fontFamilySelect = doc.querySelector([name=”family”]);
3const fontSizeInput = doc.querySelector([type=”number”]);
4const fontSizeBtns = doc.querySelectorAll(.btn-font-size);
5let selectedFontSize = fontSizeInput.worth;
6
7fontSizeBtns.forEach(operate (btn) {
8 btn.addEventListener(click on, operate (e) {
9 const inputValue = Quantity(fontSizeInput.worth);
10 if (
11 e.goal.classList.accommodates(btn-decrease) ||
12 e.goal.parentElement.classList.accommodates(btn-decrease)
13 ) {
14 if (fontSizeInput.worth <= 10) return;
15 fontSizeInput.worth;
16 } else {
17 if (fontSizeInput.worth >= 20) return;
18 fontSizeInput.worth++;
19 }
20 selectedFontSize = fontSizeInput.worth;
21 html.model.setProperty(–font-size, `${selectedFontSize}px`);
22 });
23});
24
25fontSizeInput.addEventListener(change, operate () {
26 const worth = this.worth;
27 if (worth < 10 || worth > 20) {
28 this.worth = selectedFontSize;
29 } else {
30 selectedFontSize = worth;
31 }
32 html.model.setProperty(–font-size, `${selectedFontSize}px`);
33});

Colours

The default web page background colour will likely be white, whereas the textual content colour will likely be black. Because of the enter aspect of sort colour, we are able to simply apply a brand new look to our web page.

The HTML half:

1 class=“control-wrapper”>
2 for=“background-color”>Bg colour
3 class=“internal”>
4 id=“background-color” sort=“colour” worth=“#ffffff”>
5

6

7
8 class=“control-wrapper”>
9 for=“text-color”>Textual content colour
10 class=“internal”>
11 id=“text-color” sort=“colour” worth=“#000000”>
12

13

The JavaScript half:

1const html = doc.documentElement;
2const colorInputs = doc.querySelectorAll([type=”color”]);
3
4colorInputs.forEach(operate (enter) {
5 enter.addEventListener(enter, operate () {
6 html.model.setProperty(`–${this.id}`, this.worth);
7 });
8});

Picture Results

By default, all photographs received’t have any results. Nonetheless, we are able to go for one of many following:

Discover using the container model queries to use the requested model. This is a fairly new CSS characteristic with virtually 75% help throughout this writing.

In fact, you’ll be able to implement a fallback resolution for wider browser help.

The HTML half:

1 class=“control-wrapper”>
2 for=“image-style”>Picture model
3 class=“internal”>
4 id=“image-style” identify=“image-style”>
5 worth=“regular”>Regular
6 worth=“grayscale”>Grayscale
7 worth=“blur”>Blur
8 worth=“rounded”>Rounded
9
10

11

The CSS half:

1@container model(–type: grayscale) {
2 img {
3 filter: grayscale(1);
4 }
5}
6
7@container model(–type: blur) {
8 img {
9 filter: blur(3px);
10 }
11}
12
13@container model(–type: rounded) {
14 img {
15 border-radius: 50px;
16 }
17}

The JavaScript half:

1const html = doc.documentElement;
2const imageStyleSelect = doc.querySelector([name=”image-style”]);
3
4imageStyleSelect.addEventListener(enter, operate (e) {
5 html.model.setProperty(–type, e.goal.worth);
6});

Conclusion

That’s all, of us! I hope this web page configurator has impressed you to construct one thing related in your initiatives. Be happy to increase by including extra options like a reset button or the power to repeat to the clipboard the chosen choices for simpler reuse.

When you have any questions or want one thing further, remark within the demo space.

Let’s look once more at our creation:

As at all times, thanks so much for studying!