Z-Index: Fixed element is behind relative element with lower z-index (and other weird behavior) - css

I have 4 elements, 3 of which are siblings on root level:
- Main: relative (sibling), Z-index 1
- Sidebar: fixed (sibling), Z-index 2
- Header: relative (sibling), Z-index 3
- Popup: fixed (child of Main), Z-index 4
What works:
- Header (relative, index 3) element is on top of the fixed Sidebar (fixed, index 2) as expected
- Main is below Sidebar and Header as expected
Problems:
- Popup (fixed, index 4) is rendered below the Sidebar (fixed, index 2) and below the Header (relative, index 3), but on top of Main (position of Popup is not affected by the Sidebar).
- the fixed Sidebar is not rendered in Mobile View, but relative Main is affected by its theoretical width of 3 rem.
Increasing the Z-index of Popup does not make it go on top of everything.
When I change Main to static in Mobile View, the theoretical width of the non-rendered Sidebar does not affect it. (Since the Sidebar is position: fixed I do not understand why it affects Main at all).
From my theme (I am using Styled Components)
index: {
main: 1,
sidebar: 2,
header: 3,
popup: 4,
}
This is the Layout Container which frames the entire page:
export const Layout = (props) => (
<>
<Sidebar />
<Header />
<Main>
{props.children} --> Popup is Child
</Main>
</>
)
I want Popup to be on top of everything and Main to be unaffected by the Sidebar.

Related

SCSS/Sass: Using a calculated variable from one scss class as the base for another

SHORT VERSION/CLARIFICATION
The gist of my question would be, assuming each value was unique to it’s context, would it possible to use undefined variables in sass, similarly to an algebraic function.
[formula for height of “.page-wrapper” div]
a * 0.75 = b
[formula for height of nested/child “sticky-vert” div]
b * 4 = c
a=the base value
b=the calculated value of the parent element
c=the calculated value of the child element
…and so and so forth
Most of the #mixins and #extend functions I’ve seen in sass have to do w/ overriding or replacing a display value like color or margin but not actually using calculations to get a new value from an "undefined" variable.
LONG VERSION
I have an SCSS document and I'm trying to take the numeric value from one class to use as the base for another class. Basically, I'm trying to take the height calculated from the parent class (".page-wrapper") to use as the base variable for it's child (".sticky-vert"). Is this possible to do, solely w/ sass and without javascript modifiers?
For what it's worth the website itself is set to horizontal scroll (except for the 1 section, explained below) and all the ".page-wrapper" element is set to display:flex along w/ its children. I want the child element to have four times the height as it's parent to accommodate for 4 diff content items within that section.
1. Here are the values set at the top of my scss doc:
/*Base Variables*/
$height: 100vh; // *the default value for height*
$width: 100vw; // *the default value for width*
2. These are the calculations for the parent container(s), using the $height value:
.header {height: $height * 0.14} // *header is 14vh, remains static / never scrolls*
.page-wrapper {height: $height * 0.75} // *page-wrapper is 75vh. This is a div container between the header and footer for the main content, this is the only area of the page that moves*
.footer {height: $height * 0.11} // *footer is 11vh, remains static / never scrolls*
Imagine it like a hamburger style webpage with only the middle moving.
3. This is the new value I want to calculate, without using JS modifiers or the actual numbers for flexibility:
.sticky-vert {height: height of ".page-wrapper" * 4} // Technically, the formula would be 75vh * 4 = 300vh but...
I don't want to plug the actual numbers in, in case I change the values later on down the line and have to plug in the new numbers again. Also while sticky-vert {height: $height * 0.75 * 4} could work it still requires plugging in the then-assumed value of the parent's height (75vh).
HTML SAMPLE:
<header class="colors-1">header text, etc etc</header>
<div class="page-wrapper dark">
<section class="sec-1">THE PAGE SCROLLS HORIZONTALLY</section>
<section class="sec-2">UP UNTIL YOU REACH THE NEXT SECTION</section>
<section class="sec-3 sticky-vert">
<div id="vert-1">WHICH THEN SCROLLS VERTICALLY, STARTING W/ THIS DIV</div>
<div id="vert-2">THEN IT SCROLLS DOWN TO THIS ONE.</div>
</section>
<section class="sec-4">NOW ITS BACK HORIZONTAL</section>
<section class="sec-5">AND FINISHES HERE.</section>
</div>
<footer class="colors-1">footer text, etc, etc</footer>
If I'm following correctly, you may not need to do all these calculations. Instead, would it be possible to add the height values for the header and footer regions, and have them set to position: fixed;, which would lock these elements in place which you could set with top: 0;, et.al. Then the page wrapper (for the moving content) could have margins or padding set (depending on how the main content moves around) to offset from the header and footer regions. This method could avoid a number of calculations, allowing freedom for focusing on the other areas.

Drawer rendering inside AppBar element

I created a container to limit my app to 600px(sm) width, but when I did it the drawer breaks. Instead of rendering in the container page side, it is inside the appBar.
When the width is more than 600px (the page limit), the drawer is rendering inside the appBar (picture incorrect). When the page is smaller than 600px it renders correct (picture correct).
I am using material-ui components, the app bar is position as absolute, because I am implementing on scroll events. To centralize the app bar I use:
maxWidth: 600,
[theme.breakpoints.up("sm")]: {
left: "50%",
transform: "translate(-50%, 0)"
}
Here is codesandbox example code:
https://codesandbox.io/s/material-drawer-e6vrc?file=/header.js
You should make drawer sibling with AppBar instead of it's children
return (
<div className={classes.grow}>
<AppBar className={classes.app_bar}>
...
</AppBar>
{renderDrawer}
</div>
);

