CSS Grid - Make table-like grid overflow when item is too big - html

I'm trying to create a table with CSS grid. So far I created a simple outline.
I have to create the grids at the row level (due to the fact that IRL the tables have more elements and I cannot make them at the table level). So far this works unless there is a very long word (or number), as in that case it overflows the containing cell.
My question is: is it possible to make the table overflow in order to make the cells at least as big as the biggest single word or number? (without making them breakā€”at least the numbers)
Thanks in advance!
Edit: I need to create a table with CSS grid as I need to use the same layout for the mobile version
Edit2: I don't know in advance how many elements I will have in the rows/columns, so I need to make use of repeat
Edit3: I'm looking for a pure CSS solution.
.table {
margin: 48px 0;
box-shadow: 0 5px 10px -2px #cfcfcf;
font-family: Arial;
}
.row {
display: grid;
grid-template-columns: repeat( auto-fit, minmax(72px, 1fr) );
min-height: 48px;
border-bottom: 1px solid #f1f1f1;
}
.column {
display: flex;
width: 100%;
height: 100%;
border: 1px solid #f1f1f1;
align-items: center;
}
.row:first-child {
font-weight: bold;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="table">
<div class="row">
<div class="column">Name</div>
<div class="column">Age</div>
<div class="column">Favourite Book</div>
<div class="column">Favourite Color</div>
<div class="column">Favourite Meal</div>
</div>
<div class="row">
<div class="column">Jimmy</div>
<div class="column">23</div>
<div class="column">None</div>
<div class="column">White</div>
<div class="column">Paella de Chorizo</div>
</div>
<div class="row">
<div class="column">Johny</div>
<div class="column">56</div>
<div class="column">Finnegans Wake</div>
<div class="column">Purple, Magenta and Violet</div>
<div class="column">None</div>
</div>
<div class="row">
<div class="column">Robert The Snake Robertson</div>
<div class="column">1.234.567.890.000.000</div>
<div class="column">The Count of Monte Cristo</div>
<div class="column">Orange</div>
<div class="column">Apples</div>
</div>
</div>
</body>
</html>

You want a table layout, then use table and not grid:
.table {
margin: 48px 0;
box-shadow: 0 5px 10px -2px #cfcfcf;
font-family: Arial;
display:table;
width:100%;
}
.row {
display: table-row;
min-height: 48px;
border-bottom: 1px solid #f1f1f1;
}
.column {
display: table-cell;
border: 1px solid #f1f1f1;
vertical-align: middle;
padding:10px 0;
}
.row:first-child {
font-weight: bold;
}
<div class="table">
<div class="row">
<div class="column">Name</div>
<div class="column">Age</div>
<div class="column">Favourite Book</div>
<div class="column">Favourite Color</div>
<div class="column">Favourite Meal</div>
</div>
<div class="row">
<div class="column">Jimmy</div>
<div class="column">23</div>
<div class="column">None</div>
<div class="column">White</div>
<div class="column">Paella de Chorizo</div>
</div>
<div class="row">
<div class="column">Johny</div>
<div class="column">56</div>
<div class="column">Finnegans Wake</div>
<div class="column">Purple, Magenta and Violet</div>
<div class="column">None</div>
</div>
<div class="row">
<div class="column">Robert The Snake Robertson</div>
<div class="column">1.234.567.890.000.000</div>
<div class="column">The Count of Monte Cristo</div>
<div class="column">Orange</div>
<div class="column">Apples</div>
</div>
</div>

Well you can use CSS fit-content(max-width) (docs) but I don't know if it can be used in conjunction with grid repeat().
.row {
display: grid;
grid-template-columns: auto, fit-content(300px), fit-content(100px), auto, auto;
min-height: 48px;
border-bottom: 1px solid #f1f1f1;
}
Edit: Inside a repeat(), you can use the max-content keyword.
grid-template-columns: repeat(auto-fit, minmax(auto, max-content));
You might need to add your own wrapping rules for some cells though.

You're using a mix of grid and flexbox. Try with just grid:
Updated to set the repeat style inline (since the amount of columns may change)
.grid {
display: grid;
grid-template-columns: repeat(1, 1fr);/* overridden inline */
border-top: 1px solid black;
border-right: 1px solid black;
}
.grid>div {
padding: 8px 4px;
border-left: 1px solid black;
border-bottom: 1px solid black;
}
.grid>div.th {
font-weight: bold;
}
<div class="grid" style="grid-template-columns: repeat(5,1fr);">
<div class="th">Name</div>
<div class="th">Age</div>
<div class="th">Favourite Book</div>
<div class="th">Favourite Color</div>
<div class="th">Favourite Meal</div>
<div>Jimmy</div>
<div>23</div>
<div>None</div>
<div>White</div>
<div>Paella de Chorizo</div>
<div>Johny</div>
<div>56</div>
<div>Finnegans Wake</div>
<div>Purple, Magenta and Violet</div>
<div>None</div>
<div>Robert The Snake Robertson</div>
<div>1.234.567.890.000.000</div>
<div>The Count of Monte Cristo</div>
<div>Orange</div>
<div>Apples</div>
</div>

Only add word-break: break-word; property in column class
.table {
margin: 48px 0;
box-shadow: 0 5px 10px -2px #cfcfcf;
font-family: Arial;
}
.row {
display: grid;
grid-template-columns: repeat( auto-fit, minmax(72px, 1fr) );
min-height: 48px;
border-bottom: 1px solid #f1f1f1;
}
.column {
display: flex;
width: 100%;
height: 100%;
border: 1px solid #f1f1f1;
align-items: center;
word-break: break-word;
}
.row:first-child {
font-weight: bold;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="table">
<div class="row">
<div class="column">Name</div>
<div class="column">Age</div>
<div class="column">Favourite Book</div>
<div class="column">Favourite Color</div>
<div class="column">Favourite Meal</div>
</div>
<div class="row">
<div class="column">Jimmy</div>
<div class="column">23</div>
<div class="column">None</div>
<div class="column">White</div>
<div class="column">Paella de Chorizo</div>
</div>
<div class="row">
<div class="column">Johny</div>
<div class="column">56</div>
<div class="column">Finnegans Wake</div>
<div class="column">Purple, Magenta and Violet</div>
<div class="column">None</div>
</div>
<div class="row">
<div class="column">Robert The Snake Robertson</div>
<div class="column">1.234.567.890.000.000</div>
<div class="column">The Count of Monte Cristo</div>
<div class="column">Orange</div>
<div class="column">Apples</div>
</div>
</div>
</body>
</html>

Related

CSS Grid dynamic columns auto-fit - gap between columns

I am trying youtube.com adaptive grid layout. I could achieve using CSS Grid. But if total number of cards are very less for example 2, card's width increasing to fit entire row. I could avoid this by setting max-width or width, but, gap betwwen cards changing when i change width of browser window.
How to set max-width without increasing the between cardds?
.grid-layout {
padding: 0;
margin: 0;
list-style: none;
border: 1px solid silver;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(5rem, 1fr) );
}
.card {
background: grey;
height: 4rem;
/* Uncommenting below line sets width but gap between card too high*/
/* max-width: 7rem; */
padding: 1px;
margin: 0.5rem;
line-height: 4rem;
color: white;
font-weight: bold;
font-size: 2rem;
text-align: center;
}
<section class="grid-layout">
<div class="card">0</div>
<div class="card">1</div>
<!-- <div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
<div class="card">16</div>
<div class="card">17</div>
<div class="card">18</div>
<div class="card">19</div> -->
</section>
Use grid-gap with a value of percentage:
.grid-layout {
list-style: none;
border: 1px solid silver;
display: grid;
grid-gap: 20%;
grid-template-columns: 1fr 1fr;
}
.card {
background: grey;
height: 8rem;
padding: 1px;
line-height: 8rem;
color: white;
font-weight: bold;
font-size: 2rem;
text-align: center;
}
<section class="grid-layout">
<div class="card">0</div>
<div class="card">1</div>
<!-- <div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
<div class="card">16</div>
<div class="card">17</div>
<div class="card">18</div>
<div class="card">19</div> -->
</section>
Is this what you want?
auto-fill works as per my expectations instead of auto-fit when columns doesn't wrap.
.grid-layout {
padding: 0;
margin: 0;
list-style: none;
border: 1px solid silver;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr) );
}
.card {
background: grey;
height: 4rem;
max-width: 7rem;
padding: 1px;
margin: 0.5rem;
line-height: 4rem;
color: white;
font-weight: bold;
font-size: 2rem;
text-align: center;
}
<section class="grid-layout">
<div class="card">0</div>
<div class="card">1</div>
<!-- <div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
<div class="card">16</div>
<div class="card">17</div>
<div class="card">18</div>
<div class="card">19</div> -->
</section>

Vertically Center (Using Bootstrap-CSS)

I have been writing some code for a website, and I'm not able to vertically center text. I have read multiple answers on StackOverflow and other sites about how to vertically center html (mainly using the display:table and display:table-cell methods and the top:50%, transformY method), however, I am not able to implement either of these methods successfully. I have attached my code here, hoping that someone will be able to spot an error of my mine which is causing the code to not work. (In this code, I have used the top:50%, transformY method of vertically centering text). Any help would be greatly appreciated.
HTML:
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="stylesheet.css">
<title>Game Timer and Scorekeeper</title>
</head>
<body>
<div class="container-fluid">
<div class="row" id="heading">
<div class="col-xs-12">
<div class="positioner">
<h1>Game Timer and Scorekeeper</h1>
</div>
</div>
</div>
<div class="row" id="top-labels">
<div class="col-xs-3 labels teamlabel" id="a-label">
<div class="positioner">
<h2>Team A</h2>
</div>
</div>
<div class="col-xs-6 labels" id="gameclock-label">
<div class="positioner">
<h2>Game Clock</h2>
</div>
</div>
<div class="col-xs-3 labels teamlabel" id="b-label">
<div class="positioner">
<h2>Team B</h2>
</div>
</div>
</div>
<div class="row" id="thirdrow">
<div class="col-xs-3 pointsclock teampoints" id="pointsA">
<div class="positioner">
<h1>POINTS A</h1>
</div>
</div>
<div class="col-xs-6 pointsclock" id="gameclock">
<div class="positioner">
<h1>GAME CLOCK</h1>
</div>
</div>
<div class="col-xs-3 pointsclock teampoints" id="pointsB">
<div class="positioner">
<h1>POINTS B</h1>
</div>
</div>
</div>
<div class="row" id="fourthrow">
<div class="col-xs-3 ptcontclock ptcontrol" id="ptcontrolA">
<div class="positioner">
<h2>CONTROL A</h2>
</div>
</div>
<div class="col-xs-6 ptcontclock" id="questionclock">
<div class="positioner">
<h2>QUESTION CLOCK</h2>
</div>
</div>
<div class="col-xs-3 ptcontclock ptcontrol" id="ptcontrolB">
<div class="positioner">
<h2>CONTROL B</h2>
</div>
</div>
</div>
</div>
</body>
</html>
CSS:
.container-fluid {
width: 100vw;
height: 100vh;
}
#heading {
height: 15vh;
border: 2px solid;
}
#top-labels {
height: 10vh;
border: 2px solid;
width: 100vw;
}
#top-labels .labels {
border-right: 2px solid;
border-left: 2px solid;
}
#thirdrow {
height: 40vh;
border: 2px solid;
width: 100vw;
}
#thirdrow .pointsclock {
height: 40vh;
border-right: 2px solid;
border-left: 2px solid;
}
#fourthrow {
height: 35vh;
width: 100vw;
}
#fourthrow .ptcontclock {
border-right: 2px solid;
border-left: 2px solid;
height: 35vh;
}
.positioner{
height:100%;
width:100%;
position: relative;
top: 50%;
transform: translateY(-50%);
}
You can try this.
HTML
<main>
<div>
I'm a block-level element with an unknown height, centered vertically
within my parent.
</div>
</main>
CSS
body {
background: #f06d06;
font-size: 80%;
}
main {
background: white;
height: 300px;
width: 200px;
padding: 20px;
margin: 20px;
display: flex;
flex-direction: column;
justify-content: center;
resize: vertical;
overflow: auto;
}
main div {
background: black;
color: white;
padding: 20px;
resize: vertical;
overflow: auto;
}
<main>
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
check this link for reference https://css-tricks.com/centering-css-complete-guide/

