Sticky header with scrollable content height does not fit inside card body - css

I am trying to make my table header fixed with rest of the table body scrollable in my react application.
This I have been able to achieve using the following css
// Parent Container
.Table-Container {
max-height: 60vh; //Making my table height unresponsive for some reason
min-height: 40vh;
max-width: 100vw;
position: relative;
overflow-y: scroll;
margin: 1rem;
}
// Styling and posiition for table header
.tableHeader .th {
position: sticky;
top: 0;
}
My layout is something like this.
Card is expanding because of the values assigned to table height to make it scrollable and header sticky
I don't want my wrapper content to scroll. The card height should not expand outside the remaining space
Ideally, I want header and footer fixed and the remaining space should be utilised by the breadcrumb, Filter buttons for the table(if any) and my table itself (again with fixed header) with the ability to auto expand/shrink based on the available space
I want the table height to fit inside the cardbody(parent div) automatically, but without assigning height, the scroll wouldn't work. It is only considering height in px or vh. Setting the height to auto also wouldn't work.
I want this to be responsive across different screen sizes.
Declaring a height in vh is also coming in the way of making it responsive.
Would appreciate any help or direction on this.
Thanks
I tried to set the height to my main-content like this
.main-content {
height: calc(100vh - #{$header-height} - #{$footer-height})
padding: calc(#{$header-height} + #{$grid-gutter-width})
calc(#{$grid-gutter-width} / 2) $footer-height
calc(#{$grid-gutter-width} / 2);
}
The card is still expanding outside the defined height of the parent.
I even tried using box-sizing: border-box but this wouldn't have any impacts either.
When I use this logic in a normal html + css this works perfectly,
However in react it is not behaving as expected.

Related

Scrollable dropdown div that ends at bottom of screen

In the following example, the div has the pre-defined height of: 300px.
The last city of the scrollable dropdown is Zimbawe and does not get displayed on an iPhone 6 screen for example.
I want to change the scrollable dropdown div in such a way to not specify the height and make the div end where the screen ends.
Any ideas ?
The library we use fro the dropdown is:
https://github.com/mukeshsoni/react-telephone-input
An you can see here the default height of the dropdown non dynamic:
https://github.com/mukeshsoni/react-telephone-input/blob/master/src/ReactTelephoneInput.js#L477
try this out, setting height depending upon the viewport(vh).
.div {
height: 100vh;
overflow: auto;
}
{height: 100vh;} matches the height of the viewport.
Try this:
CSS
div { // change selector
height: auto;
}
On mobile, such dropdown should appear as full overlay. Exactly like the select element options would appear on mobile.
Target mobile devices using #media and use position: fixed; with the respective positions and size (explore vh and vw units). Than use overflow-y: auto; to make your modal list scrollable.
try adding max height and overflow
.div {
max-height: 150px;
overflow: scroll;
}
you have to adjust the max-height according to screen size manually.

How to set div height depending on screen height minus the height of an absolutely positioned element?

I have a panel with a height of 100vh, so 100% of the screen (but height: 100% doesn't work, for some reason).
This panel must show a div with its own contents and the footer.
The footer is normally displayed under that panel, but in the front page it must be inside it, so I have to disable the normal one and call it inside the panel.
Thus, it must have position: absolute and bottom: 0.
Now the problem is that the footer takes its own height (which changes a bit when resizing the window's width), and the other div in the panel must take all the remaining height.
So, is there a way to set that div's height dynamically, rather than filling the CSS with media queries for each window width where the footer's height changes, setting it as height: calc(100vh - [footer height])?
Firstly, if you don't set height for parent elements, setting height in percentages on the child won't work. Your parent elements should have their height set to 100% (including html and body elements).
Secondly, if your browser support is IE10+, I recommend using flexboxes.
Here's how you do it (without browser prefixes):
.parent-container {
height: 100%;
display: flex;
flex-direction: column;
}
This will set the parent container as flexbox and change its direction to "column" (so its children stack one under the other).
.expanding-child {
height: 100%;
flex-basis: 0;
flex-shrink: 1;
flex-grow: 1;
}
This is the wrapper for your content. It will expand as much as it can, keeping in mind your footer's height.
.sticky-child {
flex-basis: auto;
flex-shrink: 0;
flex-grow: 0;
}
This is your footer that will now always be at the bottom, pinned, without overlapping the scrollable content.
Here is what your HTML would look like:
<div class="parent-container">
<div class="expanding-child">
</div>
<div class="sticky-child">
</div>
</div>
And I made a quick fiddle to demonstrate it here
This will work as intended only if you set height to 100% on all parent elements.
Edit: here is a good source to learn more about flexbox, I recommend looking into it. And here is one I used when I first started using flexbox.
I think you are asking about sticky footer. I hope it will helps you. Always footer fixed at bottom using FlexBox
Fiddle

100% height body is taller than 100vh, caused by Angular's router-outlet

I have an angular page, home, which is comprised of 2 components and a router-outlet
<div class="home-container">
<header></header>
<sub-header></sub-header>
<router-outlet></router-outlet>
</div>
I want the home-container above to always be, at a minimum, full screen height. The header should show, then the sub-header, then the contents of the router-outlet should always fill up at least the rest of the screen (or more if there's more content of course).
Normally this is easy but it seems the router-outlet is messing it up. Example can be seen http://plnkr.co/edit/56k9ZabLAGujBoX8Lsas , hit run and then click the "Heroes" link to route. In this example I don't want the Heroes div to be taller than the screen, and don't understand why it is.
My styles to accomplish this are. (assume router-outlet is on 'my-page')
html, body {
height: 100%;
}
.home-container {
height: 100%;
}
.my-page {
height: 100%;
}
My expectation here obviously is that home-container is full screen, shows header, shows sub-header, and that my-page then fills in at a minimum the rest of the vertical height.
What is actually happening though, is that there's a scroll bar with available height that appears equal to my header and sub-header.
This plnkr http://plnkr.co/edit/56k9ZabLAGujBoX8Lsas illustrates exactly my meaning. If you click Run and then the link for "Heroes" you will see the router-outlet contents, in this case heroes-list.component, with a green background. I do not understand why the green here is bleeding below the screen when everything is set to 100%
Update I have tried using all manner of different CSS attributes to different levels in this nesting. Including 100vh vs 100%, min-height vs height, and every combination of body/html/home-container/my-page. I have also tried the same with Angular's CSS :host, to the same result of no different
Update2 If I move it out of the element then everything behaves as you'd expect and there's no vertical scroll bar. Something about the router-outlet wrapper adds vertical space somewhere but I cannot figure out where or what is causing it.
Final Update The below answers might be useful for some applications but I ended up just solving it by giving the .my-page a specified height, just doing height: calc(100vh - $headerheight - $subheaderheight) which gets the job done
As far as I understand, 100% on a child will be equal to the size of the parents natural height. If you want to fill the space available, you really should be using flex unless you have a requirement to support IE9 and below.
I would update your Anchors to be contained in a div (or another wrapper)
<h1 class="title">Component Router</h1>
<div>
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
<a [routerLink]="['Heroes']">Heroes</a>
</div>
<router-outlet></router-outlet>
I would then utilize flexbox to allow the content to expand as required
.hero-list {
background-color: green;
height: 100%;
overflow:auto
}
undefined {
flex: 1;
}
body, html, my-app {
height: 100%;
}
my-app{
display: flex;
flex-flow: column;
}
Plunker to test: http://plnkr.co/edit/yE1KOZMr1pd5jQKlVYIN?p=preview
On chrome i still have scroll bars due to an 8px margin on body - this can easily be removed with CSS for a scroll free full height experience.
There are two causes that make your <body> element taller than 100% of the viewport:
Default margins of the <body> element that come from the browser's built-in styles and usually are 8px. This means that the <body> element will be as tall as the <html> element, but also will have 8px space above it and below it, causing the <html> element to overflow.
The top margin of the <h1> element "falls out" from the container due to margin collapsing. This makes the space above the <body> element equal to the default top margin of <h1> (about 21px instead of 8px).
Setting zero margin to <body> (part of ToTaTaRi's answer) helps you to solve the 1st issue. To solve the second one, you should make the <body> element or (probably better) the .my-app container establish the new Block Formatting Context. The easiest and most cross-browser way for this is setting the container overflow:hidden (other options are display:flow-root, which works for modern Chrome/Firefox, or column-count:1, which works in IE10+ and all modern browsers, you can compare nearly all the options in this live example).
First of all you should reset browser default styles at least somehow like this:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
Then you could achive what you want without a flex layout if prefered through splitting the page into a header section and main content section with a preset division... So lets say the heading and the links go together into a container div with i.e. a height of 20% and the main content which is at the moment hold in a tag "undefined" gets a height of 80%, if you now set the height of the app container to 100% or 100vh it should work as expected!
EDIT (because the topic is still open...):
Have you tried this css code like explained above, works like charm!?
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, my-app {
height: 100%;
height: 100vh;
}
h1 , h1 + div {
height: 10%;
height: 10vh;
}
undefined {
display: block;
background-color: green;
min-height: 80%;
min-height: 80vh;
}

Parent div of a position fixed img has no height / Can't apply overflow hidden if height > than viewport size

I'm trying to achieve the last piece of my general template for articles in a wordpress blog.
I've got an header/menu which is position: fixed.
Then I have a div .postThumbnail with a child img which is position: fixed so the following content can overlap the img when scrolling.
I also have a div that copy the img'height as the image is fixed.
Fact is, this could be a lot easier if .postThumbnail had an height, but it's value is equal to 0.
I do not know why.
What I intend to do is to set .postThumbnail's max-height equal to the height of the viewport minus the height of the header/menu, so if an image is taller than the viewport, it won't overflow and the following content which can be scrolled will appears right after the image (and not after the total height of the image).
Basically, I need to define .postThumbnail's height so I can apply an overflow:hidden.
Any idea?
I created a JSFiddle so you can actually see what I'm talking about.
Some of the current code :
#single\.php .postThumbnail img {
position: fixed;
z-index: 1;
width: 100%;
min-width: 640px;
height: auto;
}
#single\.php .postThumbnailGhost { /*keep as security even if no content is integrated*/
visibility: hidden;
}
What I need to achieve :
#single\.php .postThumbnail{
max-height: calc(100vh - 48px);
overflow: hidden;
}
With this fixed, I could fix the rest of the page as the content's min-height must be equal to the image's height in order to cover it properly.
Well,
I really simplified everything since I don't need a .postThumbnailGhost in this new version.
I also made it in Jquery as I couldn't do it fully in CSS ( :'( ).
Here is the script that is doing the job :
function refreshDynamicContent(){
$('.postThumbnail').height($('.wp-post-image').height());
$('.postThumbnail').css('max-height', $(window).height() - ($('header').height()));
$('#post').css('min-height', $('.postThumbnail').height());
}
refreshDynamicContent();
$(window).on("resize", refreshDynamicContent);
New JSFiddle
And I don't need an overflow anymore because I can set the height to the window's height!
YAY!

How to use an image placeholder while images load in a responsive grid?

Using a responsive fluid grid and images are 800px x 500px
Problem: When images load, the footer as it the top and is pushed down while the images are loading in.
Setup: Using a div for the images and div for the footer.
Goal: To have the footer always remain in the correct position, not trying to put it in an absolute spot, just looking to have the images spacing accounted for.
Ideas: Perhaps use a transparent png at 800x500 so it loads first before the images.
Concerns: Creating a div placeholder at 800x500 might not work as these images are responsive in a fluid grid so they'll never actually be at that size unless the viewer has a huge monitor..
Final result when images loaded:
Current issue:
Goal for images to load:
When I know the aspect ratio for something is going to stay the same no matter what the width of the elements/screen is, I do something like this:
.image-holder {
display: inline-block;
width: 33.333%;
position: relative;
}
.image-holder:before {
content:"";
display: block;
padding-top: 62.5%;
}
.image-holder img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Here's a full demo: http://jsfiddle.net/serv0m8o/1/
I wrap each image in a div with a class of image-holder (which is styled to give you the 3 per row pattern that you illustrated) and make sure it is position: relative;
I then style the :before pseudo-element of that div to be the proper height of the aspect ratio that is needed. Padding in CSS is an intrinsic property, which means it is based on the width of the element, allowing you to assign a percentage which reflects the ratio. You specified 800x500 images, so (500/800*100) = 62.5% as my padding-top
Then, you can absolutely position your image to fill the full width and height of the container (which is why we set it to be position: relative;)
Doing this means that the div element is the size that the image will be, whether the image is loaded into it or not (the image itself has no bearing on the container size, since it is absolutely positioned)

Resources