Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Scrollable responsive content between components

I am trying to make a mobile responsive terms of service page that has a title, content and two buttons. The requirements are:

  • Components must not exceed 100% of the viewport so the content is scrollable
  • The Buttons are sticky (bottom)
  • If the content is short, it has to be just below the title and not in the middle
  • The page is mobile first friendly (landscape and portrait)

I have done most of it. Using the device toolbar, I am able to view it in mobile (landscape and portrait). The issue is, if toggling to landscape, the components goes beyond 100% of the height. I have tried using flexGrow but it doesn’t seem to work so my workaround for now is to specify the height which is not ideal to make it responsive.

Reference: div with 3 rows and scrollable content at the middle

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is a self-contained sample: https://stackblitz.com/edit/react-em99kh?file=src/App.js

App.js

const App = () => {
  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'space-between',
        height: '100vh',
      }}
    >
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
        }}
      >
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            alignContent: 'center',
            mb: 3,
            mt: 3,
          }}
        >
          <Typography variant="h3">{'Terms of Service'}</Typography>
        </Box>
        <Box
          sx={{
            display: 'flex',
            overflow: 'scroll',
            //Don't want to specify height
            height: '70vh',
            //flexgrow does nothing even if height is removed
            flexGrow: 1,
          }}
        >
          <Typography variant="body1">{data()}</Typography>
        </Box>
      </Box>
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          mb: 3,
          mt: 3,
        }}
      >
        <Button
          id="decline-btn"
          color="primary"
          variant="outlined"
          sx={{
            borderRadius: 16,
            width: '47%',
            height: '50px',
          }}
        >
          {'Decline'}
        </Button>
        <Button
          id="accept-btn"
          color="primary"
          variant="contained"
          sx={{
            borderRadius: 16,
            width: '47%',
            height: '50px',
          }}
        >
          {'Accept'}
        </Button>
      </Box>
    </Box>
  );
};

export default App;

>Solution :

You should probably reorganize a bit the page and then the content part should have a flex: 1 instead of having height: 70vh. Right now your flex-grow does nothing cause the parent div of the flew-grow is not the one with 100vh but the child of it which has no defined height.

Try to have this tree:

Main div: 100vh - no scroll
 Title Box
 content div: flex-1 scrollable
 Buttons Box

Couldn’t test but should look like this:

const App = () => {
  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'space-between',
        height: '100vh',
      }}
    >
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            alignContent: 'center',
            mb: 3,
            mt: 3,
          }}
        >
          <Typography variant="h3">{'Terms of Service'}</Typography>
        </Box>
        <Box
          sx={{
            display: 'flex',
            overflow: 'scroll',
            flexGrow: 1,
          }}
        >
          <Typography variant="body1">{data()}</Typography>
        </Box>

      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          mb: 3,
          mt: 3,
        }}
      >
        <Button
          id="decline-btn"
          color="primary"
          variant="outlined"
          sx={{
            borderRadius: 16,
            width: '47%',
            height: '50px',
          }}
        >
          {'Decline'}
        </Button>
        <Button
          id="accept-btn"
          color="primary"
          variant="contained"
          sx={{
            borderRadius: 16,
            width: '47%',
            height: '50px',
          }}
        >
          {'Accept'}
        </Button>
      </Box>
    </Box>
  );
};

export default App;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading