1

I am trying to make the hotel search results feed be a fixed height, but also be able to scroll if the results exceed the size of the feed container.

It should look like this: mockup

But currently it looks like this: current

As you can see, the scroll bar appears on the entire page, instead of in the feed container.

I have the entire page wrapped in a flexbox parent container, and then the two immediate children are the searchBar and page content. page content is also a flex container currently, which contains the hotel search results and hotel suggestions components as flex children. I am currently writing the code in React with Styled Components, but this is essentially a css problem. Any ideas on how to structure my css to make it look the way I want?

App.js:

//entire screen
const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
`;

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchResults: [],
    };

    this.displaySearchFeed = this.displaySearchFeed.bind(this);
  }

  displaySearchFeed(data) {
    console.log("state set");
    this.setState({
      searchResults: data,
    });
  }

  render() {
    return (
      <Wrapper>
        <SearchBar displaySearchFeed={this.displaySearchFeed} />
        <HotelPageContent searchResults={this.state.searchResults} />
      </Wrapper>
    );
  }
}

HotelPageContent.js

const ResultsContainer = styled.div`
  display: flex;
`;

export default function HotelPageContent(props) {
  console.log("rendered");
  console.log(props.searchResults);
  return (
    <ResultsContainer>
      <HotelSearchResults searchResults={props.searchResults} />
      <HotelSuggestions />
    </ResultsContainer>
  );
}

HotelSearchResultsFeed.js

const Container = styled.div`
  height: 100%;
  flex: 3;
  border-color: red;
  border-width: 3px;
  border-style: solid;
  overflow-y: scroll;
`;
// display: grid;

// position: fixed;

export default function SearchResults(props) {
  return (
    <Container>
      <div>Hotel Search Results</div>
      {props.searchResults.length > 0
        ? props.searchResults.map((data, index) => {
            return <HotelCard key={index} HotelData={data} />;
          })
        : null}
    </Container>
  );
}

HotelSuggestions.js

const Container = styled.div`
  height: 100%;
  display: grid;
  flex: 1;
  border-color: red;
  border-width: 1px;
  border-style: solid;
`;

export default function HotelSuggestions(props) {
  return (
    <Container>
      <div>Hotel Suggestions</div>
    </Container>
  );
}

HotelCard.js

const Container = styled.div`
  height: 10em;
  display: flex;
  flex-direction: row;
  border-color: black;
  border-width: 1px;
  border-style: solid;
`;

const CenterSection = styled.div`
  background-color: #80cbc4;
  border: 1px solid #fff;
  text-align: center;
  flex: 2;
`;

const HotelImageWrapper = styled.div`
  flex: 1;
`;

const HotelImage = styled.img`
  height: 100%;
  width: 100%;
  object-fit: contain;
  border-color: black;
  border-width: 1px;
  border-style: solid;
`;

export default function HotelCard({ HotelData }) {
  return (
    <Container>
      {/* <HotelImage src={imgSrc} /> */}
      <CenterSection>{HotelData["name"]}</CenterSection>
      <div>{HotelData["rating"]}</div>
    </Container>
  );
}

2 Answers2

0

I would recommend to use CSS-Grid over flexbox for such design. CSS-Gris has the advantage to control height and width at the same time. In the sample below, the body is declared to 100vh and 100vw to fill out the exact screen size. The cals is needed to counter the paddings. The search result and hotel suggestion has an overflow rule added so that those cards will get a scrollbar instead of the body.

Test the snippet best in full screen. Of course you can change it as you want, the snippet just shows an example how to accomplish it with the sue of a CSS-Grid

body {
  height: calc(100vh - 40px);
  width: calc(100vw - 40px);
  display: grid;
  grid-template-columns: auto min-content;
  grid-template-rows: min-content auto;
  grid-gap: 20px;
  padding: 20px;
  margin: 0px;
}

p {
  margin: 0;
}

#search-bar,
#search-result,
#hotel-suggestion {
  border: 1px solid black;
  padding: 20px;
}

#search-result,
#hotel-suggestion {
  overflow-y: auto;
}

#search-bar {
  grid-column: span 2;
}

#hotel-suggestion {
  width: 25vw;
}

#search-result div,
#hotel-suggestion div {
  border: 1px solid black;
  padding: 10px;
  margin-top: 5px;
}

#search-result div:last-child,
#hotel-suggestion div:last-child {
  margin-bottom: 10px;
}
<div id="search-bar">
  Insert searchbar here
</div>
<div id="search-result">
  <p>hotel search results</p>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
  <div>dummy result</div>
</div>
<div id="hotel-suggestion">
  <p>hotel suggestion</p>
  <div>dummy suggestion</div>
  <div>dummy suggestion</div>
  <div>dummy suggestion</div>
</div>
tacoshy
  • 10,642
  • 5
  • 17
  • 34
0

check this.(SCSS)

main { //ResultContainer
    display: flex;
    width: 100%;
    height: calc(100vh - 80px);
    .list { //SearchResultFeed
        flex-grow: 1;
        padding: 0 10px 10px 10px;
        background-color: #82e9de;
        overflow-y: auto;
    }
    .curation { //Suggestions
        flex-basis: 150px;
        background-color: #4db6ac;
    }
}

https://codepen.io/chamuchamu/pen/dypMLze

Otter
  • 1
  • 2