24

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

conquester
  • 1,082
  • 2
  • 21
  • 44
  • 2
    don't use 100%, use 100vh. 100vh is the full height of the browser window. – cloned Aug 13 '19 at 09:23
  • 2
    @cloned one thing to note when using `100vh` is if you have a horizontal scrollbar `100vh` will give you a vertical scrollbar too, `100%` won't – Pete Aug 13 '19 at 09:27
  • @conquester please can you make a [mcve] with your rendered code and css so we can see what the problem is – Pete Aug 13 '19 at 09:27
  • I changed 100% to 100vh in the Box props but still the scrollbars are there. – conquester Aug 13 '19 at 09:29
  • Most likely because you have a 2 boxes on top of each other and one of them is the height of the screen so the window will scroll the amount of the first box height – Pete Aug 13 '19 at 09:30
  • Why are you adding `height='100%' border='1px solid red' marginTop='50px'` to your second `Box` element? I think you should remove the `height` – ravibagul91 Aug 13 '19 at 09:44
  • When I remove the height prop from the second box then the box(the red border one) is rendered only in half the page, leaving rest of the space empty. – conquester Aug 13 '19 at 09:49
  • I think I found an answer related to your problem here https://stackoverflow.com/a/24979148/2250742 as you already use flex. – trebor Aug 13 '19 at 09:54
  • post the output HTML and CSS in a html file. – Martin Chaov Aug 15 '19 at 13:07
  • Updated the question with code details – conquester Aug 15 '19 at 18:25
  • Do you want it to be responsive ? or is it enough for the desktop site alone ? – strek Aug 18 '19 at 06:20
  • I would like it to be responsive. – conquester Aug 18 '19 at 10:04
  • It would be easier to test if you could add working sandbox instead of raw css/html. Can you do that? Thanks. – CodeMeNatalie Aug 19 '19 at 10:18
  • @conquester you have already predefined almost every height as more than 1000 px and how do you expect it to be responsive ? – strek Aug 19 '19 at 16:08
  • I didn't understood where I have done so. Is setting 100vh, 100vw defines pixels? @XxSTREKxX – conquester Aug 19 '19 at 16:22

6 Answers6

34

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

Markus-ipse
  • 7,196
  • 4
  • 29
  • 34
  • 1
    Your solution works also for what I could imagine a typical usecase of a Material UI react application with a taskbar along the top and then the content rendered below and scrolling including the scroll bars strictly applied only to the content area below the taskbar. With your solution, the bottom horizontal scrollbar always stays within view when needed. Thank you very much! – TheDiveO Oct 06 '20 at 07:51
  • +1 Best solution I've seen so far. It's dynamic so it doesn't rely on sizes of headers, footers, etc. This should be accepted answer – G M Jun 26 '22 at 19:16
17

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

Jee Mok
  • 6,157
  • 8
  • 47
  • 80
3

Try subtracting box1 height from box2 height create a ref to box1:

ref={(ref) => this.box1 = ref}

Then in box2:

height={`calc(100% - ${this.box1.clientHeight}px)`}

Like this:

return (
    <>
        <Box display='flex' flex='1' justifyContent='space-around' ref={(ref) => this.box1 = ref}>
            <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={`calc(100% - ${this.box1.clientHeight}px)`} border='1px solid red' marginTop='50px'>
            <Graph instructions={this.getInstructions()} apiData={this.apiData} />
        </Box>
    </>
)
Akram Badah
  • 417
  • 3
  • 12
2

Try to include Flex for the Parent also

<div display='flex' flex='1' height='100%' justifyContent='space-between'> //use flex direction column as per your library     
        <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>
            <Graph instructions={this.getInstructions()} apiData={this.apiData} />
        </Box>
    </div>
gowtham
  • 56
  • 3
  • I have updated the question with the result I got. It didn't work :-( – conquester Aug 13 '19 at 12:16
  • Use 100vh in parent instead of 100%. 100% take upto max of height of all content. That won't enllarge after that. 100vh is used for vertical height of whole window. Please try that – gowtham Aug 13 '19 at 12:22
  • Tried that. It still did not work. I have almost given up on solving this issue. – conquester Aug 13 '19 at 12:32
2

css Use height: '100vh'in parent instead of 100%. 100% take upto max of height of all content. That won't enllarge after that. 100vh is used for vertical height of whole window and also check the overflow-y

0

I made the navigation division height:15vh the division following it with height:20vh and the last division with height:65vh adding it to 100 vh ie total device height you can change it as per your wish and alter the height of the divisions. The scroll doesnt appear in the desktop view now

Here is the link to the codepen It is responsive for me check whether it works. (Ive used the pastebin code that you have provided with) image

strek
  • 1,190
  • 1
  • 9
  • 19