How to nest *position: sticky* inside of mat-expansion-panel => css grid - css

Inside of an accordion, I have a grid with 2 columns (really more but for simplicity here) both of variable length (dynamic form creator). In the left column I have some buttons I want to stay on the screen when scrolling down the right column. Is css grid or expansion panels contradicted with sticky? I tried to find overflow being hidden as I read you couldn't do that, but I did not find that. Do you see what I'm missing and why my sticky doesn't stay?
.html
...
<mat-expansion-panel>
<mat-expansion-panel-header>
Header
</mat-expansion-panel-header>
<div class="grid">
<div id="left">
<div class=sticky>
stay on screen
</div>
</div>
<div id="right">
some other really long content
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
...
.css
.sticky {
position: sticky;
top:0;
}
.grid {
display: grid;
grid-template-columns: 2fr 8fr;
}

I ran into a situation where I needed the expanded mat-expansion-panel-header to stick to the top of the page as you scrolled.
#Mateusz Budzisz's answer talked about using overflow: inherit !important on the .mat-expansion-panel, but this would leave the page with a ton of empty space and scrollbars resulting from the overflowed (but height: 0'd) expansion panel body.
I solved this issue by adding this rule:
.mat-expansion-panel {
overflow: inherit !important;
}
.mat-expansion-panel-body {
overflow: hidden; // This rule fixes extra whitespace
}
.mat-expansion-panel-header.mat-expanded {
position: sticky;
top: 0;
z-index: 1000;
}
Now all expanded panel headers stick to the top of the page as they should and there is no empty space when the panels are closed.
I originally tried adding the overflow: hidden; rule to just the .mat-expansion-panel-content, but this made the expand/close animations of the panel behave weird.

<mat-expansion-panel> has overflow: hidden; You can fix position sticky by removing it, like this:
.mat-expansion-panel {
overflow: inherit !important;
}
But it will result in empty space after panel if any panel is collapsed. More about this css issue: https://github.com/w3c/csswg-drafts/issues/865

Related

Sticky element inside flexbox (not in combination with)

