Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

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

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

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

              
                <section class="description">
  <div class="description__text">
    <h1>Responsive WordPress Tables</h1>
    
    <p>On large viewports you will see the original table, which is wide and therefore legible on most laptop and desktop monitors.</p>

    <p>The JavaScript on this page has already generated a set of new tables that are based on this original table. However, if you are on a large screen then you likely do not see them yet because they are set to display:none;</p>

    <p><strong>If you resize your browser window to be smaller</strong>, then the original table will be set to display:none; and the JavaScript generated tables will be set to display:table;</p>

    <p>Notice how the newly generated tables are structured to be read vertically instead of horizontally. This ensures a better viewing experience on small viewports such as tablets and mobile phones.</p>

    <p>Please keep in mind that this script is specifically tailored to only work with one type of table format. Notice how the header of the table has no content in its first cell. Also notice how in the body of the table, each first cell within each row is set to describe the content in the following columns. As the need arises, I will modify this script to support other potential table formats. For now though, let's keep it simple.</p>
  </div>
</section>

<figure class="wp-block-table is-style-stripes">
  <table>
    <thead>
      <tr>
        <th></th>
        <th>Whole-Day Experiences</th>
        <th>Partial-Day Experiences</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><strong>Duration</strong></td>
        <td>6–8 hours</td>
        <td>1–3 hours</td>
      </tr>
      <tr>
        <td><strong>Program Components</strong></td>
        <td><strong>Includes</strong>:<br>– Live science show for the entire school<br>– 40-minute programs for individual classrooms<br>– Pop-up exhibit</td>
        <td><strong>Choose one:</strong><br>– 45-minute live science show<br>– Three 45-minute consecutive hands-on workshops<br>– 3 hours with a pop-up exhibit</td>
      </tr>
      <tr>
        <td><strong>Participants Served</strong></td>
        <td>6–15 classrooms or groups<br>(100–480 participants per day)</td>
        <td>– Science Show: Up to 400 participants<br>– Workshops: 1–3 classrooms or groups with up to 32 participants each&nbsp;<br>– Exhibit Exploration: Up to 300 participants</td>
      </tr>
      <tr>
        <td><strong>Price*</strong></td>
        <td>$2,375–$3,450</td>
        <td>$750–$1,500</td>
      </tr>
      <tr>
        <td><strong>Location</strong></td>
        <td>– Local and Western Washington year round<br>– Eastern Washington seasonally<br>(September–early November and March–June)</td>
        <td>Local only** year round</td>
      </tr>
    </tbody>
  </table>

  <figcaption class="wp-element-caption">*Funding available for qualifying schools, libraries, and community groups.<br>**Some partial-day programming is available regionally with additional travel fees. Inquire for more info.</figcaption>
</figure>
              
            
!

CSS

              
                // ***********************************
//  Responsive WordPress Tables
// ***********************************
// Hide newly generated mobile tables on large viewports
// but then show them on smaller viewports
.wp-block-table__mobile {
  display: none;

  @media (max-width: 768px) {
    display: table;
  }
}

// Hide original table on small viewports
figure.wp-block-table {
  table:not([class]) {
    @media (max-width: 768px) {
      display: none;
    }
  }
}

// Important styling for newly generated mobile tables
.wp-block-table__mobile {
  tbody {
    tr {
      display: flex;
      flex-direction: column;
      gap: 0.5em;
      padding: 0.5em;

      td {
        display: block;
        padding: 0;
      }
    }
  }
}




// ***********************************
//  Default CSS from WordPress Core and Gesso Theme
//  None of this should be copied/pasted to your project
//  In fact, you can pretty much ignore everything after this line...
// ***********************************
table {
  border-collapse: collapse;
  border-spacing: 0;
  caption-side: bottom;
  margin: 0 auto;
  max-width: 1200px;
}

figcaption {
  margin: 0 auto;
  max-width: 1200px;
  padding: 0.5em;
}

td, th {
  vertical-align: top;
}

th {
  background-color: #fff;
  border: 1px solid #003a5d;
  color: #fff;
  font-size: 0.9rem;
  padding: 0.8rem;
  text-align: left;
}

