I am using Angular 7+ and trying to build a scheduling table using HTML table. In this table I have a sticky first column which contains the working days and then to the right I have the the hours of day scrolling horizontal.
The sticky first column has a set width so all the days are showing with equal width. The time columns also have smaller set width.
The issue is the width I set are not working ie it's not being displayed with the required width in the html for time. Instead the hrs are fixed to a very small width.
Can anyone help me fixing this? Ps I don't have to use table whatever works. Thanks in advance
Link to a stackblitz of my issue:
https://stackblitz.com/edit/angular-7-master-z9sdfl?file=src%2Fapp%2Fapp.component.html
Screenshot below:
And finally my code:
TEMPLATE
<div>
<table >
<tr *ngFor="let day of ['MONDAY', 'TUESDAY', 'WEDNESDAY','THURSDAY', 'FRIDAY']">
<td style="width:300px" class="sticky canvas side-panel">{{day}}</td>
<td
style="width:200px"
*ngFor="let col of [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]"
class="time">
{{col}} 00hrs</td>
</tr>
</table>
</div>
CSS
.sticky {
position: -webkit-sticky; /*safari*/
position: sticky;
left:0px;
background-color:#424242;
}
.canvas {
background-color:#424242;
color: white;
}
.time {
color:black;
background-color:white;border-right:1px solid red;border-left:1px solid red;
}
Remove the <div> element inside your <table>, this is the problem. Bind the *ngFor on your <tr> element. Try this.
When using IE11, this file's css takes priority over the inline style. So, please use style in css. I hope it will work
.sticky
{
min-width: 200px;
}
Related
I'm following a tutorial on youtube to create a replica of LinkedIn with CSS + ReactJS. I've been following the tutorial exactly (using it as more of a learning opportunity than anything) yet sometimes when the tutorial adds certain code, it doesn't appear on my environment when I try to add it. I found a work around for one case, but when I try to add a border-bottom to css it just won't show up.
CSS:
.header{
position: sticky;
top: 0;
display: flex;
justify-content: space-evenly;
border-bottom: thin solid lightgray; /*this is a vscode shortcut*/
padding-top: 10px;
padding-bottom: 10px;
width: 100%;
z-index: 999;
}
JS:
function Header() {
return (
<div className ='Header'>
<div className="header__left">
<img src="https://www.flaticon.com/svg/static/icons/svg/174/174857.svg" alt=""/>
<div className="header__search">
<SearchIcon/>
<input type="text"/>
</div>
<div className="header__right">
<HeaderOption Icon= {HomeIcon} title="Home"/>
<HeaderOption Icon={SupervisorAccountIcon} title="My Network"/>
</div>
</div>
</div>
);
}
*HeaderOption is an imported JS function I created. It isn't conflicting with the CSS I believe because I have removed it and the border still won't appear.
Thank you in advance.
CSS is case insensitive.
But in HTML the class and ID are case sensitive
change
<div className ='Header'>
to
<div className ='header'>
First off, you might wanna check your classNames' spelling for case-sensitivity.
If that's not the issue, your divs are probably collapsing with each other, so it renders the pixels through approximation. This is usually the case if you try zooming in your page and the missing border magically appears.
I suggest setting a height for your header where the borders don't collapse with the other divs' borders. Also, I prefer setting a fixed measurement unit rather like px,rem,%, etc. rathen than using thin.
I have found a lot of issues related to this one, but not one that matches the exact same problem and I was also not able to resolve my problem with other "related" issues. Below you can see two screenshots, one with overflow-x: auto and one without.
With overflow-x: auto
[[With overflows-x][]1]
Without overflow-x: auto
[[Without overflows-x][]1]
So overflow-x auto is cutting off my tooltip when it overflows vertically. I do not know why it behaves this way, even if I put overflow-y visible on it, it does not work.
Reason I am using overflow-x: auto
I am using overflow-x: auto to make my table responsive on resize. This will give me a scrollbar when the content does not fit. I see that many people use this to make their tables responsive.
Important code parts that I am currently using
HTML
<div key={uniqueKey} className={'table-container'}>
<table>
<thead>
<tr>
<th scope='col'>Id</th>
<th scope='col'>Name</th>
</tr>
</thead>
<tbody>
{someList.map((item, index) => {
return (
<tr key={index}>
<td data-label='Id'>{id}</td>
<td data-label='Name'>{name}</td>
<td data-label='Actions'>
<div className={'actions-container'}>
// EXISTING TOOLTIP COMPONENT HERE, I WILL SHOW THE CSS.
</div>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
CSS
.table-container {
overflow-x: auto;
border-collapse: separate;
table-layout: fixed;
table {
width: 100%;
tr {
height: 40px;
}
td {
height: auto;
}
th {
min-width: 175px;
padding: 8px;
}
}}
CSS Tooltip
.tooltip{
width: 300px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px;
border-radius: 6px;
position: absolute;
z-index: 100;
word-break: normal;
opacity: 0;
visibility: hidden;
transition: opacity 0.5s;
transition-delay: 0.4s;}
Other notes
I can not modify the tooltip too much since it is a existing component within our company, we would have to change it on lots of places. Also it works as expected on other places.
If there is any information missing, just let me know and I will respond as soon as possible.
Any insights are welcome at this point!
We had faced similar issue. The way we solved this is add a support to render the tooltip view in a react portal instead.
You'll need a component change but you don't need to change a lot of existing code.
Add a portal component:
const Portal = (props) => {
const { children, target = document.body } = props;
return ReactDOM.createPortal(children, target);
};
Add a usePortal prop that'll render the view in portal instead. Otherwise the view will be rendered as it is currently.
You'll have a viewDom that renders your tooltip view, use the Portal component:
const { usePortal } = props;
const viewDom = <span> Your view dom </span>;
if (usePortal) {
return (
<Portal>
{ viewDom }
</Portal>
)
}
// otherwise return the default dom without portal
return viewDom;
I’m not sure if this would solve the issue or not, but I noticed that the visibility is set to hidden and that will hide everything that doesn’t fit within that specific div. You might want to try setting that to visible to see if it fixes this cut off issue. I have no idea if that is the fix to this, but I wanted to try and help ha ha.
If your tooltips have a max-height, you can add padding/margin top to the table to clear that height.
So if
.tooltip {
...
max-height: 3em;
}
table {
margin-top: 3em;
}
Haven't tested it but your tr only has 40px height and will cut off the overflow on auto, because your three lines of text will take more than 40px space at all.
You should try to set the tr to position:relative and the tooltip to position:absolute for positioning and forget about the overflow;
I am having issues with my sticky table header in my angular 6 project.
I have a condition in my .ts file that applies the 'sticky' class only when the user scrolls towards a certain point in the page. That part works great. The issue is that when the position: fixed class is applied, it only works if top:0.
The css looks like this:
.sticky
{
position: fixed;
top:0;
width: 100%;
background-color: #fff;
padding-right: 20px!important;
}
But if I change top:0 to top:100, too account for the header of the webpage (that is build on another component) then the top:100 attribute won't apply and be considered invalid.
The html is a little tricky but looks a little like this
child.component.html
<div>
<navigation></navigation>
<div>
</div>
<div class="table-responsive " >
<table id="tabletop" #tabletop class="table scroll">
<thead #stickyMenu [class.sticky]="sticky">
<tr id="content" class="row1">
<tr id="content" class="row2">
<tr id="content" class="row3">
</thead>
</table>
</div>
</div>
app.component.html
<header></header>
<app-child></app-child>
<footer></footer>
I want the thead to stick right underneath the header that lives on a parent component, so it is still visible.
Why is that, and how can I get my position:fixed attribute to actually keep something at the top of the page?
Any help is greatly appreciated!
I wanted to post this by comment, but looks like I need at least 50 reputation to do so. So, here it goes:
But if I change top:0 to top:100 {...}
The unit of the top seems to be missing. You probably wanted to set it to 100px? Probably the 0 value confused you as it is allowed with or without a unit.
One more thing, the id of each element must be unique, but you have 3 id="content" there.
Alternative solution
You can use position: sticky css property on your thead element (and also on the respective th child elements). This way, you wouldn't need to handle the scroll event by yourself and let the css do the job for you.
Example:
I only include the scss part here, since the code snippets make the post unnecessarily long. You can see full example on stackblitz.com.
thead {
position: sticky;
top: 0px;
tr {
position: sticky; top: 0;
/* the top value can be adjusted according to <header>'s height */
&:nth-child(1) th { position: sticky; top: 110px; }
&:nth-child(2) th { position: sticky; top: 132px; }
}
}
Hello friend i am using Bootstrap-vue to display my data that query from database and i want it to display with the overflow-y like thisenter image description here
so how should i do. please tell me if you guy know how to solve it and here it is my code
<b-table
:items="search_transfer"
:fields="columnsheader"
:current-page="currentPage"
:per-page="perPage"
class="tbsearch"
></b-table>
and here it is what i get.
enter image description here
Hi simple solution is to make it display:inline-block;
add the below css to it
.tbsearch > tbody > tr > td:nth-child(4){
height: 65px;
overflow: auto;
display: inline-block;
}
Table cells in general can be a pain to apply some stylings to (due to their default display: table-cell)
Based on your first image, it looks like they are using a wrapper element around their cell content (based on the padding present around the outside of the scrollable area).
Use a custom slot for the cell rendering, and wrap your content in a <div> element that has your overflow-y class:
<template>
<b-table
:items="search_transfer"
:fields="columnsheader"
:current-page="currentPage"
:per-page="perPage"
>
<!--
I am making an assumption that the field you want to scroll is `description`
-->
<template v-slot:cell(description)="scope">
<div class="my-cell-overflow-y">
{{ scope.value }}
</div>
</template>
</b-table>
</template>
<style>
.my-cell-overflow-y: {
max-height: 2rem;
overflow-y: auto
}
</style>
See https://bootstrap-vue.js.org/docs/components/table#custom-data-rendering for details on custom data cell rendering.
I am trying to extract the nth child of an element, so that elements appear stacked within the same container.
I've tried reading over https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child, but to no avail.
I recreated the problem in a jsfiddle,
https://jsfiddle.net/ndga732y/
html:
<table>
<td>
<p id="image-1">first content</p>
<p id="image-2">second content</p>
</td>
</table>
css:
p:nth-child(0n){
offset-x: n*2px;
offset-y: n*2px;
}
I understand that selecting the nth child is easy, using the nth-child selector, but how do I use the n-value to create a different offset, depending on its order in a container?
Thanks in advance!
This isn't possible with plain CSS unfortunately.
You can use Javascript or a CSS preprocessor (probably a postprocessor as well?).
Here is how I would approach it with Sass, which would compile to CSS:
#for $i from 1 through 2 {
p:nth-child(#{$i}) {
top: $i * 100px;
left: $i * 50px;
position: relative;
}
}
and here's a quick demo: http://www.sassmeister.com/gist/8af65851d1c404be698f
You could use padding left and do something like
p:nth-child(2){
padding-left: 50px;
}