Prevent content from expanding or overflowing column - html

I am new to CSS grid and tried hard but no luck, I am creating a printable format for A4 paper,and have setup fixed sizes for the columns. The content of the column "UNIT" in the first row (excluding Header row) is spanned/expanded to the next column whenever VALUE entered exceeds the width/border. I want the VALUE (i.e "UnitName12345678") not to cross the border but move to the next line in the same column. Also in minmax(50px , max-content) 50px is applied to only the HEADER row and what I am missing in to apply that to all the rows.
This Container will be having multiple rows generated dynamically.
Present output:
Expected output:
Code Pen : https://codepen.io/thaslim123/pen/gyQwmm
body {
margin: 0px;
}
.printcontainertable {
display: inline-grid;
grid-template-rows: minmax(50px, max-content);
grid-template-columns: 100px 500px 100px 100px 100px 100px;
width: 1150px;
padding: 10px;
}
.printcontainertable div {
border: 1px solid black;
text-align: center;
}
<div class="printcontainertable">
<div> SL.No</div>
<div> Product name</div>
<div> Unit</div>
<div> Qty</div>
<div> Price</div>
<div> total</div>
<div> 1. </div>
<div> Apple </div>
<div>UnitName12345678</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
<div> 2. </div>
<div> Orange </div>
<div>UnitName</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
</div>
PS: As I will be having fixed HEADER and FOOTER container on top and bottom of the above container (i.e .printcontainertable), How can I fix a static Height for the same. Kindly Suggest me if any other better way to implement it in GRID.

Alright, I do think there are some other things that can be improved depeniding on exactly what you need (semantics, structure, etc.) the main issue regarding the word that exceeds the border can be fixed by applying word-break: break-word to the item that contains the text.
body {
margin: 0px;
}
.printcontainertable {
display: inline-grid;
grid-template-rows: minmax(50px, max-content);
grid-template-columns: 100px 500px 100px 100px 100px 100px;
width: 1150px;
padding: 10px;
}
.printcontainertable div {
border: 1px solid black;
text-align: center;
}
.unitname {
word-break: break-word;
}
<div class="printcontainertable">
<div> SL.No</div>
<div> Product name</div>
<div> Unit</div>
<div> Qty</div>
<div> Price</div>
<div> total</div>
<div> 1. </div>
<div> Apple </div>
<div class="unitname">UnitName12345678</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
<div> 2. </div>
<div> Orange </div>
<div>UnitName</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
</div>

I want the VALUE (i.e "UnitName12345678") not to cross the border but move to the next line in the same column.
Then allow the unbroken line of text to break into multiple lines. Use the overflow-wrap property.
Add this to your code:
.printcontainertable div {
overflow-wrap: break-word;
}
Also in minmax(50px , max-content), 50px is applied to only the HEADER row and what I am missing is to apply that to all the rows.
You're using grid-template-rows. This creates explicit rows, meaning rows that you define.
So when you say this:
grid-template-rows: minmax(50px , max-content);
...you're defining only one row with that rule.
You need to use grid-auto-rows, which applies to implicit rows, which is what you need when rows are generated dynamically.
Make this adjustment to your code:
.printcontainertable {
display: inline-grid;
/* grid-template-rows: minmax(50px , max-content); */
grid-auto-rows: minmax(50px , max-content); /* new */
grid-template-columns: 100px 500px 100px 100px 100px 100px;
width:1150px;
padding:10px;
}
.printcontainertable {
display: inline-grid;
/* grid-template-rows: minmax(50px , max-content); */
grid-auto-rows: minmax(50px, max-content); /* new */
grid-template-columns: 100px 500px 100px 100px 100px 100px;
width: 1150px;
padding: 10px;
}
.printcontainertable div {
overflow-wrap: break-word; /* new */
border: 1px solid black;
text-align: center;
}
body {
margin: 0px;
}
<div class="printcontainertable">
<div> SL.No</div>
<div> Product name</div>
<div> Unit</div>
<div> Qty</div>
<div> Price</div>
<div> total</div>
<div> 1. </div>
<div> Apple </div>
<div>UnitName12345678</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
<div> 2. </div>
<div> Orange </div>
<div>UnitName</div>
<div>10</div>
<div> 100.00 </div>
<div> 1000.00 </div>
</div>

