CSS in Angular project: position: fixed not always functioning as expected - html

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; }
}
}

Related

TOP Navigation stays when page is scrolled [duplicate]

I want to create a sticky header bar for a website just like the sticky header on this website (http://www.fizzysoftware.com/) if any on can can help me out with coding or any resource that helps me to create the same. Your reply would be of great help to me.
In your CSS, add
position: fixed;
to your header element. It's just that simple, really.
And next time, try to use right click on something you see on website and choose "Inspect element". I think that every modern browser has it now. Very useful function.
If you want to make it sticky when it's scroll down to a certain point then you can use this function:
$window = $(window);
$window.scroll(function() {
$scroll_position = $window.scrollTop();
if ($scroll_position > 300) { // if body is scrolled down by 300 pixels
$('.your-header').addClass('sticky');
// to get rid of jerk
header_height = $('.your-header').innerHeight();
$('body').css('padding-top' , header_height);
} else {
$('body').css('padding-top' , '0');
$('.your-header').removeClass('sticky');
}
});
And sticky class:
.sticky {
position: fixed;
z-index: 9999;
width: 100%;
}
You can use this plugin and it has some useful options
jQuery Sticky Header
CSS already gives you the answer. Try this out
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
}
now add the class sticky to any menu sidebar or anything you want to stick to the top and it will automatically calculate the margin and stick to the top. Cheers.
If you want simplicity in a HTML and CSS option to create a Stiky NavBar you can use the following:
Just create a navbar like this one:
<nav class="zone blue sticky">
<ul class="main-nav">
<li>About</li>
<li>Products</li>
<li>Our Team</li>
<li class="push">Contact</li>
</ul>
</nav>
Remember to add the classes in this case I created a Zone (to separate my HTML in specific areas I want my CSS to be applied) blue (just a color for the nav) and sticky which is the one that gonna carry our sticky function. You can work on other attributes you want to add is up to you.
On the CSS add the following to create the sticky; first I am gonna start with the zone tag
.zone {
/*padding:30px 50px;*/
cursor:pointer;
color:#FFF;
font-size:2em;
border-radius:4px;
border:1px solid #bbb;
transition: all 0.3s linear;
}
now with the sticky tag
.sticky {
position: fixed;
top: 0;
width: 100%;
}
Position fixed meaning it will always be in the same position; and with top 0 I will always be at the top and a 100% width so it covers the whole screen.
And now the color to make our navbar blue
.blue {
background: #7abcff;
You can use this example to create a sticky navbar of yours and play around with the CSS properties to customize it to your liking.
Try This
Add this style to the corresponding
style="position: fixed; width: -webkit-fill-available"
OR
<style>
.className{
position: fixed;
width: -webkit-fill-available;
}
</style>

Table column width issue

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;
}

How can I bring a div above the current front-most (z-index: 0) div?

I'm building a gauge which uses pure CSS. It has a background to clip the remainder of the progress colour from showing. I want to add another div on top which gives a text indication of the progress: "10%".
It seems like no matter what I do, I end up with the background clip covering my text.
I've got an example of the problem here:
https://svelte.technology/repl?version=1.60.3&gist=77e1b55c23e229dee8d45b5648610593
An extremely cut down version of my code, demonstrating the problem is as follows:
<div class="gauge-wrap">
<div class="gauge-core">
<div class="gauge-bg" style="background-color: #fff;">
<div class="gauge-bg-value">10 %</div>
</div>
<div class="gauge-cap" style="background-color: #000;"></div>
</div>
</div>
<script>
.gauge-bg-value {
position: relative;
color: #f0f;
top: 7px;
z-index: 6;
}
.gauge-wrap {
position:relative;
margin:0 0 20px;
}
.gauge-bg {
position: absolute;
width: 200px;
height: 200px;
border-radius:100px;
z-index:0;
}
.gauge-cap {
position: absolute;
top:16px;
left:16px;
width: 168px;
height: 168px;
z-index:5;
}
</script>
It seems like z-index: 0 is still on top of my text div (.gauge-bg-value), even though I've given it a higher index.
Update - Solution:
In building my example, I moved the text into the .gauge-cap div and now it sits on top. Perhaps it was that div covering it all along. Happy to hear solutions that don't modify the structure of the html though.
This is to do with stacking context. In a case like this...
<div class='foo'>
<div class='bar'></div>
</div>
<div class='baz'></div>
...if foo and baz both create stacking contexts, and baz has a higher z-index than foo, then bar can never appear above baz no matter what. You'll have to break your markup apart into different layers instead (though in your example, I think you'd have an easier time using SVG instead of HTML).

