How to stack table columns to simulate calendar agenda view?

寵の児 提交于 2020-04-17 22:51:57

问题


I'd like to transpose an HTML table without using JS or using another table.

I have a table holding a schedule which I want to collapse to single column on mobile screens (I need this to become this).

Right now I have two tables and am switching which one is displayed via media-queries (as well as collapsing rows to cells as explained in this article), but I would like a better solution because every edit will require changing both tables.

Can I do this without using JavaScript?

.styled-table {
	margin: 0 auto;
	padding: 0;
	width: 100%;
}

.styled-table thead, .styled-table tbody {
	text-align: center;
}

.styled-table th {
	font-weight: normal;
	background-color: #C00;
	color: white;
}

.styled-table tr:nth-child(even) {
	background: #CCC0C0;
}

.styled-table th {
	border-top: 1px solid #C00;
	border-bottom: 1px solid #C00;
}

.styled-table th:first-child {
	border-left: 1px solid #C00;
}

.styled-table th:last-child {
	border-right: 1px solid #C00;
}

@media screen and (min-width: 769px) {
	.styled-table td + td,
												.styled-table th + th,
												.styled-table th + td {
		border-left: 1px solid black;
	}
	
	.display-sm {
		display: none;
	}
}

@media screen and (max-width: 768px) {
	
	/* Force table to not be like tables anymore */
	table.styled-table, 
												.styled-table thead, 
												.styled-table tbody, 
												.styled-table th, 
												.styled-table td, 
												.styled-table tr {
		display: block;
	}
	
	/* Hide table headers (but not display: none;, for accessibility) */
	.styled-table thead tr {
		position: absolute;
		top: -9999px;
		left: -9999px;
	}
	
	.styled-table tr {
		border-bottom: 1px solid black;
	}
	
	.styled-table td {
	/* Behave  like a "row" */
		border: none;
		border-bottom: 1px solid #eee;
		position: relative;
		padding: 5px;
		padding-left: 50%;
	}
	
	.styled-table td:before {
		position: absolute;
		top: 0;
		left: 0;
		width: 50%;
		height: 100%;
		content: attr(data-mobile-label);
		font-weight: normal;
		font-style: normal;
		background-color: #C00;
		color: white;
		border-right: 1px solid black;
	}
	
	.styled-table th {
		border-bottom: 1px solid black;
	}
	
	.hide-sm {
		display: none !important;
	}
}
<table class="styled-table hide-sm">
  <thead>
    <tr>
      <th>Time/Day</th>
      <th>Mon</th>
      <th>Tues</th>
      <th>Wed</th>
      <th>Thurs</th>
      <th>Fri</th>
      <th>Sat</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>
        8:45 AM
        to
        1:00 PM
      </th>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>
        1:00 PM
        to
        5:00 PM
      </th>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>
        5:00 PM
        to
        9:00 PM
      </th>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td>
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
  </tbody>
</table>
<table class="styled-table display-sm">
  <thead>
    <tr>
      <th>Time/Day</th>
      <th>Mon</th>
      <th>Tues</th>
      <th>Wed</th>
      <th>Thurs</th>
      <th>Fri</th>
      <th>Sat</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>Mon</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>Tues</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>Wed</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>Thurs</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>Fri</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
    <tr>
      <th>Sat</th>
      <td data-mobile-label="8:45 AM to 1:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="1:00 PM to 5:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
      <td data-mobile-label="5:00 PM to 9:00 PM">
      	Name <br>
      	Name <br>
      	Name <br>
      </td>
    </tr>
  </tbody>
</table>

回答1:


You may use display:grid and display:contents (since it is not an issue for you) to restructure the visual layout of your HTML table. A data-attribute will also be necessary to create the missing cells.

example

table {
  width: 100%;
  border-collapse: collapse;
  background:rgb(196, 215, 70)
}

th,
:before {
  background: tomato;
  box-shadow: inset 0 0 0 2px;
}

th,
td {
  box-shadow: inset 0 0 0 2px;
  text-align: center;
  vertical-align: middle;
  padding: 0.5em;
}

tr:nth-child(2n) {
  background: lightblue;
}

@supports (display: contents) {
  /* trick works if data-time attributes stands in html and if display:contents is supported */
  @media screen and (max-width: 768px) {
    table {
      display: flex;
      flex-flow: column;
    }
    thead,
    tr,
    tbody {
      display: contents;
    }
    tr th:first-child {
      display: none;
    }
    th {
      background: red;
    }
    td {
      display: table;
      /*  you may also use display : flex; */
      table-layout: fixed;
      border-collapse: collapse;
      width: 100%;
    }
    td:before {
      content: attr(data-time);
      border-right: solid 1px;
      display: table-cell;
      /* no need if td is a flex box */
      white-space: pre;
      /* only if you care */
      vertical-align:middle;
      padding: 0.25em;
    }
    /* flex or grid allows to reorder content, exactly what we need and will do */
    tr :nth-child(2) {
      order: 0;
    }
    tr :nth-child(3) {
      order: 1;
    }
    tr :nth-child(4) {
      order: 2;
    }
    tr :nth-child(5) {
      order: 3;
    }
    tr :nth-child(6) {
      order: 4;
    }
    tr :nth-child(7) {
      order: 5;
    }
    td:nth-child(2n +1) {
      background: lightblue;
    }
  }
}
<table>
  <thead>
    <tr>
      <th>Time/Day</th>
      <th>Mon</th>
      <th>Tues</th>
      <th>Wed</th>
      <th>Thurs</th>
      <th>Fri</th>
      <th>Sat</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>
        8:45 AM to 1:00 PM
      </th>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="8:45 AM
to
1:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
    </tr>
    <tr>
      <th>
        1:00 PM to 5:00 PM
      </th>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="1:00 PM
to
5:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
    </tr>
    <tr>
      <th>
        5:00 PM to 9:00 PM
      </th>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
      <td data-time="5:00 PM
to
9:00 PM">
        <p>Name </p>
        <p>Name </p>
        <p>Name </p>
      </td>
    </tr>
  </tbody>
</table>

Some ressources if you do not know about :

  • https://css-tricks.com/snippets/css/complete-guide-grid/

  • https://gridbyexample.com/

  • https://developer.mozilla.org/en-US/docs/Web/CSS/@supports

  • https://css-tricks.com/get-ready-for-display-contents/

  • https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes



来源:https://stackoverflow.com/questions/58242113/how-to-stack-table-columns-to-simulate-calendar-agenda-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!