Search code examples
cssreactjsstyled-components

Stretching div to height of parent


I understand that some variation on this question has been asked many times.

However, I can't seem to get this to work using the recommended methods.

Why is the flex: 1 seemingly being ignored?

The aim is for the red container to fill the available space below it.

CodeSandbox link here.

import React from "react";
import { render } from "react-dom";
import styled, { createGlobalStyle, ThemeProvider } from "styled-components";

const Style = createGlobalStyle`
  body, html {
    height: 100%;
    background: green;
    margin: 0;
    padding: 0;
    overflow-x: hidden;
    overflow-y: auto;
  }
`;

const FlexCol = styled.div`
  display: flex;
  flex-direction: column;
`;

const Layout = ({ children }) => {
  return (
    <div>
      <Header>header</Header>
      <FlexCol>{children}</FlexCol>
    </div>
  );
};

const Header = styled.div`
  height: 50;
  background: blue;
`;

const Home = () => {
  return (
    <div>
      <Feed />
    </div>
  );
};

const FeedContainer = styled.div`
  display: flex;
  flex-direction: column;
  flex: 1;
  background: red;
`;

const Feed = () => <FeedContainer>something</FeedContainer>;

const App = () => {
  return (
    <Layout>
      <Home />
    </Layout>
  );
};

render(
  <ThemeProvider theme={{}}>
    <React.Fragment>
      <Style />
      <App />
    </React.Fragment>
  </ThemeProvider>,
  document.getElementById("root")
);

enter image description here


Solution

  • For future reference, this can also be achieved by styling the Layout and using flexGrow where relevant.

    import React from "react";
    import { render } from "react-dom";
    import styled, { createGlobalStyle, ThemeProvider } from "styled-components";
    
    const Style = createGlobalStyle`
      body, html {
        height: 100%;
        background: green;
        margin: 0;
        padding: 0;
        overflow-x: hidden;
        overflow-y: auto;
      }
    `;
    
    const FlexCol = styled.div`
      display: flex;
      flex-direction: column;
      flex-grow: 1;
    `;
    
    const Layout = ({ children }) => {
      return (
        <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
          <Header>header</Header>
          <FlexCol>{children}</FlexCol>
        </div>
      );
    };
    
    const Header = styled.div`
      height: 50;
      background: blue;
    `;
    
    const Home = () => {
      return (
        <div
          style={{
            height: "100%"
          }}
        >
          <Feed />
        </div>
      );
    };
    
    const FeedContainer = styled.div`
      display: flex;
      flex: 1;
      background: red;
      height: 100%;
      width: 100px;
    `;
    
    const Feed = () => <FeedContainer>something</FeedContainer>;
    
    const App = () => {
      return (
        <Layout>
          <Home />
        </Layout>
      );
    };
    
    render(
      <ThemeProvider theme={{}}>
        <React.Fragment>
          <Style />
          <App />
        </React.Fragment>
      </ThemeProvider>,
      document.getElementById("root")
    );
    

    This gives:

    enter image description here