Table with dynamic content (rows) taking too much height - css

I have a regular table with table rows that are generated with ngFor loop.. the issue is the following: Even though I have set css of table-wrapper to max-height: 450px and overflow-y: auto; , it doesnt matter, that div gets the scroll needed, but my entire page, entire body element, has the height of that table with every single row... Anyone had similar issue?
.table-wrapper {
display: block;
max-height: 450px;
overflow-y: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
td {
border: 1px solid black;
}
<div class="table-wrapper">
<!-- I'm reproducing the DOM after Angular ng for -->
<table>
<tr *ngFor="let s of something">
<td>Some content</td>
</tr>
</table>
</div>

Related

Vertical stretch of a table, without moving its content

despite the fact that I'm working on a project using Angular and angular material, the solution might be pure CSS.
So I have a table with very few elements in it 2 or 3 rows for the moment and I want it to be at a fixed height (let's say 700px). I tried setting the height of the table to 700px, BUT, the content of my table is stretching to fill it, so if I have two rows, they will have top and bottom padding to fille the table. therefore the total height of each of my two cells is 350px (if my table body is 700px).
Another problem I have is that angular material doesn't have vertical separators for each column. Therefore I have to set a border to my cells, but if my cells don't take all the height of the table, I don't have a full vertical line, it ends at my last row.
I tried playing around with flex attributes but nothing worked.
This is basicaly what I have for the moment:
<div id="main-table">
<div id="table-container">
<table id="master" mat-table [dataSource]="projects">
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let project" class="py-0 px-0">
<button mat-button (click)="getVersionsList(project);" class="cell-button"> {{project.name}} </button>
</td>
</ng-container>
<!-- Description Column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> Description </th>
<td mat-cell *matCellDef="let project" class="py-0"> {{project.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<!-- other stuff -->
</div>
.mat-header-cell, .mat-cell{
padding: 12px;
}
.py-0 { // padding on Y axis 0
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.px-0, .cell-button { // padding on X axis 0
padding-left: 0 !important;
padding-right: 0 !important;
}
.cell-button{
width: 100%;
padding: 6px 0;
}
.mat-row {
height: auto;
}
.mat-cell{
//padding-top: 16px;
//padding-bottom: 16px;
//border-right: rgba(0,0,0,.12) 1px solid;
border-bottom: 0;
}
My CSS is quite empty since nothing was working.
Thanks for helping.
I had the same problem because Angular Material Table is not responsive at all. So while searching for a solution, I came up with this: https://ampersandacademy.com/tutorials/angular-material/scrollable-table-in-angular-material
I'm using only css (instead o scss), so here's my code for it:
.table-responsive {
display: block;
width: 100%;
overflow-x: auto;
}
.table-responsive .mat-table {
width: 100%;
max-width: 100%;
margin-bottom: 1rem;
display: table;
border-collapse: collapse;
margin: 0px;
}
.table-responsive .mat-row, .table-responsive .mat-header-row {
display: table-row;
}
.table-responsive .mat-cell, .table-responsive .mat-header-cell {
word-wrap: initial;
display: table-cell;
padding: 0px 5px;
line-break: unset;
width: auto;
white-space: nowrap;
overflow: hidden;
vertical-align: middle;
}
Just add it to your styles.css, make a div surrounding your table, and add the "table-responsive" class
<div class="mat-elevation-z1 table-responsive">
<table mat-table [dataSource]="dataSource">
...
</table>
</div>
But there's a problem: this doesn't work well if you have a mat-paginator for your table. I did a workaround by setting him outside the "table-responsive" div, which worked pretty well for me.

How to make table header fixed when scrolling and table scroll goes background

I am using table (angular-4-data-table) which displays the rows. I wanted to have a vertical scrollbar with header fixed. I tried to add style= position: fixed; to the
<thead> section. I can see the fixed header, but when I scroll through, the table data section was moving on top of the header.
<table class="table table-condensed table-bordered data-table">
<thead style= position: fixed;>
</thead>
<tbody>
</tbody>
</table>
Is there any style that I can apply on tbody so that when scroll happens, it hides beneath the header.
tbody tag is relative so it will just operate as every other element in the page.
You should work only on the "special" element (thead) in order to let the browser works with the highest number of common element possible.
Have you tried giving z-index:999; as thead style?
Ok, now I remember how to do that.
Inside each <th> insert a <div> with the content of the column header, than using CSS you must set the div position absolute over the table and the th with 0 height.
Plus, you must give to a <div> containing the table a top-padding to leave the space for the fake <th>
It's not a nice code, but it works without JS.
<style>
.container { padding-top: 50px; }
.inner { height: 100px; overflow-y: auto; }
.t { width: 100%; table-layout: fixed; }
.t thead th { height: 0 !important; }
.t thead th > div {
position: absolute;
height: 50px;
line-height: 50px;
top: 0;
}
</style>
<div class="container">
<div class="inner">
<table class="t">
<thead><tr>
<th><div>col 1</div></th>
<th><div>col 2</div></th>
</tr></thead>
<tbody>
<tr>
<td>a</td>
<td>b</td>
</tr>
</tbody>
</table>
</div>
</div>

How to fit images into <td> keeping the exact size of <td>

I'm trying to sort out quite a challenging issue. I have a header of a website into which three random picture will be generated. The collection of picture is quite huge and so the aspect ratio vary from picture to picture.
The header of the web is in fact a responsive table with one row and three table cell:
.header table {
width: 94%;
border: 0;
background: transparent;
margin-left: 5%;
margin-right: 5%;
vertical-align: middle;
display: table;
}
Now what I'd like to do is to:
Keep the table responsive (i.e. if possible avoid defining width and height with pixels and use rather "%") => like this:
.header td {
display: table-cell;
width: 25%;
height: auto;
text-align: center;
vertical-align: middle;
}
...but at the same time, to fit three random picture into to the table cell without changing the size or aspect ratio of the table cell... It means that some pictures will be cropped.
I was experimenting with the css3 attribute contain:
.header td {...
background-repeat: no-repeat;
background-size: contain;
...}
<table class="header">
<tr>
<td class="header" style="background-image:url('img/random1.jpg')">
</td>
<td class="header" style="background-image:url('img/random2.jpg')">
</td>
<td class="header" style="background-image:url('img/random3.jpg')">
</td>
</tr>
</table>
But it this attribute doesn't seem to be friend with the td tag...
Anyways, I'm not actually insisting on the "table" solution. Does anyone have any kind of work around how to:
Make three pictures in a "row" responsible
Fit them into frames which don't change their proportion
?
Pure CSS solution is preferable but I guess it might not be possible.
First of all you need some kind of a width and hight relation, otherwhise you woun't get a responsive behavior.
So i did some dirty hack ^^
I insert a image into each td that gives me the relation, then i hide it with opacity 0 (won't work in ie8). Now if you want to insert some other contetn then work with positions and seperate containers.
HTML:
<table class="header">
<tr>
<td class="header" style="background-image:url('img/1.jpg')">
<img src="img/1.jpg" />
</td>
<td class="header" style="background-image:url('img/2.jpg')">
<img src="img/1.jpg" />
</td>
<td class="header" style="background-image:url('img/3.jpg')">
<img src="img/1.jpg" />
</td>
</tr>
</table>
then i altered your CSS:
table {
width: 94%;
border: 0;
background: transparent;
margin-left: 5%;
margin-right: 5%;
vertical-align: middle;
}
td {
width: 25%;
height: auto;
text-align: center;
vertical-align: middle;
background-repeat: no-repeat;
background-size: cover;
overflow-x: hidden;
display: inline-block;
}
td img {
opacity: 0;
width: 100%;
height: auto;
}
It's looking kind a wierd becaus im using a table layout and then i overwrite the tabel display behavior (display: inline-block), but im missing some backround informations so i decided to use exact yout html.
Here you can see the result JS Fiddle

Width issue with input in table's thead th

I have a table which has a peculiar style issue when I insert an input element in the header. It does not center the input exactly; instead it is off by 2 pixels on the right side. I have some Twitter Bootstrap styles applied to the table, but I can't find one that is causing the issue so I don't think that has anything to do with it. Here is the markup:
<thead>
<tr>
<th scope="col" style="width: 5%;">
ID
<input type="text" value="" class="grid-filter" id="id-filter">
</th>
...
Here is a picture of the issue (zoomed in considerably):
Here are the styles applied:
th {
width: 15%;
a { display: block; }
input {
height: 15px;
line-height: 15px;
margin: 0;
padding: 5px 0;
width: 100%;
}
}
In the image above, I'm using Firebug and have focused on the "ID" anchor. As you can see, the anchor is correctly centered in the th, but the input box has an extra 2 pixels on the right for some reason. Why is this? The weird thing is that this does NOT affect select elements, only input elements.
Update: When I set the border and outline, Bootstrap's focus glow also has a border. Not sure which style to override...
edit: looks like the problem is your width attribute. Check this JSFiddle
HTML:
<table>
<thead>
<tr>
<th scope="col" style="width: 5%;">
ID
<input type="text" value="" class="grid-filter" id="id-filter"/>
</th>
</tr>
</thead>
</table>
CSS:
a, input {
padding: 0;
margin 0;
}
a {
display: block;
background: red;
}
input {
height: 15px;
line-height: 15px;
/* width: 100%; */
}
table { width: 3em }
The width attribute on the input defaults to auto, which does what you want in this case.

Table expand row with just CSS

I have some markup like so:
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<tr>
</thead>
<tbody>
<tr class="main">
<td>some content</td>
<td>some content2</td>
<tr>
<tr class="more">
<td colspan="2">
<div class="more-link"><a tabindex="0" href="#">Show more info</a></div>
<div class="more-info">
more info goes here
</div>
</td>
<tr>
</tbody>
</table>
And some CSS:
td, th{
border: 1px solid red;
}
.main td{
height: 50px;
width: 300px;
vertical-align: top;
}
.main td{
border-bottom: 0;
}
.more td{
border-top: 0;
height: 0;
}
.more-link{
position: relative;
top: -30px;
}
.more-link:focus + div, .more-link:active + div{
height: auto;
}
What I want to do is that when the "show more info" link is clicked, the table row called "more" expands.
The problems:
There is no effect if I set the td inside more to have a height of 0;
If I set height of the more-info div to 0, or display:none, the table row still takes up space.
I would like to do this with just CSS, javascript can be used to make it better, but the basics should just work without javascript.
How can I get my more row to expand when the show more info link is clicked?
And a fiddle: http://jsfiddle.net/QJr2e/
Got it!
Instead of using position:relative to move the "show more info" link, I gave it a float:left. This allowed me to move it anywhere I want using margin, while reorganizing the flow.
Instead of using height, I just set more-info to display:none, and then when the "show more info" link is clicked:
.more-link:active + div, .more-link:focus + div{
display: block;
}

Resources