How can I set space between responsive div?

I'm new to css and wrote this html code:
<div class="col-1">A</div>
<div class="col-1">B</div>
<div class="col-1">C</div>
<div class="col-1">D</div>
<div class="col-1">E</div>
<div class="col-1">F</div>
<div class="col-1">G</div>
<div class="col-1">H</div>
<div class="col-1">I</div>
<div class="col-1">J</div>
<div class="col-1">K</div>
<div class="col-1">L</div>
and this is my css:
.col-1 {
width: 58px;
background-color: chocolate;
}
write up code for achive this output:
CLICK TO SHOW
but my result is this:
THIS LINK
How can i solve that problem?thanks.
You can simply add a margin margin: 1px; to your col-1 elements like this:
.col-1 {
width: 58px;
background-color: chocolate;
margin: 1px;
/*I just added this to make them inline */
display: inline-block;
}
<div class="col-1">A</div>
<div class="col-1">B</div>
<div class="col-1">C</div>
<div class="col-1">D</div>
<div class="col-1">E</div>
<div class="col-1">F</div>
<div class="col-1">G</div>
<div class="col-1">H</div>
<div class="col-1">I</div>
<div class="col-1">J</div>
<div class="col-1">K</div>
<div class="col-1">L</div>
It will give you the expected results, note that you can edit it with the wanted pixels.
I would reccommend using the new flexbox layout. Browser support is pretty good already (http://caniuse.com/#feat=flexbox) and you can add some vendor prefixes if needed.
.col-wrapper {
display: flex;
}
.col-1 {
width: 58px;
background-color: chocolate;
margin: 0px 6px;
}
<div class="col-wrapper">
<div class="col-1">A</div>
<div class="col-1">B</div>
<div class="col-1">C</div>
<div class="col-1">D</div>
<div class="col-1">E</div>
<div class="col-1">F</div>
<div class="col-1">G</div>
<div class="col-1">H</div>
<div class="col-1">I</div>
<div class="col-1">J</div>
<div class="col-1">K</div>
<div class="col-1">L</div>
</div>
.main{float: left; width: 100%; overflow: hidden; background: #eee; box-sizing: border-box;}
.col-1{float: left; width: 8%; box-sizing: border-box; overflow: hidden; padding: 5px; border: 1px solid #000; margin: 1%; background: #3C3}
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.main{float: left; width: 100%; overflow: hidden; background: #eee; box-sizing: border-box;}
.col-1{float: left; width: 8%; box-sizing: border-box; overflow: hidden; padding: 5px; border: 1px solid #000; margin: 1%; background: #3C3}
</style>
</head>
<body>
<div class="main">
<div class="col-1">A</div>
<div class="col-1">B</div>
<div class="col-1">C</div>
<div class="col-1">D</div>
<div class="col-1">E</div>
<div class="col-1">F</div>
<div class="col-1">G</div>
<div class="col-1">H</div>
<div class="col-1">I</div>
<div class="col-1">J</div>
</div>
</body>
</html>

Place banners side by side using HTML/CSS?

How to put banners side by side using HTML/CSS? Ideally with different sizes as shown below?
One simple way would be to display the banners inline-block, and assign them the required width.
.banner {
display: inline-block;
}
.banner-sm {
width: 32%;
}
.banner-lg {
width: 65%;
}
.banner {
height: 100px;
background: #DDD;
padding: 0; margin: 0;
}
<div class="row">
<div class="banner banner-lg"> </div>
<div class="banner banner-sm"> </div>
</div>
<div class="row">
<div class="banner banner-sm"> </div>
<div class="banner banner-sm"> </div>
<div class="banner banner-sm"> </div>
</div>
<div class="row">
<div class="banner banner-sm"> </div>
<div class="banner banner-lg"> </div>
</div>
Either use some grid system, or the bare CSS float property, pseudo example shown below:
.banner1 {
float: left;
width: 100px;
height: 20px;
margin: 4px;
border: 1px solid #777;
}
.banner2 {
float: left;
width: 200px;
height: 20px;
margin: 4px;
border: 1px solid #777;
}
.banner3 {
float: left;
width: 50px;
height: 20px;
margin: 4px;
border: 1px solid #777;
}
.clearfix {
clear: both;
}
<div class="banner1">banner</div>
<div class="banner1">banner</div>
<div class="clearfix"></div>
<div class="banner2">banner</div>
<div class="clearfix"></div>
<div class="banner3">banner</div>
<div class="banner3">banner</div>
<div class="banner3">banner</div>
<div class="banner3">banner</div>
<div class="clearfix"></div>
Good luck
You can use Twitter Bootstrap to get grid system and other useful layout functionality:
.row div {
height: 30px;
background: #aaa;
border: 1px solid #ddd;
}
* {
box-sizing: border-box;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='row'>
<div class='col-xs-8'></div>
<div class='col-xs-4'></div>
</div>
<div class='row'>
<div class='col-xs-4'></div>
<div class='col-xs-4'></div>
<div class='col-xs-4'></div>
</div>
<div class='row'>
<div class='col-xs-4'></div>
<div class='col-xs-8'></div>
</div>
<div class='row'>
<div class='col-xs-4'></div>
<div class='col-xs-8'></div>
<div class='col-xs-8'></div>
<div class='col-xs-4'></div>
</div>
If you are familiar with twitter-bootstrap then use its Grid system otherwise using inline-block will help you.
div {
border: 1px solid #ddd;
height: 200px;
margin: 5px;
display: inline-block;
box-sizing:border-box;
}
<section style="width:650px">
<div style="width:415px;"></div>
<div style="width:200px;"></div>
<div style="width:200px;"></div>
<div style="width:200px;"></div>
<div style="width:200px;"></div>
<div style="width:200px;"></div>
<div style="width:415px;"></div>
</section>
you can use CSS3 flex-box concept
.flex-container {
display: -webkit-flex;
display: flex;
width: 400px;
height: 250px;
background-color: lightgrey;
flex-direction:column;
}
.flex-item {
background-color: cornflowerblue;
width: calc(100% - 20px);
height: 100px;
margin: 10px;
display:flex;
justify-content:space-between;
}
.sub{
height:100%;
background:white;
box-sizing:border-box;
}
.one{
width:75%;
border:1px solid green;
}
.two{
width:25%;
border:1px solid red;
}
.subb{
width:33%;
background:white;
height:100%;
}
<div class="flex-container">
<div class="flex-item">
<div class="sub one">sub 1 </div>
<div class="sub two">sub 2 </div>
</div>
<div class="flex-item">
<div class="subb s3">sub 3 </div>
<div class="subb s4">sub 4 </div>
<div class="subb s5">sub 5 </div>
</div>
</div>
You can use Bootstrap to do this.
Bootstarp is a Powerful css framework which enables web developer's
to do stuff like these(dividing screens etc).
Bootstrap is very easy to learn and implement.
You can start Learning Bootstrap here

Setting the variable percentage width of HTML elements next to other variable-width elements

I have a HTML structure with given CSS.
Both caption and progress elements should be rendered in same line. caption elements should not have fixed width and progress elements should fill up the rest of the space next to caption based on their inline-set width, which means that every progress element will have a different total pixel-width but should fill up only the given percentage of available space.
HTML structure and CSS rules can be changed in any way.
Is it possible to solve this problem with CSS only?
.table {
padding: 15px;
width: 280px;
border: 1px solid black;
font-family: sans-serif;
font-size: 12px;
}
.caption {
float: left;
}
.progress {
height: 14px;
border: 1px solid white;
border-radius: 4px;
background-color: green;
overflow: hidden;
}
.value {
margin-left: 5px;
}
<div class="table">
<div class="row">
<div class="caption">Short text: </div>
<div class="progress" style="width:11.65%">
<span class="value">11.65</span>
</div>
</div>
<div class="row">
<div class="caption">A bit longer text: </div>
<div class="progress" style="width:100%">
<span class="value">100.00</span>
</div>
</div>
<div class="row">
<div class="caption">X: </div>
<div class="progress" style="width:45.50%">
<span class="value">45.50</span>
</div>
</div>
</div>
Have you considered using Flexbox?
Just add this rule:
.row {
display: flex;
}
If your are concerned about browser support, an alternative would be using display:table. You should change your markup and CSS, like this:
.table {
border: 1px solid black;
font-family: sans-serif;
font-size: 12px;
padding: 15px;
width: 280px;
}
.inner-table {
display: table;
}
.row {
display: table-row;
}
.caption {
display: table-cell;
white-space: nowrap;
width: 1%;
}
.progress {
background-color: green;
border: 1px solid white;
border-radius: 4px;
display: table-cell;
height: 14px;
}
.value {
margin-left: 5px;
display:block;
width:0;
overflow: visible;
}
<div class="table">
<div class="inner-table">
<div class="row">
<div class="caption">Short text: </div>
<div style="width:1.65%" class="progress">
<span class="value">1.65</span>
</div>
<div class="remainder"></div>
</div>
</div>
<div class="inner-table">
<div class="row">
<div class="caption">A bit longer text: </div>
<div style="width:100%" class="progress">
<span class="value">100.00</span>
</div>
<div class="remainder"></div>
</div>
</div>
<div class="inner-table">
<div class="row">
<div class="caption">X: </div>
<div class="progress" style="width:45.50%">
<span class="value">45.50</span>
</div>
<div class="remainder"></div>
</div>
</div>
</div>
Please try this - padding-right: 5px; display:inline; add these properties in progress class and also remove width in progress.
Well, just for the future reference, I was playing a bit with the flexbox thingie and came up with this:
.table {
padding: 15px;
width: 280px;
border: 1px solid black;
font-family: sans-serif;
font-size: 12px;
}
.row {
display: flex;
}
.caption {
margin: 1px 5px 1px 0;
}
.progress {
flex-grow: 1;
margin: auto;
}
.progress-content {
height: 14px;
border-radius: 4px;
background-color: green;
}
.value {
margin-left: 5px;
}
<div class="table">
<div class="row">
<div class="caption">Short text:</div>
<div class="progress">
<div class="progress-content" style="width:11.65%">
<span class="value">11.65</span>
</div>
</div>
</div>
<div class="row">
<div class="caption">A bit longer text:</div>
<div class="progress">
<div class="progress-content" style="width:100%">
<span class="value">100.00</span>
</div>
</div>
</div>
<div class="row">
<div class="caption">X:</div>
<div class="progress">
<div class="progress-content" style="width:45.50%">
<span class="value">45.50</span>
</div>
</div>
</div>
</div>
If I get a solution without flexbox, will accept it as an answer :)