Styling with CSS to format a table so that each cell occupies one row when viewed on narrower

I've come across some HTML that resembles this structure

<html><body><table>
  <thead><tr><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th></tr></thead>
  <tbody>
    <tr><td>1A</td><td>1B</td><td>1C</td><td>1D</td><td>1E</td></tr>
    <tr><td>2A</td><td>2B</td><td>2C</td><td>2D</td><td>2E</td></tr>
    <tr><td>3A</td><td>3B</td><td>3C</td><td>3D</td><td>3E</td></tr>
  </tbody>
</table></body></html>

Each row represents an object, with columns representing its properties. The cell values can be quite lengthy, sometimes up to 20-30 characters long. While it displays well on most devices, smaller phones may pose a problem. While I could hide certain columns on narrow devices, it doesn't feel like the right approach in this case. Currently, I have x-overflow: scroll applied to the table, but I would prefer a CSS solution that restructures the table for narrow screens as follows:

A: 1A
B: 1B
C: 1C
D: 1D
E: 1E
-----
A: 2A
B: 2B
C: 2C
D: 2D
E: 2E
-----
(etc)

Assuming I want to implement this unconditionally without device width testing, tweaking the HTML markup slightly is acceptable to add extra classes or attributes. It's important to keep using a <table> element with one <tr> per logical row due to backward compatibility reasons. Despite the availability of a cleaner API, many users still scrape the site. As a result of internal dynamics, I'd rather avoid a JavaScript solution if possible (although I'm capable of writing one if necessary).

While I've made progress with my current CSS, particularly in styling the data rows, I'm unsure how to dynamically generate the field names which are currently fixed as 'X' in my code snippet:

  thead { display: none; }
  table, tr, td { display: block; }
  tr + tr { border-top: thin solid black; }
  td::before { content: "X:"; display: inline-block; width: 2em; }

I've noticed similar designs on various websites, but finding a CSS-specific implementation has proved challenging. While this seems like a common requirement, I'm struggling to locate suitable resources or explanations due to search term ambiguity.

Answer №1

Keep going, you're almost there! Consider using data-col attributes on your <td> elements and referencing them in your CSS using the content property with :before

thead {
  display: none;
}

table,
tr,
td {
  display: block;
}

tr+tr {
  border-top: thin solid black;
}

td::before {
  content: attr(data-col)':';
  display: inline-block;
  width: 2em;
}
<table>
  <thead>
    <tr>
      <th>A</th>
      <th>B</th>
      <th>C</th>
      <th>D</th>
      <th>E</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td data-col="A">1A</td>
      <td data-col="B">1B</td>
      <td data-col="C">1C</td>
      <td data-col="D">1D</td>
      <td data-col="E">1E</td>
    </tr>
    <tr>
      <td data-col="A">2A</td>
      <td data-col="B">2B</td>
      <td data-col="C">2C</td>
      <td data-col="D">2D</td>
      <td data-col="E">2E</td>
    </tr>
    <tr>
      <td data-col="A">3A</td>
      <td data-col="B">3B</td>
      <td data-col="C">3C</td>
      <td data-col="D">3D</td>
      <td data-col="E">3E</td>
    </tr>
  </tbody>
</table>

An alternative method involves utilizing CSS variables to store column values, which can make your code less repetitive and save space for longer tables:

thead {
  display: none;
}

table,
tr,
td {
  display: block;
}

tr+tr {
  border-top: thin solid black;
}

td:before {
  display: inline-block;
  width: 2em;
}

td:nth-child(1):before {
  content: var(--col1)':';
}

td:nth-child(2):before {
  content: var(--col2)':';
}

td:nth-child(3):before {
  content: var(--col3)':';
}

td:nth-child(4):before {
  content: var(--col4)':';
}

td:nth-child(5):before {
  content: var(--col5)':';
}
<table style="--col1:'A'; --col2:'B'; --col3:'C'; --col4:'D'; --col5:'E'">
  <thead>
    <tr>
      <th>A</th>
      <th>B</th>
      <th>C</th>
      <th>D</th>
      <th>E</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1A</td>
      <td>1B</td>
      <td>1C</td>
      <td>1D</td>
      <td>1E</td>
    </tr>
    <tr>
      <td>2A</td>
      <td>2B</td>
      <td>2C</td>
      <td>2D</td>
      <td>2E</td>
    </tr>
    <tr>
      <td>3A</td>
      <td>3B</td>
      <td>3C</td>
      <td>3D</td>
      <td>3E</td>
    </tr>
  </tbody>
</table>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Arranging elements within a complex div structure

I have been working on styling this div that displays the products for an e-commerce website. I initially used CSS and a table within it, but it seems like using tables for content is not recommended, so I am trying to find a better solution. However, my a ...

Issues with the performance of input range sliders in iOS Safari is causing frustration

I recently developed a basic range slider component for an application built with NextJS. This component utilizes an <input type="range"> element. While the range slider functions properly on Desktop and Android devices, I encountered sign ...

Using jQuery in Rails 3 to display the id of a td element

I am working with a 3x3 table that contains td elements with unique id's (id='a1'...id='c3'). I want to enable the user to click on any of these 9 td elements and receive an alert displaying the id of the clicked td. Below is my C ...

Having difficulty aligning ListItem to the right within a List

I am working with an array that contains objects which I need to display in ListItems of a List. My goal is to show these ListItems from the array Objects in a layout where odd numbers are on the left and even numbers are on the right. However, I am facing ...

Rendering SVG graphics on browsers for Android devices

I've been struggling with an issue for quite some time now and I can't seem to find a solution. The problem lies in having an SVG image as a CSS background on the top left corner of a div. Instead of seamlessly merging with the div background, i ...

Is there a way for me to stack the submenu links on top of each other?

Is there a way to rearrange the submenu links so they appear stacked vertically instead of horizontally? Currently, they line up next to each other under the main menu and subsequent links fall below the submenu. I believe it involves adjusting the positio ...

Converting Data from MySQL and PHP to Excel

Is there a way to export human resource applications stored in my MySQL table as an Excel file? function exportExcel($filename='ExportExcel',$columns=array(),$data=array(),$replaceDotCol=array()){ global $connect; header('Content-Enc ...

Items that share identical height and margin values will appear with divergent visual presentations

I am trying to align three horizontal lines so that they are the same height and have an equal spacing between each other. However, due to variations in height and margins, some lines appear larger or smaller than others. How can I ensure they all have th ...

What is the best way to customize the default button style for buttons in Angular Datables?

After integrating buttons into my Angular Datatables, I noticed that they have default styling, which makes them stand out from the rest of my web page (refer to the Column Visibility button in the screenshot below): I attempted to use CSS to make the but ...

Creating a legitimate svg element using javascript

While working with SVG, I had an issue where I added a <rect> element directly into the svg using html, and then created a new element (without namespace) <circle> with javascript. However, the <circle> element did not display in the svg ...

How can I make all fields in the CKAN Resource form html the same size as the "Description" field?

I am completely new to CKAN and front-end development. I've been scouring through various html/css files without success in locating where I can adjust the field sizes in the resources form (where users can modify metadata via GUI). I would like to r ...

Effortlessly glide to a specific div ID upon page load using the URL address

One way to implement smooth scrolling to an anchor on page load is by using jQuery. Here's an example code snippet: $(function(){ $('html, body').animate({ scrollTop: $( $('#anchor1').attr('href') ).offset(). ...

Is there a way to modify a document without altering its original location?

I attempted to load an entire page using ajax, with the doctype and html tags removed. However, when I tried setting it with the following code: document.documentElement.innerHTML=xmlhttp.responseText; Google Chrome returned an error message: An invalid ...

Storing information in a database

Need help troubleshooting why my form isn't saving data to the database. <div class="container"> <div class="row" style="margin-top:200px;"> <form ENCTYPE="multipart/form-data" ACTION="upload.php" METHO ...

What is the best way to showcase additional fields from a custom post type along with the featured thumbnail feature?

'I designed a custom post plugin in Wordpress that successfully displays the title and main content, but I am facing issues with displaying other fields such as company details. Despite mentioning a featured thumbnail option in my plugin, I am not ab ...

Accessing JavaScript results in PHP

Hello everyone! I am working on creating a dropdown menu for selecting time using JavaScript to get the computer's current time. My goal is to have an output that automatically selects the option in the dropdown if it matches the computer's time. ...

Modify th:hover in CSS to alter the background color

I currently have a table structured as follows: <table class="cedvel"> <caption> count: <%:Html.Encode(TempData["RowsCount"])%></caption> <thead> <tr&g ...

What is the method to determine the encoding that the user is using to input into the browser?

After reading Joel's insightful article about character sets, I have decided to follow his advice by using UTF-8 on both my web page and in my database. However, one thing that confuses me is how to handle user input. As Joel aptly points out, "It doe ...

"In the shadows, the .toLowerCase() method of undefined is failing without making a sound, yet the code

It seems that letting things fail in the background is necessary for this example to work consistently. Is there a way to work around this issue? There are instances where I need to check a div with a data-attribute on certain pages and add a class if it ...

Tips on how to align a wrapper-div in the center without affecting the positioning of the

I am looking to keep my page perfectly centered in the browser without affecting the content (similar to how align-text: center works). Specifically, I want to center my wrapper-div. How can I achieve this? Here is a simplified version of my current page ...