thead td, thead th {
  background-color: #003a5d;
  font-size: 18px;
  font-weight: 900;
}

.wp-block-table {
  margin: 32px auto;
  overflow-x: auto;
}

.wp-block-table.is-style-stripes {
  background-color: transparent;
  border-bottom: 1px solid #f0f0f0;
  border-collapse: inherit;
  border-spacing: 0;
}

.wp-block-table table {
  border-collapse: collapse;
  width: 100%;
}

tr:nth-of-type(odd) {
  background-color: #f0f0f0;
}

.wp-block-table.is-style-stripes td,
.wp-block-table.is-style-stripes th {
    border-color: transparent;
}

.wp-block-table td,
.wp-block-table th {
    border: 1px solid;
    padding: 0.5em;
}

.wp-block-table.is-style-stripes tbody tr:nth-child(odd) {
    background-color: #f0f0f0;
}




// ***********************************
//  CodePen Formatting
// ***********************************
body {
  font-family: sans-serif;
  line-height: 1.5;
  margin: 0;
  padding: 1em;
}

.description {
  background-color: #e3e3e3;
  box-shadow: 1px 1px 5px rgb(0 0 0 / 0.25);
}

.description__text {
  margin-inline: auto;
  max-width: 1200px;
  padding: 2em;
  
  h1 {
    margin-top: 0;
  }

  p {
    &:first-of-type {
      margin-top: 0;
    }
    
    &:last-of-type {
      margin-bottom: 0;
    }
  }
  
  strong {
    color: firebrick;
  }
}
              
            
!

JS

              
                const responsiveTable = () => {
  // Select all tables with the class '.wp-block-table'
  const tables = document.querySelectorAll('.wp-block-table table');

  // Iterate through each selected table
  tables.forEach((table) => {
    // Get the header row of the table
    const thead = table.querySelector('thead tr');
    const theadLength = thead.children.length;

    // Check if the first <th> element is empty
    if (thead.children[0].innerHTML.trim() !== '') {
      // If not empty, return and do nothing
      return;
    }

    // Iterate through each <th> element (excluding the first one)
    for (let i = 1; i < theadLength; i++) {
      // Create a new table for each <th> element
      const newTable = document.createElement('table');
      // Add classes to the new table for styling purposes
      newTable.classList.add('wp-block-table__mobile', `wp-block-table__mobile--${i}`);

      // Create a new <thead> and <tr> structure within each new table
      const newThead = document.createElement('thead');
      const newTr = document.createElement('tr');
      // Create a new <th> and append the content of the original <th> (excluding the first one)
      const newTh = document.createElement('th');
      newTh.innerHTML = thead.children[i].innerHTML;
      newTr.appendChild(newTh);
      newThead.appendChild(newTr);
      newTable.appendChild(newThead);

      // Create a new <tbody> for the remaining rows
      const newTbody = document.createElement('tbody');

      // Iterate through each <tbody><tr> element
      const tbodyRows = table.querySelectorAll('tbody tr');
      tbodyRows.forEach((tbodyRow) => {
        // Create a new <tr> structure within each new tbody
        const newTrBody = document.createElement('tr');

        // Create a new <td> and append the content of the first <td> in the original table
        const newTdLabel = document.createElement('td');
        newTdLabel.innerHTML = tbodyRow.children[0].innerHTML;

        // Create a new <td> and append the content of the corresponding <td> in the original table
        const newTdValue = document.createElement('td');
        newTdValue.innerHTML = tbodyRow.children[i].innerHTML;

        // Append the content of both <td> elements within the same <tr>
        newTrBody.appendChild(newTdLabel);
        newTrBody.appendChild(newTdValue);

        // Append the new <tr> to the new <tbody>
        newTbody.appendChild(newTrBody);
      });

      // Append the new tbody to the new table
      newTable.appendChild(newTbody);

      // Insert the new table before the original table in the DOM
      table.parentNode.insertBefore(newTable, table);
    }
  });
};
responsiveTable();

              
            
!
999px

Console