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":...