Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <header id="header" class="responsive">
  <!-- tabs with dummy links -->
  <div class="tabbed">
    <ul>
      <li>
        <a href="#sec">Dashboard builder</a>
      </li>
      <li>
        <a href="#section2" aria-selected="true">Widget designer</a>
      </li>
      <li>
        <a href="#section3">Administration</a>
      </li>
    </ul>
  </div>

  <div id="header-right">
    <span id="schoolDomain">domain.edu.au</span>
    <!-- scroll links (not buttons and no need for role="button" either) with svg icons were weird in iOS so I switched the (FontAwesome) SVG to unicode https://unicode-table.com/en/alt-codes/ -->
    <a href="#" title="scroll up">↑</a>
    <a href="#form-end-section" title="scroll down">↓</a>
  </div>
</header>

<main id="main">
  <h2>
    <button aria-expanded="false">
      Data query
      <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
        <rect class="vert" height="8" width="2" y="1" x="4" />
        <rect height="2" width="8" y="4" x="1" />
      </svg>
    </button>
  </h2>
  <div hidden>
    <p>Write an SQL query selecting records from the database to create a dataset. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero. Nullam tortor metus, tincidunt ut urna id, posuere placerat orci. Ut quis risus dictum risus facilisis imperdiet quis sed eros.</p>
  </div>
  <h2>
    <button aria-expanded="false">
      Widget views
      <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
        <rect class="vert" height="8" width="2" y="1" x="4" />
        <rect height="2" width="8" y="4" x="1" />
      </svg>
    </button>
  </h2>
  <div hidden>
    <p>Create 1 to 5 views to visualise the data. <a href="https://uxplanet.org/10-rules-for-better-dashboard-design-ef68189d734c#b760">Choose the right representation for the data</a>. Data representation is a complex task, especially since you will want to display multiple types of information in a dashboard, be it static or dynamic changes over time. This can be quite challenging. Choosing the wrong chart type, or defaulting to the most common type of data visualization could confuse users or lead to data misinterpretation.</p>
  </div>
  <h2>
    <button aria-expanded="false">
      Template details
      <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
        <rect class="vert" height="8" width="2" y="1" x="4" />
        <rect height="2" width="8" y="4" x="1" />
      </svg>
    </button>
  </h2>
  <div hidden>
    <p>Give the widget a title, long description, tags, and other metadata. Nullam tortor metus, tincidunt ut urna id, posuere placerat orci. Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
  </div>
  <h2>
    <button aria-expanded="true">
      Parameters
      <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
        <rect class="vert" height="8" width="2" y="1" x="4" />
        <rect height="2" width="8" y="4" x="1" />
      </svg>
    </button>
  </h2>
  <div>
    <p>Configure parameters for users to be able to set data filters and visualisation threshold values.</p>
    <details>
      <summary id="queryParametersPreview">SQL preview</summary>
      <textarea readonly rows="12" aria-labelledby="queryParametersPreview">SELECT
    to_char("OccuredTimestamp", 'HH12 AM') as "date",
    EXTRACT(HOUR from "OccuredTimestamp") as "another_date",
    count(*),
    EXTRACT(Year from "OccuredTimestamp") as "Year"
