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!
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;
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>