Related

Having problems with fitting content in div with css grid

I'm playing around with Css Grid and having problems with fitting overlaying content.
There is a top level container defined as css grid (class="container"), then content grid (class="content") which splits into 3 rows (header, label, rows).
Header is just a header, label contains labels for rows and rows is a content of "table".
Here is what it looks like:
When I resize window I got scroll bar on the right but it's for the whole page. Instead I would like to scroll only rows not the whole page.
Here is the the StackBlitz working example:
https://stackblitz.com/edit/angular-ivy-ayujp5
I guess it's simple but having problems with understanding how height is calculated and where and how overflow properties should be defined.
p {
font-family: Lato;
}
.container {
display: grid;
grid-template-columns: 30px 1fr 30px;
grid-template-rows: 30px 1fr 30px;
grid-template-areas: '. . .' '. content .' '. . .';
}
.content {
grid-area: content;
display: grid;
grid-template-rows: 50px 30px 1fr;
grid-template-areas: 'header' 'label' 'rows';
}
.header {
grid-area: header;
}
.label {
grid-area: label;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: repeat(3, 4fr);
align-items: center;
}
.rows {
grid-area: rows;
height: 100%;
}
.row {
background-color: pink;
margin: 5px 0px;
border-width: 1px;
border-radius: 10px;
padding: 25px;
color: black;
}
<div class="container">
<div class="content">
<div class="header">Header</div>
<div class="label">
<div>Name</div>
<div>From</div>
<div>To</div>
</div>
<div class="rows">
<div class="row">
<div class="label">
<div>1</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>3</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>4</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
</div>
I go with height calculation .pin-table { height: calc(100vh - 125px); overflow: auto; } but if anyone has better idea feel free to write.

CSS Grid with Angular | Don't distribute grid items equally on width