FROM public.chronicle_entries
WHERE "ChronicleCategoryName" IN (Chronicle_category)
GROUP BY "Year", "another_date", "date"
ORDER BY "another_date", "Year"</textarea>
    </details>

    <form autocomplete="off" autocorrect="off" spellcheck="true" novalidate method="get" action="#" class="responsive">
      <!-- https://inclusive-components.design/data-tables/#goingresponsive is nice but breaks position: sticky; on the th[scope=col] so we need to make sure any lengthy content (particularly in the keyword column) will wrap onto multiple lines, and come up with a responsive solution too ... -->
      <table>
        <caption>
          <h3>Parameters configuration</h3>
        </caption>
        <thead>
          <tr>
            <th scope="col">Keyword</th>
            <th scope="col" role="columnheader" aria-sort="ascending">
              <span id="placeholder-header">Placeholder</span>
              <button type="button" aria-label="sort by placeholder">sort<i class="fas fa-sort"></i></button>
            </th>
            <th scope="col" role="columnheader" aria-sort="none">
              <span id="type-header">Type</span>
              <button type="button" aria-label="sort by type">sort<i class="fas fa-sort"></button></th>
            <th scope="col"><span id="configured-header">Configured</span></th>
            <th scope="col">Action</th>
          </tr>
          <!-- Show sort controls for narrow screens somehow ... -->
        </thead>
        <tbody>
          <tr>
            <th scope="row">‘0’,‘1’,‘2’,‘3’,‘4’</th>
            <td><input type="text" maxlength="255" value="Periods" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row1select" aria-labelledby="type-header">
                <option value="non-configurable" selected>Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td></td>
            <td>None</td>
          </tr>
          <tr>
            <th scope="row">Percent</th>
            <td><input type="text" maxlength="255" aria-labelledby="placeholder-header" value="Threshold"></td>
            <td>
              <select aria-labelledby="type-header" id="row2select">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage" selected>Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td></td>
            <td><a href="#">Add rules <span class="visuallyhidden">to Threshold</span></a></td>
          </tr>
          <tr>
            <th scope="row">IsTeachingDay</th>
            <td><input type="text" maxlength="255" aria-labelledby="placeholder-header" value=""></td>
            <td></td>
            <td></td>
            <td></td>
          </tr>
          <tr>
            <th scope="row">yyyyDate</th>
            <td><input type="text" maxlength="255" aria-labelledby="placeholder-header" value="Year"></td>
            <td>
              <select id="row3select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year" selected>Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td></td>
            <td><a href="#">Add rules <span class="visuallyhidden">to Year</span></a></td>
          </tr>
          <tr>
            <th scope="row">2019-01-01</th>
            <td><input type="text" maxlength="255" value="Start_date" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row4select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date" selected>Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td>&lt;&nbsp;End_date,<br>&lt;=&nbsp;Some_other_date_Test_string_of_500_characters</td>
            <td><a href="#">Edit rules <span class="visuallyhidden">for Start_date</span></a></td>
          </tr>
          <tr>
            <th scope="row">2019-12-30</th>
            <td><input type="text" maxlength="255" value="End_date" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row5select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date" selected>Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td></td>
            <td><a href="#">Add rules <span class="visuallyhidden">to End_date</span></a></td>
          </tr>
          <tr>
            <th scope="row">10</th>
            <td><input type="text" maxlength="255" value="Tier_1_end" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row6select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number" selected>Number</option>
              </select>
            </td>
            <td>&lt;=&nbsp;Tier_2_end</td>
            <td><a href="#">Edit rules <span class="visuallyhidden">for Tier_1_end</span></a></td>
          </tr>
          <tr>
            <th scope="row">30</th>
            <td><input type="text" maxlength="255" value="Tier_2_end" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row7select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio">Radio</option>
                <option value="Number" selected>Number</option>
              </select>
            </td>
            <td>&gt;&nbsp;Tier_1_end</td>
            <td><a href="#">Edit rules <span class="visuallyhidden">for Tier_2_end</span></a></td>
          </tr>
          <tr>
            <th scope="row">Unexplained</th>
            <td><input type="text" maxlength="255" value="Absences" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row8select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text">Text</option>
                <option value="Radio" selected>Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td><input type="text" maxlength="255" value="Explained, Unexplained" aria-labelledby="configured-header"></td>
            <td>
              <!-- <a href="#">Edit options</a> -->

            </td>
          </tr>
          <!-- lengthy text in keyword column test  -->
          <tr>
            <th scope="row">6WdgrLpQMOacfv8ZpzztbLrM,0DkP4nOEm5YQKQZlijZZjVtuAbIOurcEO9J8tV7t5F6B1GfsPgFuBzJu254nEA573JCAzt6f1nsnoaCxYbFZT2XMTSjfV't4SUPq8hN4wr5YXO2kHGg-OB3t2CJYhWLCoanf4ke6VykJnFXDr3Ed,bnBJUrgFdmsxKqa0oE7NQcJhebAzkXi'4AjUV3SVwIhKRvmZJsDweopPa91AqswUOtmcbufUnRhQx4JlDP2g67Lw1aTOBE9j4rFcz3awl5a9yzvI5fj-RuynF,NsO7'OthhgqAwhRqkb-NE59VXLIQScdr0htK'ccYoFak8r0eUHMiClvTaRNuP2Ju1-jTOov1TNdmtfHwnz4KoxXBC3Sh6nUGbNHcnjhawg7g9c1OjoTac7NJB63Y7DMbSq'MXThAYxbFFuXZZlR5ZaRXf9pS5V8o-ue6wa2ksicILuwd1OpfGrPqbFh36FDxCRN68oHrOXFW</th>
            <td><input type="text" maxlength="255" value="Test_string_of_500_characters" aria-labelledby="placeholder-header"></td>
            <td>
              <select id="row9select" aria-labelledby="type-header">
                <option value="non-configurable">Attendance Period</option>
                <option value="Percentage">Percentage</option>
                <option value="Date">Date</option>
                <option value="Year">Year</option>
                <option value="Text" selected>Text</option>
                <option value="Radio">Radio</option>
                <option value="Number">Number</option>
              </select>
            </td>
            <td><input type="text" maxlength="255" value="Alpha, Bravo, Charlie, Delta, Echo, Foxtrot, Golf" aria-labelledby="configured-header"></td>
            <td>
              <a href="#" title="Once options are editable in a modal, these placeholder types need an action:">Edit options <span class="visuallyhidden">for Test_string_of_500_characters</span></a>
            </td>
          </tr>

        </tbody>
      </table>
    </form>
  </div>
  <section id="form-end-section">
    <button type="submit">Update template</button>
  </section>
