I have the following table design, laid out with CSS Grid (see first snippet).
Is it possible to make all columns of the same type/class (e.g. .Table_col_day) as wide as the column of that type/class with the widest content, with CSS/without JS? The solution doesn’t have to be CSS Grid based.
See the second code snippet for a quick JS-based solution, to illustrate what I'd like to do.
.Table__row {
background-color: plum;
display: grid;
grid-template-columns: 0.5fr 0.5fr 1fr;
}
.Table__row:nth-of-type(even) {
background-color: lime;
}
<div class="Table">
<div class="Table__row">
<div class="Table__day">Mon</div>
<div class="Table__time">10am</div>
<div class="Table__title">Some event</div>
</div>
<div class="Table__row">
<div class="Table__day">Tue</div>
<div class="Table__time">12:30pm</div>
<div class="Table__title">Another event</div>
</div>
<div class="Table__row">
<div class="Table__day">Wed</div>
<div class="Table__time">9:00am</div>
<div class="Table__title">A different event</div>
</div>
</div>
Javascript-based solution (determine widest column content, then manually set grid column styles of row element)
function resizeColumns(SELECTOR) {
const colElements = document.querySelectorAll(SELECTOR);
//////
const widths = [...colElements].map(el => el.querySelector('span').offsetWidth);
const width_max = Math.max(...widths);
//////
for(let col of colElements) {
col.parentNode.style.gridTemplateColumns = `${width_max}px 0.5fr 1fr`;
}
}
resizeColumns('.Table__col_day');
.Table__row {
background-color: plum;
display: grid;
grid-template-columns: 0.5fr 0.5fr 1fr;
}
.Table__row:nth-of-type(even) {
background-color: lime;
}
<div class="Table">
<div class="Table__row">
<div class="Table__col_day">
<span>Mon</span>
</div>
<div class="Table__col_time">
<span>10am</span>
</div>
<div class="Table__col_title">
<span>Some event</span>
</div>
</div>
<div class="Table__row">
<div class="Table__col_day">
<span>Tue</span>
</div>
<div class="Table__col_time">
<span>12:30pm</span>
</div>
<div class="Table__col_title">
<span>Another event</span>
</div>
</div>
<div class="Table__row">
<div class="Table__col_day">
<span>Wed</span>
</div>
<div class="Table__col_time">
<span>9:00am</span>
</div>
<div class="Table__col_title">
<span>A different event</span>
</div>
</div>
</div>
You said it at the beginning: "table design" so use table
.Table {
display: table;
width: 100%;
}
.Table__row {
background-color: plum;
display: table-row;
}
.Table__row > * {
display: table-cell;
white-space: nowrap;
}
.Table__row > *:not(.Table__day) {
width: 50%;
}
.Table__row:nth-of-type(even) {
background-color: lime;
}
<div class="Table">
<div class="Table__row">
<div class="Table__day">Mon</div>
<div class="Table__time">10am</div>
<div class="Table__title">Some event</div>
</div>
<div class="Table__row">
<div class="Table__day">Tue</div>
<div class="Table__time">12:30pm</div>
<div class="Table__title">Another event</div>
</div>
<div class="Table__row">
<div class="Table__day">Wed</div>
<div class="Table__time">9:00am</div>
<div class="Table__title">A different event</div>
</div>
</div>
Or consider display:contents if you want to keep display:grid;
.Table {
display: grid;
grid-template-columns: auto 1fr 1fr;
}
.Table__row {
display: contents;
}
.Table__row > * {
background-color: plum;
}
.Table__row:nth-of-type(even) > * {
background-color: lime;
}
<div class="Table">
<div class="Table__row">
<div class="Table__day">Mon</div>
<div class="Table__time">10am</div>
<div class="Table__title">Some event</div>
</div>
<div class="Table__row">
<div class="Table__day">Tue</div>
<div class="Table__time">12:30pm</div>
<div class="Table__title">Another event</div>
</div>
<div class="Table__row">
<div class="Table__day">Wed</div>
<div class="Table__time">9:00am</div>
<div class="Table__title">A different event</div>
</div>
</div>
Related
I'm trying to achieve this, where brown gets pushed down when pink is too long, and pink is dynamically sized based on its text content.
I was only able to achieve this using javascript and two templates, if pink length is over X use second template, but I'm wondering if there's a way to achieve this using CSS only?
I tried meddling with grid auto-fill/auto-fit with minmax, float, flex with wrap, but I couldn't get to the desired result with these.
.parent {
width: 170px;
}
.flex {
display: flex;
}
div {
outline: 2px solid rgba(255, 0,0, 0.3);
}
<div>
<p>scenario A</p>
<div class="parent flex">
<div>
<div class="one">A short title</div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
<div>
<p>scenario B</p>
<div class="parent">
<div class="one">Testing a very long title</div>
<div class="flex">
<div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
</div>
<p>can a component achieve both a and b with only css?
I found a solution, it requires having fixed height in the first row, and the right side button will basically overflow when needed.
Will wait a bit before accepting my own solution in case someone came with a better one.
.container {
width: 300px;
display: flex;
gap: 10px;
padding: 16px;
font-size: 14px;
font-family: Arial;
}
.text {
flex: 1;
min-width: 0;
}
.first-row {
height: 22px;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.image {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #444;
}
.title {
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<h2>Long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test title test title</div>
<button>Visit store</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Short title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Short title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Very long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test titleTest title test titleTest title test title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
So I have this layout on my grid
But as the width goes smaller I want to change to this layout
So far I have it like this
.row > div {
border: 1px solid black
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class='row'>
<div class="col-md-6">
1
</div>
<div class="col-md-5">
<div class='row'>
<div class="col-md-12">
2
</div>
<div class="col-md-12">
3
</div>
</div>
</div>
</div>
I think best practice way CSS Grid layout to essay and customizable
.grid > div {
border: 1px solid black;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
#media (min-width: 768px) {
.one {
grid-row: 1/3;
}
}
.three {
grid-column: 1/3;
}
#media (min-width: 768px) {
.three {
grid-column: 2/3;
}
}
<div class='grid'>
<div class="one">
1
</div>
<div class="two">
2
</div>
<div class="three">
3
</div>
</div>
like this?
<div class='row'>
<div class="col-md-6 col-sm-6">
1
</div>
<div class="col-md-6">
<div class='row'>
<div class="col-md-12 col-sm-6">
2
</div>
<div class="col-md-12 col-sm-12">
3
</div>
</div>
</div>
</div>
I've a five column grid, which has in some cases only content in three columns. The content should be right aligned, so that there will be an offset of two columns. Is there a possibility to do this automatically? Actually I'm doing it with grid-column-start: 3, grid-column-start: 4, grid-column-start: 5:
.grid {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.col {
text-align: center;
padding: 2rem;
background-color: lightblue;
}
<div class="grid">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
</div>
<p>Actual syntax / layout:</p>
<div class="grid">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<p>Should behave like this:</p>
<div class="grid">
<div class="col" style="grid-column-start: 3;">1</div>
<div class="col" style="grid-column-start: 4;">2</div>
<div class="col" style="grid-column-start: 5;">3</div>
</div>
Thought about something like justify-items: end but thats for the alignment of the content inside the column. For me I'm looking like even more a solution as it's behaviour in flexbox (justify-content), but I don't want to use flexbox ;)
Regards,
Markus
You can handle each case alone since they aren't a lot:
.grid {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.col {
text-align: center;
padding: 2rem;
background-color: lightblue;
}
.col:nth-last-child(1):first-child {
grid-column-end: -1;
}
.col:nth-last-child(2):first-child {
grid-column-end: -2;
}
.col:nth-last-child(3):first-child {
grid-column-end: -3;
}
.col:nth-last-child(4):first-child {
grid-column-end: -4;
}
<div class="grid">
<div class="col">1</div>
</div>
<div class="grid">
<div class="col">1</div>
<div class="col">2</div>
</div>
<div class="grid">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="grid">
<div class="col" >1</div>
<div class="col" >2</div>
<div class="col" >3</div>
<div class="col" >4</div>
</div>
<div class="grid">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
</div>
In my code,
Within one container Three blocks will be there. one freezes on the left and one freezes on the right and the other will scroll in between these two divs. Just like modern grids. But I don't want to use the grid.
I have tried, but the center block is not getting the Horizontal scroll.
I want no breakage of the center block, instead, it should scroll horizontally.
* {
box-sizing: border-box;
}
.container {
width: 100%;
overflow: auto;
white-space: nowrap
}
.scroll-center {
width: auto;
overflow: auto;
display: block;
white-space: nowrap
}
.row {
float: left;
}
.cell {
padding: 3px;
border: 1px solid #bbb;
min-height: 25px;
min-width: 200px;
}
<div class="container">
<div class="row">
<div class="cell">HeaderL1</div>
<div class="cell">HeaderL2</div>
<div class="cell">HeaderL3</div>
</div>
<div class="scroll-center">
<div class="row">
<div class="cell">HeaderT2</div>
<div class="cell">Data21</div>
<div class="cell">Data22</div>
</div>
<div class="row">
<div class="cell">HeaderT3</div>
<div class="cell">Data31</div>
<div class="cell">Data32</div>
</div>
<div class="row">
<div class="cell">HeaderT4</div>
<div class="cell">Data41</div>
<div class="cell">Data42</div>
</div>
<div class="row">
<div class="cell">HeaderT5</div>
<div class="cell">Data51</div>
<div class="cell">Data52</div>
</div>
<div class="row">
<div class="cell">HeaderT6</div>
<div class="cell">Data61</div>
<div class="cell">Data62</div>
</div>
<div class="row">
<div class="cell">HeaderT7</div>
<div class="cell">Data71</div>
<div class="cell">Data72</div>
</div>
<div class="row">
<div class="cell">HeaderT8</div>
<div class="cell">Data81</div>
<div class="cell">Data82</div>
</div>
<div class="row">
<div class="cell">HeaderT9</div>
<div class="cell">Data91</div>
<div class="cell">Data92</div>
</div>
</div>
<div class="right">
<div class="row">
<div class="cell">HeaderTR</div>
<div class="cell">DataR1</div>
<div class="cell">DataR2</div>
</div>
</div>
</div>
You probably need to add width to your container. Right now it's set to 100% so it will not size beyond the browser window. Instead you could do something like this:
.container {
overflow: auto;
white-space: nowrap;
width:2000px;
}
I realize that you may need to change this value dynamically but hopefully this gets you started
Example:http://codepen.io/nilestanner/pen/jAjbdK
Try with For example:
css:
* {
box-sizing: border-box;
}
.left, .center, .right{
float:left
}
.center {
width:400px;
overflow: scroll;
display: block;
white-space: nowrap
}
#center-scroll{
width:2000px;
}
.center .row{
display:inline-block;
width:33%;
}
.center .row .cell{
min-width:100%;
}
.row{
float:left;
}
.cell {
padding: 3px;
border: 1px solid #bbb;
min-height: 25px;
min-width: 200px;
}
HTML
<div class="container">
<div class="left">
<div class="row" >
<div class="cell">HeaderL1</div>
<div class="cell">HeaderL2</div>
<div class="cell">HeaderL3</div>
</div>
</div>
<div class="center">
<div id="center-scroll">
<div class="row">
<div class="cell">HeaderT2</div>
<div class="cell">Data21</div>
<div class="cell">Data22</div>
</div>
<div class="row">
<div class="cell">HeaderT3</div>
<div class="cell">Data31</div>
<div class="cell">Data32</div>
</div>
<div class="row">
<div class="cell">HeaderT4</div>
<div class="cell">Data41</div>
<div class="cell">Data42</div>
</div>
<div class="row">
<div class="cell">HeaderT5</div>
<div class="cell">Data51</div>
<div class="cell">Data52</div>
</div>
<div class="row">
<div class="cell">HeaderT6</div>
<div class="cell">Data61</div>
<div class="cell">Data62</div>
</div>
<div class="row">
<div class="cell">HeaderT7</div>
<div class="cell">Data71</div>
<div class="cell">Data72</div>
</div>
<div class="row">
<div class="cell">HeaderT8</div>
<div class="cell">Data81</div>
<div class="cell">Data82</div>
</div>
<div class="row">
<div class="cell">HeaderT9</div>
<div class="cell">Data91</div>
<div class="cell">Data92</div>
</div>
</div>
</div>
<div class="right">
<div class="row">
<div class="cell">HeaderTR</div>
<div class="cell">DataR1</div>
<div class="cell">DataR2</div>
</div>
</div>
</div>
In this sample all the columns share the same height:
http://www.minimit.com/demos/bootstrap-3-responsive-columns-of-same-height
In my sample: http://codepen.io/helloworld/pen/ogrjML
The same css code does not produce the same output of same height columns.
What do I wrong?
I can not use Flexbox!
<div class="container">
<div class="row">
<div class="row-same-height row-full-height">
<div style="background:orange;" class="col-xs-9 col-xs-height col-full-height">
<div class="item">
<div class="content">
<br><br><br><br><br><br><br>
</div>
</div>
</div>
<div style="background:red;" class="col-xs-3 col-xs-height col-full-height">
<div class="item"><div class="content">test2</div></div>
</div>
</div>
</div>
</div>
There are some styles in the minimit example that are not included in bootstrap. You need to add the following to get the heights you desire:
.row-same-height {
display: table;
width: 100%;
}
.col-xs-height {
display: table-cell;
float: none;
}
.col-full-height {
height: 100%;
vertical-align: middle;
}
Demo