Make elements same height with Angular Material + Flex - css

I have an app I'm building that has a basic layout with a page header, a sidebar, and a main content area. I'm using Angular Material (1.0.5) with Angular.js (1.5.0). I'm using Angular Material's flexbox layout directives for my application's layout.
My problem is that I'm using flex to extend the sidebar to the bottom of the page, but when I scroll on a page with many ng-repeated items, it stays the height of the window. I would like it to extend all the way to the bottom of the page itself, as far as the repeated items goes. I've tried several different ways using Angular Material's flex directives, however this is the best I've been able to do thus far. One option I could do that I'd like to avoid is to calculate the height it needs to be using JavaScript in a $timeout, but like I said, that would be my last choice. Another option I know is available is to make the content area scrollable so that the header and sidebar are always fixed there. I would do that, but the client dislikes that and said no. (hence, not an option)
I've put together a CodePen to reproduce the issue I'm having. This has got my layout pretty much identical to what my app has got for its layout at the moment.

Firs create a wrapper class and insert all the content inside the wrapper
.wrapper {
width: 100%;
height: 100%;
overflow-y: auto;
}
<body ng-app="my-app" layout="column">
<div class="wrapper" layout="column">
ADD ALL YOUR CONTENT HERE
</div>
</body>
And for your rows / header not to shrink, add flex-shrink: 0 to them
.header,
.row-item {
flex-shrink: 0;
}
Result:
http://codepen.io/retamalph/pen/GZYZJo?editors=1100

Related

How to make dynamic height with Angular Material and responsive sidebar?

I followed this guide to create a responsive sidebar menu with Angular Material. Now I'm trying to make the content part of the screen render correctly with dynamic data. The content looks fine when rendering a static page. For example, here's the welcome page:
However, when I have a list screen with dynamic data, I can't scroll up to see the entire list. The list goes above the content section and overflows below it too.
I can fix this by changing the .content class from using height: calc(100vh - 98px) to height: auto, but then it causes regular screens to look funny because the content part doesn't flow to the bottom.
The screen with the list looks a lot better though and you can scroll to see all its contents.
Is it possible to 1) make it so the height is dynamic and stretches to the bottom while allowing scroll-ability? Also, how do I make the static content render at the top instead of the vertical center?
You can see this issue in action by cloning this repo and running its Angular Material example:
git clone -b styles-support https://github.com/manfredsteyer/angular-crud.git
cd demo-material
npm install
npm start
You can set a minimum height of the content div like this
min-height: calc(100vh - 98px);
height:auto;
This way and height to auto so it will expand and look proper
You can fixed this by adding min-height: 100% in your .content class

Make Full Page Scrollbars Control Table with Sticky Headers (CSS Only)