</main>
              
            
!

CSS

              
                :root {
  --color-BlueBerry: #464fb1;
  /* Brown is new for the theme */
  --color-Brown: #8a4500;
  /* Dell is new for the theme */
  --color-Dell: #256411;
  /* RebeccaPurple is new for the theme */
  --color-RebeccaPurple: #663399;
  --color-Hurricane: #404040;
  --color-BrandBlueAlternate: #002d74;

  --color-Sunkist: #f8e2a0;
  --color-CoolGray: #cdd4e4;
  --color-CoolGray-hoverOrFocus: #edf1f8;
  --color-PanelBackground: #f8faff;
  --color-PanelBackground-hoverOrFocus: #e7ecf5;

  /* Colours for table row striping */
  --color-oddRows: var(--color-WhiteKnight);
  --color-evenRows: var(--color-PanelBackground-hoverOrFocus);

  /* https://convertacolor.com/#/hex/293847 gives hsl(210,26.8%,22%) */
  --color-BrandBlue: #293847;
  /* https://convertacolor.com/#/hex/5b749a gives rgb(91,116,154) */
  --color-BrandBlue-active: rgb(91, 116, 154);

  /* more contrast for hover state by changing lightness by 7.9% from hsl(216, 26%, 48%) ? */
  /*   --color-BrandBlue-hover: hsl(216.2, 25.7%, 40.1%); */

  /* https://convertacolor.com/#/hex/425678 gives hsl(217.8,29%,36.5%) */
  --color-BrandBlue-hoverOrFocus: #425678;

  /* For black, white and shades of grey I use hue saturation lightness hsl() https://caniuse.com/#feat=css3-colors 
  
  It might be nice to use https://css-tricks.com/no-comma-color-functions-in-css/ but space-separated functional color notations such as hsl(0 0% 0% / 100%) has no support in IE11 https://caniuse.com/#feat=mdn-css_types_color_space_separated_functional_notation so we use the old syntax */

  /* https://convertacolor.com/#/hex/000000 gives hsl(0, 0%, 0%) */
  --color-BlackIsBlack: hsl(0, 0%, 0%);
  /* https://convertacolor.com/#/hex/404040 gives hsl(0,0%,25.1%) */
  --color-Hurricane: hsl(0, 0%, 25.1%);
  /* https://convertacolor.com/#/hex/767676 gives hsl(0,0%,46.3%) */
  --color-Boulder: hsl(0, 0%, 46.3%);
  /* https://convertacolor.com/#/hex/D0D0D0 gives hsl(0, 0%, 81.6%) */
  --color-CloudyDay: hsl(0, 0%, 81.6%);
  /* https://convertacolor.com/#/hex/EFEFEF */
  --color-Gallery: hsl(0, 0%, 93.7%);
  /* https://convertacolor.com/#/hex/F7F7F7 */
  --color-Alabaster: hsl(0, 0%, 96.9%);
  /* https://convertacolor.com/#/hex/FFFFFF gives hsl(0, 0%, 100%) */
  --color-WhiteKnight: hsl(0, 0%, 100%);

  /* "slightly temper the contrast" a la Inclusive Design Patterns by Heydon Pickering */
  --color-BlackIsBlack: hsl(0, 0%, 5%);
  --color-WhiteKnight: hsl(0, 0%, 99%);

  --focusColor: var(--color-Sunkist);
  --borderRadius: 1px;
  --transitionAll: all 0.2s ease-in-out;

  --Shadow-subtle: 0px 2px 6px 0px rgba(119, 119, 119, 0.23);

  --baseFontSize: calc(1rem + 0.5vw);
  font-size: var(--baseFontSize);
}

