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.
Related
I am trying to fix the header of my table so that it does not scroll but stays fixed in place.
I have searched some older SO threads to try and find a solution to fixing the header of a scrollable table. I'm rather new to bootstrap and React and I believe I am close. I am asking this question here to find an answer specific to my code.
my table in a react component
<div>
<div className="tablediv">
<div className="table-wrapper-scroll-y my-custom-scrollbar">
<table className="table table-hover table-striped table-light">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Value: USD</th>
</tr>
</thead>
<tbody>
{priceAndDateArray.slice(0).reverse().map((item, i) => (
<tr key={i}>
<th scope="row">{i+1}</th>
<td>{item.date}</td>
<td>{item.price}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
my css relevant to the table
.tablediv {
flex-wrap: wrap;
align-content: space-evenly;
padding: 5%;
justify-content: center
}
.tablediv tr {
cursor: pointer;
cursor: hand;
}
.my-custom-scrollbar {
position: relative;
height: 400px;
overflow: auto;
}
.table-wrapper-scroll-y {
display: block;
}
Expected results is the top header of the table (#, Date, Value: USD) to be fixed in place. Actual results are that they scroll with the table.
Try to add this.
.tablediv {
flex-wrap: wrap;
align-content: space-evenly;
padding: 5%;
justify-content: center;
position: fixed;
top: 0;
}
you want css position:sticky This will hold the header until the content scrolls past. Here's info and examples
Roughly though your css would look like this
thead {
position: sticky;
top:0; //or whatever offset you want
z-index: 100; // make sure it stacks higher than other stuff on the page
}
I am using primeng picklist. I found that when the options length in the target or source control are bigger then the picklist control buttons in the middle gets smaller. My picklist code follows
<p-pickList [source]="availableFormula" [target]="selectedFormula" sourceHeader="Available Formula"
targetHeader="Selected Formula" [responsive]="true" filterBy="Name" dragdrop="true" dragdropScope="cars"
sourceFilterPlaceholder="Search by Formula" targetFilterPlaceholder="Search by Formula" [sourceStyle]="{'height':'300px'}"
[targetStyle]="{'height':'300px'}" showSourceControls="false" [showTargetControls]="false" (onSourceSelect)="formulaSelectEvent($event)"
(onTargetSelect)="formulaSelectEvent($event)">
<ng-template let-availableFormula pTemplate="item">
<div class="ui-helper-clearfix">
<div style="font-size:14px;float:right;margin:15px 5px 0 0">{{availableFormula.Name}}</div>
</div>
</ng-template>
</p-pickList>
I tried the following in CSS override to make it not shrink but nothing worked.
.ui-picklist-buttons{
width: 100% !important;
}
The problem is not with the width of the buttons.
The problem is that the picklist-buttons and picklist-listwrapper are declared as table-cell and td's increase their width depending on content. ( Unlike a block elements )
If you just want to have fixed column widths use table-layout: fixed on the ui-picklist. If the problem is that one list has a very long word inside it, use word-break: break-word on the picklist-listwrapper or on the ui-picklist-item
See example below
.fixed {
table-layout: fixed;
width: 100%;
}
.buttons {
width: 20%;
background: blue;
}
.list {
width: 40%;
background: red;
}
.not-fixed .list {
word-break: break-word;
}
<!–– with table-layout: fixed but no break-word -->
<table class="fixed">
<tr>
<td class="list">40percent</td>
<td class="buttons">button</td>
<td class="list">veryveryveasasasarylongtextthatdoesntfitin40percent</td>
</tr>
</table>
<!–– with break-word -->
<table class="not-fixed">
<tr>
<td class="list">40percent</td>
<td class="buttons">button</td>
<td class="list">veryveryveasasasarylongtextthatdoesntfitin40percent</td>
</tr>
</table>
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>
The table on this page has a caption with display: table-caption set.
http://www.petersen-stainless.co.uk/lifting/CE-swage-sockets/stainless-steel-threaded-sockets.html
The HTML is:
<table class="product-data">
<caption>
Rated for lifting in accordance with EN 13411-8. WLLs stated based on 90% of wire MBL at a 6:1 factor of safety. All terminals permanently etched with CE mark and batch identification number.
</caption>
<tbody>
<tr>
<td data-th="Product Code">SCM6X3R-EN</td>
<td data-th="Wire (mm)">3</td>
<td data-th="Thread">M6</td>
<td data-th="D (mm)">6.3</td>
<td data-th="L (mm)">97.0</td>
<td data-th="CT (mm)">47.0</td>
<td data-th="WLL 7x19 / 6x19-IWRC">70kg</td>
<td data-th="WLL 6x36-IWRC">N/A</td>
</tr>
</tbody>
</table>`
And the css I used:
.content .product-data {
float: left;
margin-right: 20px;
width: 70%
}
.product-data caption {
display: table-caption;
width: 100%;
margin-bottom: 2em;
border: 1px solid #ccc;
box-sizing: border-box;
border-top: none;
}
It displays at 100% width of the table in webkit browsers but in firefox it is 100% width of the page. How can i get this caption to fit properly in firefox? Is it a bug? It seems like it shouldnt be behaving this way. If so are there any work arounds?
Please try to add
.content .product-data { display: inline-block; }
The issue will get fixed in firefox
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.