Many similar questions have been posted to try and achieve position sticky with an element that has flex rules applied (e.g. this post is one of many that I tried the answers from), but my aim is to apply position:sticky to a child of a flex element.
I have a two-column layout with a menu on the left. The idea is that when the page is scrolled down, the blue-colored menu stays at the top (although the image above should scroll upwards, leaving just the menu visible in it's place).
However, no matter of which combinations of align-self I apply, the menu still disappears vertically upwards with the image.
If its possible to combine flex with sticky, then I'm hoping there's also a solution for the child element.
Fiddle here using SCSS
.PageContainer {
.OuterContainer {
display: flex;
flex-wrap: nowrap;
gap: 1em;
.SideOne {
background-color:#fee;
align-self: flex-start /* Solution from https://stackoverflow.com/questions/44446671 */;
width: 10em;
.CompanyLogo {
img {
width: 100%;
}
}
.MyStickMenu {
border:1px solid blue;
background-color:#eef;
position: sticky;
top: 0;
}
}
.SideTwo {
background-color:#ddd;
flex-grow: 1;
flex-shrink: 1;
}
}
}
<div class="PageContainer">
<div class="OuterContainer">
<div class="SideOne">
<div class="CompanyLogo">
<img src="https://via.placeholder.com/250x100.png" alt="" />
</div>
<div class="MyStickMenu">
<h2>
Not-so Sticky Menu
</h2>
<ul>
<li>
Home
</li>
<li>
Away
</li>
</ul>
</div>
</div>
<div class="SideTwo">
<h1>
Scrollable page
</h1>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
</div>
</div>
Your issue is not with the sticky property but with the expectations you have of it. A sticky element is only sticky within its parent and so the Side One's height limits how far the menu can go.
You're going to have to put the Menu as a sibling to the "sides".
Alternatively you could divide Side One into two separate sides one for the menu and one for the rest, applying the position: sticky to the new side as it is the one who is supposed to cover its siblings while scrolling.

How to ensure containing element is full page height, no matter the number of dynamic children

I am trying to get a containing div that is full page-height to expand so that is is always equal to the height of its content.
The overall structure is
search.html
<div class="outer-container">
<div class="inner-container">
<div class="body">
<app-results></app-results>
</div>
</div>
</div>
results.html
<div class="card" *ngFor="let c of content; let index = index">
<h1 class="h">{{index}}</h1>
</div>
I have tried setting the .outer-container to [display: inline-flex][1]; which works really well. Until more cards are added dynamically to the view. At that point, the containing element remains at the same place it was before the dynamic content was inserted, right at the viewport's previous bottom.
I've also tried various permutations of height: auto, and height: 100% on the entire tree of elements, but it seems like when I get the parent's height to work correctly with a batch of children that extends beyond the page, its height shrinks when it is one element; and when it looks good when there is just one element, the parent looks to short when more children are added which overflow the page height.
Also, in my app overflow: auto produces a double scrollbar, so that won't work.
How can I get the full height to persist no matter the number of elements?
More detailed StackBlitz You have to click the "search" link to get to the correct route. (I added angular router to be sure my reproduction was accurate as possible)
I looked at your StackBlitz. I assume that the issue is that when you click 'toggle' the pink background does not extend. If so, all you need to do is add overflow: auto; to your CSS as shown below. I tried it on your StackBlitz and it worked.
.outer-container {
width: 100%;
position: relative;
height: 100%;
display: inline-flex;
flex-direction: column;
background: pink;
overflow: auto;
.inner-container {
height: inherit;
}
}
The overflow property specifies what should happen if content overflows an element's box.
I changed a couple lines on your stackblitz and it seems to be working how you described. You can make the .outer-container height fit-content and min-height 100%:
.outer-container {
width: 100%;
position: relative;
height: fit-content;
min-height: 100%;
display: inline-flex;
flex-direction: column;
background: pink;
.inner-container {
height: inherit;
}
}

UI-Router: Height:100% on body element ignoring nested view height

I'm building an angular application that frequently uses nested views. Certain views, however, are taller than the other elements on the page and end up extending well beyond the end of the parent view.
I'm using Ryan Fait's Sticky Footer so I have a wrapper around a containing div set to height:100% and I would have expected the page to just adapt and move the footer to the bottom of the nested view however I'm seeing the style elements of the footer border and background-color are remaining at end of the parent div while the content of the footer is being pushed to the end of the nested div.
Including an image as I'm struggling with getting the language exact:
I'm really looking for any solution from fixing the css to something that seems hackier like changing the footer or using ng-if/ng-class on certain pages. I'm imagining I'm misunderstanding something about CSS/UI-Router but I can't really track it.
The code isn't really interesting but here is it?
CODE
.wrapper {
min-height: 100%;
margin-bottom: -50px;
}
.push {
height: 50px;
}
.footer {
display: block;
height: 50px;
}
.nested {
max-height: 500px;
}
<body>
<div class="wrapper">
<div>
<h1>Some text</h1>
<ui-view class="nested"></ui-view>
</div>
<div class="push"></div>
</div>
<footer class="footer">
<span>some copy</span>
</footer>
</body>
If you use percentage values for height (i.e. a relative height), the parent element heights have to be defined too. In your case you also need height: 100% on body and html, like
html, body {
height: 100%;
}

expand web page through left- right instead of up-down

I aling divs in through right
{ float: right;}
but end of the page it (when divs become more than 4) the fifth div goes under other divs while page expands to down. I dont want this. I want height of the page become fixed and web page expand left to right always how can i do this.
Use min-width and display:table-cell example in fiddler : http://jsfiddle.net/HarishBoke/c8G7V/
On the top level parent element (presumably a 'body' tag) set the overflow-x property, in CSS, to scroll.
Something along the lines of:
body{
overflow-x: scroll;
}
Note that this possible solution may not be pre-IE8 friendly. As far as keeping the page's height fixed, define the height in CSS and set the overflow-y to be hidden. This will hide any elements exceding the parent element's height, rather than stretching the content.
You need a extra div with large width which contains other div's. This will not allow your body container to add new line when running out of space.
HTML:
<div id="container" class="clearfix">
<div id="wrapper" class="clearfix">
<div id="div1">Div1</div>
<div id="div2">Div2</div>
<div id="div3">Div3</div>
<div id="div4">Div4</div>
</div>
</div>
CSS:
#container {
height: 275px;
overflow-x: auto;
overflow-y: hidden;
max-height: 275px;
}
#wrapper div {
float: right;
border:1px solid black;
width:200px;
height:100px;
display:inline-block;
}
.clearfix:after {
content: " "; /* Older browser do not support empty content */
visibility: hidden;
display: block;
height: 0;
clear: both;
}
To make it more dynamic,you can first calculate the space taken by inner div and then some ettra space on the wrapper div accordingly
Javascript:
var width=0;
$('#wrapper>div').each(function() {
width =width+parseInt($(this).css('width'));
});
wrapperWidth=width+100;
$('#wrapper').css('width',wrapperWidth);
Updated Fiddle: http://jsfiddle.net/ankur1990/mgxk5/3/

Chrome: overflow:auto + margin:auto fails to layout correctly sometimes

I'm trying to layout a page which has anchor elements that I would like on a new line and centered. However these blocks are inside of <p> elements which are beside floating images.
Right:
http://test.sunnysidemarket.ca/right.jpg
Wrong:
http://test.sunnysidemarket.ca/wrong.jpg
So basically I have:
HTML:
<div class="content">
<div>
<img src="..." width="276" height="207" />
</div>
<div class="body">
<p>
...
<a class="mediaset" href="...">Link</a>
</p>
</div>
</div>
CSS:
.content img {
float: right;
}
a.mediaset {
margin: 0 auto;
width: 220px;
display: block;
overflow: auto;
}
Or what you can see in the jsfiddle: http://jsfiddle.net/CVkFw/
The issue is intermittent, sometimes it happens, sometimes it doesn't. What it appears to me to be is a bug in chrome where the overflow and margin properties are calculated but when the floating content loads, sometimes the browser doesn't layout the elements again.
There are ways of solving this using jQuery and modifying my HTML but I would really love to solve this with CSS if at all possible.
My best guess is that this erratic behavior is caused by overflow: visible applied in global.styles.css. The problem:
.node-article .field-name-body,
.node-synced-facebook-content .field-name-body {
overflow: visible;
}
I'm offering this suggestion because when I add this CSS override for overflow: hidden, that component appears to load "more solidly". The fix:
.node-article .field-name-body,
.node-synced-facebook-content .field-name-body {
overflow: hidden;
}
The selector itself might need to be adjusted depending on what it is intended to affect. (I'm obviously not that familiar your page's css code.) Hopefully this points you in the right direction though!

Resources