/* data-types to color form controls (input and select) in the row */
[data-type="percentage" i] input,
[data-type="percentage" i] select
/* if we must support IE browsers, then we may need to use class selectors like .Percentage input, .Percentage select */ {
  color: var(--color-BlueBerry);
  border-color: var(--color-BlueBerry);
}
[data-type="date" i] input,
[data-type="date" i] select {
  color: var(--color-Brown);
  border-color: var(--color-Brown);
}
[data-type="year" i] input,
[data-type="year" i] select {
  color: var(--color-Dell);
  border-color: var(--color-Dell);
}
[data-type="radio" i] input,
[data-type="radio" i] select,
[data-type="text" i] input,
[data-type="text" i] select {
  color: var(--color-RebeccaPurple);
  border-color: var(--color-RebeccaPurple);
}
[data-type="non-configurable" i] input,
[data-type="non-configurable" i] select {
  color: var(--color-Hurricane);
  border-color: var(--color-Hurricane);
}
[data-type="number" i] input,
[data-type="number" i] select {
  color: var(--color-BrandBlueAlternate);
  border-color: var(--color-BrandBlueAlternate);
}

main {
  margin: 0.5rem;
}

/* sticky headers https://caniuse.com/#feat=css-sticky no support in IE so consider it a progressive enhancement for all other browsers - IE users will lose sight of table headers scrolled offscreen */
header,
th[scope="col"] {
  position: sticky;
  top: 0;
  z-index: 150;
}
th[scope="col"] {
  background-color: var(--color-CloudyDay);
  overflow-wrap: break-word;
  top: 2.25rem;
  font-size: smaller;
  padding: calc(0.25 * var(--baseFontSize)) calc(0.5 * var(--baseFontSize))
    calc(0.25 * var(--baseFontSize));
}
header {
  background-color: var(--color-BrandBlue);
  color: var(--color-WhiteKnight);
  border-bottom: 2px solid var(--color-Hurricane);
  box-shadow: 0px 2px 6px 0px rgba(119, 119, 119, 0.23),
    0px 0.2rem 0.2rem currentcolor;
}
thead {
  filter: drop-shadow(0px 1px 1px var(--color-BlackIsBlack))
    drop-shadow(0px -0.7rem 0px var(--color-WhiteKnight));
}

