skip to Main Content

I have a React component with this structure
the tools and searchPanel blocks have fixed heights.
the main block should occupy the remaining space:


    <div className={`reference-container`}> 
        {
         isToolsVisible && <div className={`tools`}></div>
        }
        {
         isSeracpPanleVisible && <div className={`searchPanel`}></div>
        }
        <div className={`mainContent`}></div>
    </div>

I have a stylesheet file:

.reference-container {
    $toolHeight: 100px;
    $serachPanelHeight: 50px;
    
    height: 100%;
    display: grid;
    grid-template-areas: 
      "tools"
      "serachPanel"
      "mainContent";
    grid-template-rows: $toolHeight $serachPanelHeight 1fr;
    
    .tools {
        grid-area: tools
    }
    .searchPanel {
        grid-area: searchPanel
    }
    .mainContent {
        grid-area: mainContent
    }
} 

Depending on the condition, and are displayed.
However, I’m not sure how to correctly change grid-template-areas when the conditional blocks are absent.

I tried to set several conditional modifier classes for the parent container, and based on them, dynamically define the grid-template in the CSS file.

html(JSX)

<div className={`reference-container ${isToolsVisible ? 'with-tools' : ''} ${isSearchPanelVisible ? 'with-search-panel' : ''}`}>
  {isToolsVisible && <div className={`tools`}></div>}
  {isSearchPanelVisible && <div className={`searchPanel`}></div>}
  <div className={`mainContent`}></div>
</div>

SCSS

.reference-container {
  $toolHeight: 100px;
  $searchPanelHeight: 50px;

  height: 100%;
  display: grid;
  grid-template-rows: 1fr;
  
  &.with-tools {
    grid-template-areas: 
      "tools"
      "mainContent";
    grid-template-rows: $toolHeight 1fr;
  }
  
  &.with-search-panel {
    grid-template-areas: 
      "searchPanel"
      "mainContent";
    grid-template-rows: $searchPanelHeight 1fr;
  }
  
  .tools {
    grid-area: tools;
  }
  
  .searchPanel {
    grid-area: searchPanel;
  }
  
  .mainContent {
    grid-area: mainContent;
  }
}

I think this is not the correct solution, maybe it’s better not to use grid at all in this case?please advise a better one. Thank u advance!

2

Answers


  1. Chosen as BEST ANSWER

    I was also advised elsewhere that it's better to use Flexbox here. In my opinion, a simpler and more refined solution in this specific case is as follows.

    .reference-container {
      $toolHeight: 100px;
      $searchPanelHeight: 50px;
    
      height: 100%;
      display: flex;
      flex-direction: column;
    
    
      .tools {
        height: $toolHeight;
      }
    
      .searchPanel {
        height: $searchPanelHeight;
      }
    
      .mainContent {
        flex-grow: 1;
      }
    }
    

  2. You are doing it too complicated.

    The elements in the HTML are in the same order that you want them to be seen, you can let the grid-flow take care of this. You only need to set the main content to the last row:

    .container {
        display: grid;
        height: 300px;
        border: solid 1px black;
        grid-template-rows: auto auto 1fr;
        margin: 5px;
    }
    
    .tools {
        height: 100px;
        background-color: lightblue;
    }
    
    .search {
        height: 50px;
        background-color: lightgreen;
    }
    
    .main {
      background-color: yellow;
      height: 100%;
      grid-row: -2 / -1;
    }
    <div class="container">
    <div class="tools"></div>
    <div class="search"></div>
    <div class="main"></div>
    </div>
    <div class="container">
    <div class="search"></div>
    <div class="main"></div>
    </div>
    <div class="container">
    <div class="tools"></div>
    <div class="main"></div>
    </div>
    <div class="container">
    <div class="main"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search