SO-75822623
by David Thomas
HTML
<section id="model-colors">
<header>
<div class="lead">
<!-- added the <span> here, in order to update the text to show the chosen-color: -->
<span class="colorChoice">Burning Red</span>
<span class="finish-style">Pearl Metallic</span>
</div>
</header>
<div class="rightHolder">
<h2>Colors</h2>
<!--
while I chose to use JavaScript to store the data, I chose to add
an 'id' attribute to the <img> elements in order to allow, and
check for, an element being linked to (from a color-choice shared
via copy+paste for example):
-->
<img
src="https://suzuki.bizmo.al/wp-content/uploads/2023/03/burning-red.png"
class="el-tooltip img-responsive item s16"
aria-describedby="el-tooltip-8288"
tabindex="0"
data-color-choice="burning-red"
id="color-choice-burning-red">
<img
src="https://suzuki.bizmo.al/wp-content/uploads/2023/03/speedy-blue.png"
class="el-tooltip img-responsive item s16"
aria-describedby="el-tooltip-6384"
tabindex="0"
data-color-choice="speedy-blue"
id="color-choice-speedy-blue">
<img
src="https://suzuki.bizmo.al/wp-content/uploads/2023/03/pure-white.png"
class="el-tooltip img-responsive item s16"
aria-describedby="el-tooltip-9890"
tabindex="0"
data-color-choice="pure-white"
id="color-choice-pure-white">
<img
src="https://suzuki.bizmo.al/wp-content/uploads/2023/03/premium-silver.png"
class="el-tooltip img-responsive item s16"
aria-describedby="el-tooltip-1345"
tabindex="0"
data-color-choice="premium-silver"
id="color-choice-premium-silver">
<img
src="https://suzuki.bizmo.al/wp-content/uploads/2023/03/mineral-gray.png"
class="el-tooltip...
CSS
/*
CSS properties that are likely to be used across the whole
project/page:
*/
:root {
--spacing: 0.5rem;
}
/*
simple reset to remove default margin and padding, and
to force browsers to use the same sizing algorithm (in
order to include border-sizes and padding with an
assigned width/height:
*/
*,
::before,
::after {
box-sizing: border-box;
font-family: inherit;
margin: 0;
padding: 0;
}
html,
body {
min-block-size: 100%;
}
/* setting the font for the page: */
body {
background-color: hsl(0deg 100% 100% / 1);
font-family: "suzukiproheadline", system-ui;
font-size: 16px;
font-weight: 400;
}
h2 {
font-size: 1.5rem;
text-align: center;
}
section {
/*
using grid to layout the <section> element, with a gap,
and padding, taken from the --spacing custom property:
*/
display: grid;
gap: var(--spacing);
/*
setting an absolute size for the first column, and
allowing the second to occupy the remaining space:
*/
grid-template-columns: 10rem 1fr;
/*
allowing the browser to size the first grid-row, and
assigning remaining space to the second grid-row:
*/
grid-template-rows: auto 1fr;
/*
again, using the same custom property for consistent
padding:
*/
padding: var(--spacing);
/*
setting a maximum block-size (the block axis is the axis
on which blocks are laid out, this is the vertical axis
in most European languages):
*/
max-block-size: 100vh;
}
header {
/*
setting a linear-gradient set to a 315 degree angle,
with a solid color-stop at 50% between --color1 and
--color0 (the color-order may sound odd but it's due
to the direction):
*/
background-image: linear-gradient(
315deg,
var(--color1) 0 50%,
var(--color0) 50% 100%
);
/*
setting a span of two columns, so this element will be
positioned automatically on its grid-row (as a specific
row isn't declared) and will span from the first column
across to the...
JavaScript
// some simple utility functions
const D = document,
// takes a String:
capitalize = (words) => {
let probableSeparator = [...words].filter((char) => /\W/.test(char)),
separator = probableSeparator && probableSeparator.length ? probableSeparator[0] : /[\s-]/;
return words
// using String.prototype.split() to separate the
// words on space-characters to form an Array:
.split(separator)
// we iterate over that Array using
// Array.prototype.map() to create a new Array:
.map(
// within the function we take the individual word ('w'),
// convert the first character (w[0]) to upper-case, and
// concatenate with the rest of the string:
(w) => w[0].toUpperCase() + w.slice(1)
)
// we join those words back together and return the
// joined sentence to the calling-context:
.join(probableSeparator || " ");
},
fauxClickEvent = new Event("click"),
get = (selector, context = D) => context.querySelector(selector),
getAll = (selector, context = D) => [...context.querySelectorAll(selector)];
// Object with properties to store the relevant data; because more data is
// required for this approach (more than the previous) I'm choosing to use
// an extensible method rather than further littering the DOM with custom
// attributes:
const colorChoices = {
"burning-red": {
name: "burning red",
color: "black",
colors: ["hsl(0deg 84% 45% / 1)"],
src: "https://suzuki.bizmo.al/wp-content/uploads/2023/03/red.png",
},
"speedy-blue": {
name: "speedy blue",
color: "black",
// obviously specify relevant/better colors in these colors Arrays:
colors: ["blue"],
src: "https://suzuki.bizmo.al/wp-content/uploads/2023/03/blue.png",
},
"pure-white": {
name: "pure white",
color: "black",
colors: ["white"],
src: "https://suzuki.bizmo.al/wp-content/uploads/2023/03/silver.png",
},
"premium-silver":...