thead tr th:first-child {
  border-radius: calc(5 * var(--borderRadius)) 0 0 0;
}
thead tr th:last-child {
  border-radius: 0 calc(5 * var(--borderRadius)) 0 0;
}
/* Tables */
table {
  border-collapse: collapse;
  border-style: hidden;
  width: 100%;
  font-feature-settings: "zero";
}
table caption {
  background-color: var(--color-WhiteKnight);
  border-radius: calc(5 * var(--borderRadius));
  filter: drop-shadow(0px -3px 4px var(--color-WhiteKnight));
}
th button {
  margin: 0 1ch;
  border-radius: calc(4 * var(--borderRadius));
}
th,
td {
  /* not convinced about this uneven top-bottom padding  */
  padding: calc(0.25 * var(--baseFontSize)) calc(0.5 * var(--baseFontSize));
  vertical-align: baseline;
  /* https://caniuse.com/#search=overflow-wrap says 'anywhere' doesn't work in Safari and some other browsers. So switch from overflow-wrap to https://caniuse.com/#feat=word-break - it works in all browsers */
  word-break: break-all;
}
/* Ensure lengthy content in this column won't ruin the layout */
th[scope="row"] {
  max-width: 20ch;
  font-size: smaller;
}
tbody tr {
  transition: var(--transitionAll);
  border-bottom: 1px solid var(--color-Gallery);
}
/* stripe alternating rows */
tbody tr:nth-of-type(odd) {
  background-color: var(--color-oddRows);
}
tbody tr:nth-of-type(even) {
  background-color: var(--color-evenRows);
}
/* Help keyboard and mouse users identify the row with focus */
/* https://speakerdeck.com/a11ychi/if-its-interactive-it-needs-a-focus-style-with-eric-bailey?slide=56 */
tbody tr:focus-within {
  /* I previously included
tbody tr:hover in the selector but the rapid changing of highlight colour across rows is messy when using a mouse */
  background-color: var(--focusColor);
  /*  Don't use filter: drop-shadow - it ruins the layering of this row over the top of the header row */
  box-shadow: inset 0px -2px 4px 0px rgb(0, 0, 0, 0.1);
}
/* Ensure action column displays all content on one line without wrapping */
tbody tr td:last-child {
  white-space: nowrap;
  font-size: smaller;
  color: var(--color-Hurricane);
}

/* Typography */
html {
  box-sizing: border-box;
  font-family: "Inter", sans-serif;
}
@supports (font-variation-settings: normal) {
  html {
    font-family: "Inter var", sans-serif;
  }
}
*,
*:before,
*:after {
  box-sizing: inherit;
  text-align: start;
}
td.tabular {
  /* Not needed for these tables in Widget designer. Handy for data tables. */
  font-feature-settings: "tnum";
}
body {
  text-rendering: optimizelegibility;
  -webkit-font-smoothing: subpixel-antialiased;
  margin: 0;
  background-color: var(--color-WhiteKnight);
  color: var(--color-BlackIsBlack);
}
h3,
summary {
  font-size: calc(0.75 * var(--baseFontSize));
  font-weight: bold;
  padding-left: calc(0.125 * var(--baseFontSize));
  padding-right: calc(0.125 * var(--baseFontSize));
}
summary {
  margin-bottom: 0.1rem;
}

/* Form controls */
input[aria-labelledby],
select[aria-labelledby],
label[for] + input[id],
label[for] + select[id] {
  font-size: calc(0.75 * var(--baseFontSize));
  background-color: var(--color-WhiteKnight);
  border: 2px solid;
  border-radius: calc(4 * var(--borderRadius));
  padding: 0.1rem 0.25ch;
  /* size these form controls a little taller as there is no clickable label for mouse users */
  height: 2rem;
  width: unset;
  max-width: 100%;
}
textarea {
  font-size: calc(0.75 * var(--baseFontSize));
  width: 60ch;
  min-width: 50%;
  max-width: calc(100% - 1rem);
  min-height: 3rem;
  max-height: 25rem;
  line-height: 1.5;
  margin-left: calc(0.125 * var(--baseFontSize));
  margin-right: calc(0.125 * var(--baseFontSize));
}