The following sandbox shows code that works perfectly well for a Material UI Table placed within a Paper component with a sticky header: https://codesandbox.io/s/2n40y
I would like the scrollbars (horizontal and vertical) to appear at the edges of the browser page, bottom and right respectively, yet still control the scrolling of the Table itself.
Currently I am only able to do this when removing the table from the Paper and making it a child of the page directly -- or a child of a main div that would span the full page height. Yet I need the Paper component to remain there, where other components will be placed above and below it.
Any ideas on how to achieve this?
UPDATE: in the attached sketch, the browser border appears in black and the scrollbars where they should ideally be appear in green. There is a container div in the middle of the page that contains the table in red. The table's headers should be sticky and the table shouldn't appear beyond the container div which acts as an aesthetic wrapper around it. Ideally, the browser vertical scrollbar would scroll the whole page down while leaving the page header (title + subtitle) and the table headers sticky. Also, when horizontally scrolling, the table should scroll within the container div. This is why I marked the parts that should not ideally appear in dashed lines.
All the changes we need to make are on demo.js
Firstly, we need to use a custom MUI TableContainer as the containerComponent for your #devexpress/dx-react-grid-material-ui Table. Basically, the purpose of this is so we can remove the overflow properties of the Table so that the scrolling is primarily for the body to address the requirement of
the scrollbars (horizontal and vertical) to appear at the edges of the
browser page, bottom and right respectively
import TableContainer from "#material-ui/core/TableContainer";
import makeStyles from "#material-ui/core/styles/makeStyles";
const useStyles = makeStyles({
tableContainer: {
overflow: "initial"
}
});
const MUITableContainer = ({ children, ...rest }) => {
const classes = useStyles();
return (
<TableContainer classes={{ root: classes.tableContainer }} {...rest}>
{children}
</TableContainer>
);
};
Secondly, at your MUITableContainer, get rid of the height: 400px so that the table's height will respond to the content. Again, the browser body bottom & right scrollbars will now control the document's scroll positions - this includes the table. Take a look at the Table containerComponent prop as well - we have assigned the custom TableContainer we created earlier.
<Paper>
<Grid rows={rows} columns={columns} rootComponent={GridRoot}>
<Table
containerComponent={MUITableContainer}
tableComponent={StickyTable}
/>
...
Lastly, to test this requirement:
there will be other objects before and after it.
Just render sample components before & after the Paper component
I cannot see the design spec you have referenced, but going off the sample in the comment on the first answer, I think you are trying to keep the header and footer from going off the left edge of the viewport when the user scrolls. But using just CSS, no JavaScript.
I took the entirety of the HTML (only the HTML) from your original code at https://codesandbox.io/s/2n40y (specifically <div id="root">) and dropped that into a Codepen.
Then I added a few visual design styles from your example so it looks kinda close.
Then I added the following CSS to make the column headers sticky:
th {
position: -webkit-sticky;
position: sticky;
top: 0;
}
I dropped in the following HTML as the first child and last child of <div id="root">, though it really doesn't matter where they live as long as they are not in the table.
<div class="stuckHeaderFooter">
[...]
</div>
To keep those from scrolling off screen when I scroll to the right, I made them sticky to the left (for RTL content you would need to make it sticky to the right):
.stuckHeaderFooter {
position: -webkit-sticky;
position: sticky;
left: 0;
padding: 0 1em;
display: inline-block;
}
The padding just makes it look less ugly. The inline-block is there to keep the block-level elements from filling the entire document width, which would keep them from being properly sticky since they would be wider than the viewport. You will probably have to set a max-width using vw units, but without knowing your content, target sizes, etc., I cannot say what would be best.
Finally, you have to remove the inline height: 400px on the first <div> under the root (<div class="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded" style="height: 400px;">). If you cannot override it because something injects it, then this style will override it for you but it brittle without knowing what else may be going on:
#root > div {
height: auto !important;
}
CSS only, no JavaScript in this approach at all, which is what I think you wanted.
Pen: https://codepen.io/aardrian/pen/PoNMopM
Debug view: https://cdpn.io/aardrian/debug/PoNMopM
Update: 5 October 2020: Looking at the sketch provided with the question, it is important to note that the container that does the clipping is the one that gets the scrollbar. So your options for a CSS-only solution are limited:
Add a fake block to make a visible border on the right (I updated the pen to add one; look at #root::after for an example but you will still need JS to make sure that does not appear until the table starts to get covered).
Yeah, I ran out of ideas.
In conclusion, I don't believe there is a CSS-only solution here because of how clipped areas work.
You can achieve this by setting the height and width to be equal to the viewport:
<Paper style={{ height: "100vh", width: "100vw" }}>
Example modified: https://codesandbox.io/s/table-sticky-header-forked-l77is?file=/demo.js

What does it mean to "apply a global class name"?

I'm trying to build my interface using Material-UI (current version is 3.1.2.)
A while ago when I was using Bootstrap4, I added style="overflow-y: scroll; height: 100%" to my head tag to always show a scrollbar to stop the app from jumping around when the page content grew longer than the screen.
Now that I'm trying to use Material-UI, the overflow setting seems to cause problems when combined with Material-UI's popup components (popper, menu, etc.)
I read in the FAQ that this is a known issue with a workaround: https://material-ui.com/getting-started/faq/#why-do-the-fixed-positioned-elements-move-when-a-modal-is-opened-
But I'm not sure what that's telling me to do.
What is implied by the phrase "apply a global class" in the following?
"apply a global .mui-fixed class name ... to handle those elements."
Where do they intend that mui-fixed would be added - to every component in my app? To the anchor of the menu/popper? Or do they mean that I'm supposed to apply it "globally" (ie. high up in the React page component hierarchy somehwere?)
In the meantime, as a workaround, I've just removed the overflow styling from my html element.
The app content still jumps about when the content grows/shrinks across page size, but it seems less ugly than when I was using Bootstrap.
I tried adding the mui-fixed class to my body, so when the app starts, it looks like:
<body style="overflow-y: scroll; height: 100%" class="mui-fixed">
So when the page is short, there is a disabled scrollbar. If the page grows, the scrollbar becomes enabled.
Then, while the menu popup is displayed, Material-UI changes it to this:
<body style="overflow: hidden; height: 100%; padding-right: 17px;" class="mui-fixed">
Which looks fine, regardless of the content's length. But then when the menu is dismissed, Material-UI changes the body element to:
<body style="height: 100%; padding-right: 0px;" class="mui-fixed">
The overflow style is gone and this results in the scrollbar being removed entirely if the page content is shorter than the window - so the page content "jumps" across to fill the space from the missing scrollbar.
This is for scrollbar if I got it correct, then it would be apply "globally" one time.
in your styles.ts you can add:
'#global': {
'.mui-fixed': {
// something here
},
},
and it will apply globally!

Make last of stacked div's inside header/footer 100% height of the rest

Currently trying to find a clean solution for achieving the following layout for a sidebar like this
Header
Section 1 that updates it's (dynamic) height aligned to the content
Section 2 that takes the rest of the height with content that needs to scroll if it doesn't fit anymore
Footer
How to make Section 2 taking the remaining space between Section 1 and the footer as nothing I tried makes it happen?
#data_section {
/*Section 2*/
position: relative;
background: red;
/* This needs to be 100% of the 'reset' excluding the footer */
/*height: 100%;*/
/* he content needs to scroll if it outgrows the height */
/*overflow-y: scroll;*/
}
Is there a CSS only solution for this kind of layout that works on >= IE9 and current FF, Chrome, Safari versions?
As it is part of a JavaScript centric application nothing speaks against using JS to calculate the dimensions. But as I always have a hard time when it comes to CSS and it's capabilities it would be nice to see if there's a "clean way" in doing by CSS only.
Here's a fiddle with the barebones layout without getting Section 2 to do what it should.
I would suggest using display:table; and display: table-row. The nifty thing with these display types is that the rows will both try to fill the entire table as well as fitting the content inside. Because of this, you can set height: 0; to the rows that you want to merely fit the content, and let section 2 just fill the rest.
Here's a fiddle
Assuming that you have no content as per you Fiddle, my suggestion would be to add :padding-bottom : 90%; // adjust the value to your need to your css in #data_section, as this will mark up the color in entire remaining area without affecting the footer!