Styling for CSS class not getting applied when class is added using Angular

I am trying to make a header that is localized under a div. When you scroll and the header reaches the top of the page it should "stay" there. I am using Angular so I found this solution: Bind class toggle to window scroll event here and I am using it for adding the class fix-header. In the inspector I can see that the class gets added but the styling does not apply when it is added. Here is my CSS for making the header fixed:
.wrapper {
background-color: pink;
height: 100px;
z-index: 1;
}
.wrapper .fix-header{
position: fixed;
top: 10px;
}
The "fix-search" class is added here:
<body ng-app="myApp">
<div ng-controller="MyController">
<div class="banner">
<div class="dummy-container"></div>
<div class="wrapper" change-class-on-scroll offset="200" scroll-
class="fix-header">
</div>
</div>
</div>
</body>
The line change-class-on-scroll offset="200" scroll-class="fix-header" adds the class fix-header to the wrapper div.
Here is some working code: https://codepen.io/Martin36/pen/jmbEgJ
So my question is, why doesn't the class properties get applied when the class is added?
Why don't the styles get applied when the class is added?
Because you are referencing the wrong class, your CSS target should be:
.wrapper.fix-header{
position: fixed;
top: 10px;
}
Note no space between the wrapper class and the fix-header class
I incorporated the comment given by #Ronnie and the answer from #cnorthfield and made an updated pen: https://codepen.io/Martin36/pen/jmbEgJ, for those of you that are interested. The header now sticks to the top of the screen when the "dummy" div is scrolled past. The following changes were made:
/* Since the classes are on the same element there should not be a blank between them */
.wrapper.fix-header{
background-color: pink;
height: 100px;
/* Without the "width" the header disappears */
width: 100%;
z-index: 1;
position: fixed;
top: 0;
left: 0;
}
To elaborate on cnorthfield's answer:
/*Apply style to all elements of both the wrapper class and the fix-header class*/
.wrapper .fix-header
{
}
/*Apply style to all elements which have both the wrapper and fix-header classes*/
.wrapper.fix-header
{
}
Notice how the addition/removal of a single space significantly changes the meaning of the selector.

How to place an html element outside of a newly generated one

Is it possible to place an Html element outside of a newly generated one?
Well, I have an IONIC2 app that generates a new element <scroll-content>, the issue is that this element has some CSS properties that affects the child elements.
So, what I would like to do it either to place that my div element outside of that <scroll-content> or even better to disable the CSS properties of <scroll-content> on the div
Here is the code, so I can make things clearer:
HTML
<ion-content id="contentPadding">
<div class="header">
</div>
</ion-content>
When Ionic renders the above code, the browser generate something like this:
HTML
<ion-content id="contentPadding">
<scroll-content>
<div class="header">
</div>
<scroll-content>
</ion-content>
CSS:
.top{
background:black;
}
//generated
scroll-content{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
display: block;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
will-change: scroll-position;
}
I guess, it's clearly shown that a new element called <scroll-content> is being created and <div class="header"> inherits all the css properties of <scroll-content> which I would like to avoid in my case.
Your header (child) is inheriting its parent's (scroll-content) CSS styling. You need to clear any unwanted inherited rules by explicitly changing the inherited styles. For example, if you want to reset the css-display, write
.header {
display: initial;
}
Hopefully in the future we can avoid this with the all:initial trick - however, it currently isn't supported enough.