button[type="submit"] {
  padding: 0.5rem 4ch;
  font-weight: bold;
}
button[type] {
  background-color: var(--color-Gallery);
  border-width: 1px;
  border-color: var(--color-Alabaster);
  border-style: outset;
  border-radius: calc(5 * var(--borderRadius));
}
button[type]:not(:disabled):hover,
button[type]:focus {
  background-color: var(--color-Alabaster);
}

#form-end-section {
  background-color: var(--color-BrandBlue-active);
  border-radius: 0 0 calc(5 * var(--borderRadius)) calc(5 * var(--borderRadius));
  padding: 0.5rem;
  margin-bottom: 9rem;
}

/* tabs */
header .tabbed,
header [role="tablist"] {
  padding: 0;
  margin: 0;
  display: inline-block;
}
#header-right {
  position: fixed;
  right: 0;
  top: 0;
  display: flow-root;
  padding: 0.25rem 0.5rem;
  background-color: inherit;
  border-radius: calc(5 * var(--borderRadius)) 0 0 calc(5 * var(--borderRadius));
}
#header-right a {
  background-color: var(--color-BrandBlue-hoverOrFocus);
  color: var(--color-WhiteKnight);
  padding: 0 1rem;
  border-radius: calc(2 * var(--borderRadius));
  transition: var(--transitionAll);
  box-shadow: 0px 4px 4px -4px var(--color-BlackIsBlack);
  border-bottom: 1px solid currentColor;
  text-decoration: none;
}
#header-right a + a {
  /* breathing space between adjacent touch targets */
  margin-left: 0.5rem;
}
#header-right a:hover,
#header-right a:focus {
  /* Darken background by ~8% */
  background-color: var(--color-BrandBlue);
  box-shadow: 0px 4px 6px -4px var(--color-BlackIsBlack);
}
#header-right a:active {
  filter: invert(100%);
  box-shadow: 0px 4px 1px -4px var(--color-BlackIsBlack);
}

#schoolDomain {
  font-size: medium;
  text-shadow: rgba(0, 0, 0, 0.5) -1px 1px 5px;
}

[role="tablist"] li,
[role="tablist"] a {
  display: inline-block;
}

[role="tablist"] a {
  background-color: var(--color-BrandBlue-hoverOrFocus);
  color: var(--color-WhiteKnight);
  text-decoration: none;
  position: relative;
  top: 2px;
  padding: 0.5rem 1em;
  border-radius: calc(5 * var(--borderRadius)) calc(5 * var(--borderRadius)) 0 0;
  border-style: outset;
  border-width: 2px 2px 0 2px;
  border-color: var(--color-Hurricane);
  font-size: medium;
  line-height: 1;
}
[role="tablist"] a:hover,
[role="tablist"] a:focus {
  background-color: var(--color-BrandBlue);
}

[role="tablist"] [aria-selected] {
  top: 2px;
  background-color: var(--color-CoolGray);
  color: var(--color-Hurricane);
}
[role="tablist"] [aria-selected]:hover,
[role="tablist"] [aria-selected]:focus {
  background-color: var(--color-CoolGray-hoverOrFocus);
}

/* collapsible sections */
main h2 {
  margin: 0;
  font-size: calc(0.85 * var(--baseFontSize));
  background-color: var(--color-evenRows);
  padding-left: calc(0.125 * var(--baseFontSize));
  padding-right: calc(0.125 * var(--baseFontSize));
  border-radius: calc(5 * var(--borderRadius));
}

main > div + h2 {
  border-top: 3px solid var(--color-WhiteKnight);
}

main h2:focus-within,
main h2:hover {
  background-color: var(--color-PanelBackground);
}

h2 button {
  all: inherit;
  border: 0;
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 0.25rem 0;
  cursor: pointer;
}

h2 button:focus svg {
  outline: 2px solid;
}

a svg[role="img"],
button svg {
  height: 1rem;
}
button svg {
  margin-left: 0.25rem;
}

[aria-expanded="true"] .vert {
  display: none;
}

[aria-expanded] rect {
  fill: currentColor;
}