How to use position fixed on elements inside smooth scrollbar plugin's 'data-scrollbar' attribute

I am trying to create a fixed nav menu inside the smooth scrollbar plugin 'data-scrollbar' attribute https://idiotwu.github.io/smooth-scrollbar/
Position fixed does not work
Below is an example of my HTML structure - Note that if I move the nav outside of .scroll position fixed works but I cannot scroll content if cursor positioned over nav
I'm trying to understand why this is happening and if there is a solution?
<div class="scroll" data-scrollbar>
<nav></nav>
<!-- scroll content -->
</div><!-- End of Scroll Class -->
This is a bit late, but hopefully this helps.
You need to add a scroll listener, and apply offsets to the fixed element.
HTML
<div class="scroll" data-scrollbar>
<nav class='fixed-nav'></nav>
<!-- scroll content -->
</div>
Javascript
const fixedElem = document.getElementsByClassName('fixed-nav')[0]
const scrollbar = Scrollbar.init(
document.getElementsByClassName('scroll')[0]
)
scrollbar.addListener( status => {
const offset = status.offset
fixedElem.style.top = offset.y + 'px'
})

Get div to adjust height with header content

I have a side bar that contains two divs. The first div may or may not have content, depending on what else is done on the page. The second div contains a long list of things and has a limited height, so scrolling is possible. I want to have the sidebar be as tall as the page, and I want the list container in the sidebar to be as tall as the sidebar minus the height of the header (which will change while using the page). I don't care about limiting the size of the header. The biggest is will get isn't anything significant.
Right now I'm just setting the height of the list container to be some number that is won't go over a maximized window height if the header div as as much content as it can, but this leaves an empty space at the bottom when the header is empty, and still doesn't work very well if the window is resized.
The layout is similar to this.
Is there a css solution to what I'm looking for, or will I have to use javascript and get window height/set div heights in pixels? I'm fine with either, it just seemed like there should be a CSS way to accomplish it.
If you're not opposed to using a little jQuery, here's a little code snippet that should help you equalize the height of the two divs, no matter which has more content. You can change it to your liking too.
var leftHeight = $(".left").height();
var rightHeight = $(".right").height();
var maxHeight = 0;
var div = "";
if (leftHeight >= rightHeight)
{
maxHeight = leftHeight;
div = ".right";
}
else
{
maxHeight = rightHeight;
div = ".left";
}
$(div).each(function(){
if ($(this).height() > maxHeight) { maxHeight = $(this).height(); }
});
$(div).height(maxHeight);
and credit where credit is due, this is an edit of a code snipped found at css-tricks.com
is this what you want?
http://jsfiddle.net/YWNyr/
CSS tips:
If you use 'absolute' positioning, width,height,left,top, etc... is relative to the first ancestor that has a "position" property other than "static", or the body if nothing is there.
for static menus, it is common to use 'position:fixed' as it will simplify scrolling issues
When using jquery its easier(and faster) to toggle a class than to change the DOM since that requires redrawing of the elements by the browser
-edit: for refreshing the sidebar size some javascript is necessary:
$('#headerAdd , #headerRemove').click( function()
{$('#sideContainer').height($(window).height()-$("#header").height());
} );
Try setting the height of your list container to 100%, and your overflow to scroll:
#listContainer {
height: 100%;
overflow: scroll;
}
This will keep the list in a scrollpane that reaches to the bottom of the page, no matter how large the header grows or shrinks.

page size as screen size and scrollable frame inside

Here's the scenario:
I have an asp.net webpage which displays dynamic data in a gridview.
I'm using a master page to display the header and footer of the page, and this gridview is being displayed inside a div in the contentplaceholder.
The Problem:
What I want is that the size of the page that is displayed remains constant for a user and must be equal to the size of their browser's available display area and the content being visible by scrolling the div.
Sort of like the header and footer remain at the same position and the content inside it is scrollable.
I really don't know how to achieve this.
Any help on the matter is highly appreciated.
Thanks.
Try some jQuery:
function changeHeight(){
var winHeight = $(window).height();
var heightOfHeaderAndFooter = 200px; // change this to what you need
$('#myDiv').height($(window).height() - heightOfHeaderAndFooter);
}
$(window).resize(function() { // changes height with browser window
changeHeight();
});
$(document).ready(function() { // changes height on load of the page
changeHeight();
});
What you want is for your div to use width:auto and to dynamically change the height of it to always keep the footer at the bottom of the page. Also, make sure your div has overflow-y:scroll
Code snippet:
divMain.style.height --> height of div in pixel containing GridView. This div tag also has style setting of style="overflow-y:auto;"
document.documentElement.clientHeight --> height of the working/client area for your display.
document.getElementById("divMain").offsetTop --> height of content prior to divMain.
25 --> this is the height of my additional footer.
The pixel result is the height available for your divMain.
divMain.style.height = (document.documentElement.clientHeight - document.getElementById("divMain").offsetTop - 25) + "px";
Hope this helps.

Resources