Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full height & width without scrollbar in Material UI React app

I am trying to render a page for full height. But it adds a scrollbar which is undesirable. With 100% height, I mean just the size of the screen.

Here is the demonstration. The yellow highlighted part is the unwanted height added. There is also a horizontal scrollbar(not highlighted):

enter image description here

Here is the render method of the page:

return (
    <>
        <Box display='flex' flex='1' justifyContent='space-around'>
            <IndexSelector
                id='index'
                value={symbol}
                onChange={this.onSymbolChange}/>
            <SeriesSelector
                id='series'
                seriesList={Form.seriesList}
                onChange={this.onSeriesChange}/>
            <DateRange fromDate={fromDate} toDate={toDate} onChange={this.onDateChange}/>
        </Box>

        <Box height='100%' border='1px solid red' marginTop='50px'>
            <Graph instructions={this.getInstructions()} apiData={this.apiData} />
        </Box>
    </>
)

Here is the index.css:

html {
  box-sizing: border-box;
}

html, body, #root {
  padding: 0px !important;;
  margin: 0px !important;;
  height: 100vh;
  width: 100vw;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
  monospace;
}

How to avoid this extra height & width and make the red border boxed container full height?

EDIT: As per @gowatham suggestion, I tried and it didn't work. I got the following result:

EDIT 2:

HTML: https://pastebin.com/Qu2RFHe7 CSS: https://pastebin.com/1z3Zg5rv

enter image description here

like image 458
conquester Avatar asked Aug 13 '19 09:08

conquester


2 Answers

If you set the main container to be 100vh, i.e. 100% of viewport height, and make it a display its children with a flex column direction, then you can just make the result container take all the remaining space by setting it to flex: 1 and make its content scroll by also setting overflow: auto

The benefit of this approach is that you can let the filter container be of any/dynamic height and it'll still work.

<Box height="100vh" display="flex" flexDirection="column">
  <Box>Filter</Box>
  <Box flex={1} overflow="auto">
    {Array.from(Array(100)).map((v, i) => (
      <div key={i}>Testing {i}</div>
    ))}
  </Box>
</Box>

https://codesandbox.io/s/material-demo-ntvoj

Another possible solution, that would probably work in ancient browsers as well, is to just set the filter container to position: fixed and then make sure that element that directly follows the filter container has either margin-top or padding-top that is enough to prevent it's content from appearing behind the filter div when the page is scrolled to the top.

<Box
  position="fixed"
  top={0}
  height="60px"
  width="100%"
>
  Filter
</Box>
<Box marginTop="60px">
  {Array.from(Array(100)).map((v, i) => (
    <div key={i}>Testing {i}</div>
  ))}
</Box>

https://codesandbox.io/s/material-demo-4m85i

like image 136
Markus-ipse Avatar answered Oct 11 '22 23:10

Markus-ipse


Don't give up! CSS styling can be tricky when you first started, but it is actually quite straight forward after you plan your page layout.

I would do 90vh for the body and set 10vh for the filter box that you have above, so it will always be only 100vh on the page, unless you wanted to change the layout. So I would have something like this:

return (
  <div style={{ height: '90vh', margin: 0, padding: 0 }}>
    <Box display='flex' flex='1' justifyContent='space-around' style={{ height: '10vh' }}>
        <IndexSelector
            id='index'
            value={symbol}
            onChange={this.onSymbolChange}/>
        <SeriesSelector
            id='series'
            seriesList={Form.seriesList}
            onChange={this.onSeriesChange}/>
        <DateRange fromDate={fromDate} toDate={toDate} onChange={this.onDateChange}/>
    </Box>

    <Box style={{ maxHeight: "100%", overflow: "auto" }}>
        <Graph instructions={this.getInstructions()} apiData={this.apiData} />
    </Box>
  </div>
)

Note that your border 1px might also increase the 100% and you might see a scrollbar. To force hide the scrollbar, just add overflow: hidden to the parent div. Example on CodeSandbox:

Edit Material demo

like image 16
Jee Mok Avatar answered Oct 12 '22 00:10

Jee Mok