/* utility classes */
.visuallyhidden {
  /* Accessible "Read More" Links https://codepen.io/svinkle/pen/Jmlbw needed for all the Action ... links */
  /* HTML5 Boilerplate accessible hidden styles */
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  white-space: nowrap;
}

/* https://css-tricks.com/responsive-data-tables/
Max width before this PARTICULAR table gets nasty
This query will take effect for any screen smaller than 1048px
*/
@media only screen and (max-width: 67em) {
  /* Force table to not be lke tables anymore */
  .responsive table,
  .responsive caption,
  .responsive thead,
  .responsive tbody,
  .responsive th,
  .responsive td,
  .responsive tr {
    display: block;
  }
  /* Hide table headers (but not display: none; for accessibility) */
  .responsive thead tr {
    position: absolute;
    top: -9999px;
    left: -9999px;
  }
  .responsive tr {
    border: 1px solid var(--color-CloudyDay);
    border-width: 2px 1px 0;
  }
  .responsive th[scope="row"],
  .responsive td {
    /* behave like a "row" */
    border: none;
    border-bottom: 1px solid var(--color-Gallery);
    position: relative;
    top: 0.1rem;
    padding-left: 40%;
    max-width: unset;
    min-height: 2rem;
  }
  .responsive th:before,
  .responsive td:before {
    /* Now like a table header */
    position: absolute;
    /* Top/left values mimic padding */
    top: 6px;
    left: 6px;
    min-width: calc(10% + 16px);
    padding-right: 10px;
    white-space: nowrap;
    font-size: initial;
  }

  /* Label the data */
  .responsive th:nth-of-type(1):before {
    content: "Keyword";
  }
  .responsive td:nth-of-type(1):before {
    content: "Placeholder";
  }
  .responsive td:nth-of-type(2):before {
    content: "Type";
  }
  .responsive td:nth-of-type(3):before {
    content: "Configured";
  }
  .responsive td:nth-of-type(4):before {
    content: "Action";
  }

  /* reduce font-size on domain in the header */
  .responsive #schoolDomain {
    font-size: small;
  }
}

@media only screen and (max-width: 32em) {
  /* Changes for those viewing at viewport widths narrower than ~510px */

  /* Style these things the same as .visuallyhidden */
  .responsive #schoolDomain,
  header.responsive [role="tablist"] a:not([aria-selected="true"]) {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    white-space: nowrap;
  }
}

/* And on touchscreens such as iPad, iPhone */
@media (pointer: coarse) {
  /* Hack positioning the table sticky header directly under header - on widths like iPad in landscape orientation */
  th[scope="col"] {
    top: -1.1rem;
  }
}

              
            
!

JS

              
                // Vernon's function to set tr data-type based on value of select[id][aria-labelledby]
function selectChange(id1) {
  const typeSelect = document.getElementById(id1);
  var selectedValue = typeSelect.value;
  // Find which row this element is in.
  var tableRow = typeSelect.closest("tr");
  // Using setAttribute data-* should work fine in IE browsers. It's the getAttribute data-* that has only partial support in IE6-10 https://caniuse.com/#search=data-*
  tableRow.setAttribute("data-type", selectedValue);

  // In this prototype we're only hiding existing input aria-labelled-by=configured-header
  // An improved version would create an input if there wasn't an existing one, and the type text is selected.
  // Find the first input in the same table row that is aria-labelled-by=configured-header (if any exists).
  var configuredInput = tableRow.querySelector(
    "input[aria-labelledby=configured-header]"
  );
  if (configuredInput) {
    // Check whether Text or Radio is the selected value, then show/hide the configured input.
    if (selectedValue === "Text" || selectedValue === "Radio") {
      configuredInput.removeAttribute("hidden");
    } else if (selectedValue !== "Radio" && selectedValue !== "Text") {
      configuredInput.setAttribute("hidden", "");
    }
  }
}

document.onreadystatechange = function () {
  if (document.readyState === "complete") {
    // Set data-type for each row on page load completed
    initApplication();
  }
};