I have a app which has rows and columns. I can dynamically remove rows. When I remove them then the other items distribute themself equaly over the width of the grid.
Now I want to have something like flex, but with grid. The grid items should have a margin to the next item beside them. Like that. And not distribute themself over the width.
CSS
.column {
padding: 10px;
margin: 10px 0;
display: grid;
grid-auto-flow: column;
.row-item {
text-align: center;
display: grid;
grid-auto-rows: 25px;
grid-row-gap: 10px;
width: 9vw;
}
}
HTML
<div class="column">
<ng-container *ngFor="let jS of journeyStepDisplay">
<div *ngIf="jS.display" class="row-item">
<div class="column-item header">
<p>{{ jS.name }}</p>
</div>
</div>
</ng-container>
</div>
If you have a minimum and/or a max width of the grid items that are to be distributed, you can use a combination of different grid properties to get the desired outcome, like
grid-template-columns: repeat(auto-fit, minmax(100px, 100px));
In the example below, we have a grid where the items will be distributed evenly with a min/max width of 100px. If they can't fit into the row a new row will be inserted.
.container {
height: 200px;
width: 600px;
gap: 5px;
border: 2px solid red;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 100px));
grid-template-rows: auto;
padding: 10px;
}
.box {
border: 2px solid blue;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
You have to declare width for each item.
<div class="column">
<div class="row-item">
<div class="column-item header">
<p>ciao</p>
</div>
</div>
<div class="row-item">
<div class="column-item header">
<p>ciao2</p>
</div>
</div>
<div class="row-item">
<div class="column-item header">
<p>ciao3</p>
</div>
</div>
</div>
.column {
width: 100%;
display: grid;
grid-template-columns: 150px 150px 150px 150px;
grid-template-rows: auto;
}
.row-item {
text-align: center;
}
here a useful guide.
(I didn't use directive from angular, but you can add it)

CSS Grids - Padding causes child element to overflow

Here's my code:
.media {
display: grid;
box-sizing: border-box;
padding: 10rem;
border: 1px solid red;
grid-template-columns: repeat(auto-fit, minmax(50rem, 1fr));
}
.big-pic {
width: 100%;
height: 10rem;
border: 1px solid blue;
}
.small-pic {
display: inline-block;
margin-right: -.5rem;
width: 50%;
height: 10rem;
border: 1px solid blue;
}
<div class="media">
<div class="column">
<h2>On TV</h2>
<div class="big-pic">
Main Pic
</div>
<div class="small-pic">
Pic 1
</div>
<div class="small-pic">
Pic 2
</div>
</div>
<div class="column">
<h2>In Theaters </h2>
<div class="small-pic">
Pic 1
</div>
<div class="small-pic">
Pic 2
</div>
<div class="big-pic">
Main Pic
</div>
</div>
When you lower the screen size of the browser, the child elements will overflow out of the container. Why is not the column (a wrapper <div> with a class of column) width not filling the parent's width?
I used grid-template-columns: repeat(auto-fit, minmax(50rem, 1fr)); So 1fr should fill up the parent's width. When you add the padding, it overflows. Without the padding, it fills up the parent's width. Not sure what's happening.
Adding box-sizing: border-box doesn't fix the issue either. Any ideas on how to fix it?

CSS Grid Group Variable Width Columns into Fixed Width

I've just started learning about CSS Grids and I'm struggling to achieve a certain layout. I have a grid with 4 columns and I want the total width of column 1 + column 2 to equal 50% of the grid and the total width of column 3 + column 4 to equal 50% of the grid. The tricky part is I need the individual columns to have variable widths, specifically columns 1 and 3 to expand with the text they contain and columns 2 and 4 to grow and shrink in relation to the width of columns 1 and 3. Is this possible using the grid layout?
I've been using codepen to test:
https://codepen.io/anon/pen/MqxJNW
<div class="outergrid">
<div class="one">One</div>
<div class="two">Two </div>
<div class="three">Three</div>
<div class="four">Four</div>
<div class="five">Five</div>
<div class="six">Six</div>
<div class="Seven">Seven</div>
<div class="Eight">Eight</div>
<div class="Nine">Nine</div>
<div class="Ten">Ten</div>
* {box-sizing: border-box;}
.outergrid
{
display:grid;
max-width: 540px;
margin: 0 auto;
grid-template-columns: repeat(4, auto);
grid-template-rows: repeat(3, auto);
gap: 5px 5px;
}
.outergrid > div
{
border: 2px solid rgb(233,171,88);
border-radius: 5px;
background-color: rgba(233,171,88,.5);
padding: 1em;
color: #d9480f;
word-break: break-word;
}
Thanks

CSS grid wrapping

Is it possible to make a CSS grid wrap without using media queries?
In my case, I have a non-deterministic number of items that I want placed in a grid and I want that grid to wrap. Using Flexbox, I'm unable to reliably space things nicely. I'd like to avoid a bunch of media queries too.
Here's some sample code:
.grid {
display: grid;
grid-gap: 10px;
grid-auto-flow: column;
grid-template-columns: 186px 186px 186px 186px;
}
.grid > * {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
And here's a GIF image:
As a side-note, if anyone can tell me how I could avoid specifying the width of all the items like I am with grid-template-columns that would be great. I'd prefer the children to specify their own width.
Use either auto-fill or auto-fit as the first argument of the repeat() notation.
<auto-repeat> variant of the repeat() notation:
repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
auto-fill
When auto-fill is given as the repetition number, if the grid
container has a definite size or max size in the relevant axis, then
the number of repetitions is the largest possible positive integer
that does not cause the grid to overflow its grid container.
https://www.w3.org/TR/css-grid-1/#valdef-repeat-auto-fill
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 186px);
}
.grid>* {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
The grid will repeat as many tracks as possible without overflowing its container.
In this case, given the example above (see image), only 5 tracks can fit the grid-container without overflowing. There are only 4 items in our grid, so a fifth one is created as an empty track within the remaining space.
The rest of the remaining space, track #6, ends the explicit grid. This means there was not enough space to place another track.
auto-fit
The auto-fit keyword behaves the same as auto-fill, except
that after grid item placement any empty repeated tracks are collapsed.
https://www.w3.org/TR/css-grid-1/#valdef-repeat-auto-fit
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, 186px);
}
.grid>* {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
The grid will still repeat as many tracks as possible without overflowing its container, but the empty tracks will be collapsed to 0.
A collapsed track is treated as having a fixed track sizing function of 0px.
Unlike the auto-fill image example, the empty fifth track is collapsed, ending the explicit grid right after the 4th item.
auto-fill vs auto-fit
The difference between the two is noticeable when the minmax() function is used.
Use minmax(186px, 1fr) to range the items from 186px to a fraction of the leftover space in the grid container.
When using auto-fill, the items will grow once there is no space to place empty tracks.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
}
.grid>* {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
When using auto-fit, the items will grow to fill the remaining space because all the empty tracks will be collapsed to 0px.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
}
.grid>* {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
Playground:
CodePen
Inspecting auto-fill tracks
Inspecting auto-fit tracks
You want either auto-fit or auto-fill inside the repeat() function:
grid-template-columns: repeat(auto-fit, 186px);
The difference between the two becomes apparent if you also use a minmax() to allow for flexible column sizes:
grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
This allows your columns to flex in size, ranging from 186 pixels to equal-width columns stretching across the full width of the container. auto-fill will create as many columns as will fit in the width. If, say, five columns fit, even though you have only four grid items, there will be a fifth empty column:
Using auto-fit instead will prevent empty columns, stretching yours further if necessary:
You may be looking for auto-fill:
grid-template-columns: repeat(auto-fill, 186px);
Demo: http://codepen.io/alanbuchanan/pen/wJRMox
To use up the available space more efficiently, you could use minmax, and pass in auto as the second argument:
grid-template-columns: repeat(auto-fill, minmax(186px, auto));
Demo: http://codepen.io/alanbuchanan/pen/jBXWLR
If you don't want the empty columns, you could use auto-fit instead of auto-fill.
I had a similar situation. On top of what you did, I wanted to center my columns in the container while not allowing empty columns to for them left or right:
.grid {
display: grid;
grid-gap: 10px;
justify-content: center;
grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
Here's my attempt. Excuse the fluff, I was feeling extra creative.
My method is a parent div with fixed dimensions. The rest is just fitting the content inside that div accordingly.
This will rescale the images regardless of the aspect ratio. There will be no hard cropping either.
body {
background: #131418;
text-align: center;
margin: 0 auto;
}
.my-image-parent {
display: inline-block;
width: 300px;
height: 300px;
line-height: 300px; /* Should match your div height */
text-align: center;
font-size: 0;
}
/* Start demonstration background fluff */
.bg1 {background: url(https://unsplash.it/801/799);}
.bg2 {background: url(https://unsplash.it/799/800);}
.bg3 {background: url(https://unsplash.it/800/799);}
.bg4 {background: url(https://unsplash.it/801/801);}
.bg5 {background: url(https://unsplash.it/802/800);}
.bg6 {background: url(https://unsplash.it/800/802);}
.bg7 {background: url(https://unsplash.it/802/802);}
.bg8 {background: url(https://unsplash.it/803/800);}
.bg9 {background: url(https://unsplash.it/800/803);}
.bg10 {background: url(https://unsplash.it/803/803);}
.bg11 {background: url(https://unsplash.it/803/799);}
.bg12 {background: url(https://unsplash.it/799/803);}
.bg13 {background: url(https://unsplash.it/806/799);}
.bg14 {background: url(https://unsplash.it/805/799);}
.bg15 {background: url(https://unsplash.it/798/804);}
.bg16 {background: url(https://unsplash.it/804/799);}
.bg17 {background: url(https://unsplash.it/804/804);}
.bg18 {background: url(https://unsplash.it/799/804);}
.bg19 {background: url(https://unsplash.it/798/803);}
.bg20 {background: url(https://unsplash.it/803/797);}
/* end demonstration background fluff */
.my-image {
width: auto;
height: 100%;
vertical-align: middle;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
<div class="my-image-parent">
<div class="my-image bg1"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg2"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg3"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg4"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg5"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg6"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg7"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg8"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg9"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg10"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg11"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg12"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg13"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg14"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg15"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg16"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg17"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg18"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg19"></div>
</div>
<div class="my-image-parent">
<div class="my-image bg20"></div>
</div>