How to get a CSS Layout like at elkaniho.com/

This website http://www.elkaniho.com/ has a CSS layout which is what i want, you see, the divs stack on top of each other, not on a precise grid, but just at the bottom and on the side.
And when you re-size the browser, they all re-adjust perfectly?
anyone know how i can get the same layout like at elkaniho.com or what type of layout this is called?
There is also a neat jQuery plugin called Masonry that can deal with div's of varying width and stacks them up as tightly as possible. Depends on your content.
That's just a six column layout. Easily done with 6 divs:
<div id="container">
<div class="column">one</div>
...
<div class="column">six</div>
</div>
As a fluid layout:
#container { overflow: auto; }
div.column { width: 16%; float: left; }
You can of course fix the widths too.
Each column then has several divs which do what divs (and in fact any block element) do: they stack top to bottom.
The effect you are speaking of is created using javascript. If you look at the source code, you will find a link to a javascript file called funciones.js which includes functions called cajas and cajasInterior that are responsible for this effect. Also note that they are using jQuery.
The functions:
Figures out the maximum number of columns based on the body width, box width and margin
Sets all divs with a class of box and boxInterior to have absolute positions and set their width
Goes through each box and calculate the left and top positions.
I would contact the webmaster of the site and ask permission to use this script and change it to fit your needs.

Resources