function initApplication() {
  const matches = document.querySelectorAll("tr select[id][aria-labelledby]");
  matches.forEach(function (match) {
    // Trigger the initial change
    selectChange(match.id);
    // Add an event listener so we don't need to explicitly add an onchange to each <select> in the HTML
    match.addEventListener("change", function (e) {
      selectChange(match.id);
    });
  });
}

// Tabs and Panels from https://inclusive-components.design/tabbed-interfaces/
(function () {
  // Get relevant elements and collections
  const tabbed = document.querySelector(".tabbed");
  const tablist = tabbed.querySelector("ul");
  const tabs = tablist.querySelectorAll("a");
  const panels = tabbed.querySelectorAll('[id^="section"]');

  // The tab switching function
  const switchTab = (oldTab, newTab) => {
    newTab.focus();
    // Make the active tab focusable by the user (Tab key)
    newTab.removeAttribute("tabindex");
    // Set the selected state
    newTab.setAttribute("aria-selected", "true");
    oldTab.removeAttribute("aria-selected");
    oldTab.setAttribute("tabindex", "-1");
    // Get the indices of the new and old tabs to find the correct
    // tab panels to show and hide
    let index = Array.prototype.indexOf.call(tabs, newTab);
    let oldIndex = Array.prototype.indexOf.call(tabs, oldTab);
    panels[oldIndex].hidden = true;
    panels[index].hidden = false;
  };

  // Add the tablist role to the first <ul> in the .tabbed container
  tablist.setAttribute("role", "tablist");

  // Add semantics are remove user focusability for each tab
  Array.prototype.forEach.call(tabs, (tab, i) => {
    tab.setAttribute("role", "tab");
    tab.setAttribute("id", "tab" + (i + 1));
    tab.setAttribute("tabindex", "-1");
    tab.parentNode.setAttribute("role", "presentation");

    // Handle clicking of tabs for mouse users
    tab.addEventListener("click", (e) => {
      e.preventDefault();
      let currentTab = tablist.querySelector("[aria-selected]");
      if (e.currentTarget !== currentTab) {
        switchTab(currentTab, e.currentTarget);
      }
    });

    // Handle keydown events for keyboard users
    tab.addEventListener("keydown", (e) => {
      // Get the index of the current tab in the tabs node list
      let index = Array.prototype.indexOf.call(tabs, e.currentTarget);
      // Work out which key the user is pressing and
      // Calculate the new tab's index where appropriate
      let dir =
        e.which === 37
          ? index - 1
          : e.which === 39
          ? index + 1
          : e.which === 40
          ? "down"
          : null;
      if (dir !== null) {
        e.preventDefault();
        // If the down key is pressed, move focus to the open panel,
        // otherwise switch to the adjacent tab
        dir === "down"
          ? panels[i].focus()
          : tabs[dir]
          ? switchTab(e.currentTarget, tabs[dir])
          : void 0;
      }
    });
  });

  // Add tab panel semantics and hide them all
  Array.prototype.forEach.call(panels, (panel, i) => {
    panel.setAttribute("role", "tabpanel");
    panel.setAttribute("tabindex", "-1");
    let id = panel.getAttribute("id");
    panel.setAttribute("aria-labelledby", tabs[i].id);
    panel.hidden = true;
  });

  // Initially activate the first tab and reveal the first tab panel
  /* In this prototype I do this staticly via the HTML so I'll comment out these 
  tabs[0].removeAttribute("tabindex");
  tabs[0].setAttribute("aria-selected", "true");
  panels[0].hidden = false;
  */
})();

// Collapsible sections from https://inclusive-components.design/collapsible-sections/
(function () {
  const headings = document.querySelectorAll("h2");

  Array.prototype.forEach.call(headings, (h) => {
    let btn = h.querySelector("button");
    let target = h.nextElementSibling;

    btn.onclick = () => {
      let expanded = btn.getAttribute("aria-expanded") === "true";

      btn.setAttribute("aria-expanded", !expanded);
      target.hidden = expanded;
    };
  });
})();

              
            
!
999px

Console