1

I have a webpage designed using CSS Grid. This is how it looks like -

With the user name

There are certain cases where I want to remove the Username - CSS Grid User such that the rendered page looks like this -

Without the user name

I am using this in a react/redux project. Based on a variable, I have to show/hide the username of the user.

Thus I want to change the number of rows of the grid, I tried making the class display: none like so

.username {
  display: none;
}

However, all it does is removes the CSS Grid User string, but the row exists, leaving a blank space.

Is there any way where I would be able to change the number of rows/columns dynamically. I don't want to use CSS in JS solutions. I have a plain CSS file that sets styles to the react component.

.layout {
  display: grid;
  grid-template-columns: minmax(200px, auto) minmax(200px, 300px) minmax(900px, auto) minmax(200px, auto);
  grid-template-rows: 60px 60px 60px minmax(700px, auto);
  grid-gap: 5px;
  height: calc(100vh);
}

.navbar {
  grid-column: 1 / -1;
  grid-row: 1 / 2;
  background-color: #3a3f51;
  border-bottom: 1px solid #797d89;
  text-align: center;
  color: aliceblue;
}

.username {
  grid-column: 1 / -1;
  grid-row: 2 / 3;
  background-color: #f7f9f9;
  border-bottom: 1px solid #dee5e7;
  text-align: center;
}

.statement-list {
  grid-column: 2 / 3;
  grid-row: 3 / 5;
  max-height: 600px;
  overflow-y: auto;
}

.title {
  grid-column: 3 / 4;
  grid-row: 3 / 4;
}

.content {
  grid-column: 3 / 4;
  grid-row: 4 / 5;
  overflow-x: auto;
  overflow-y: auto;
}
<body class="layout">
  <div class="navbar">About</div>
  <div class="username">CSS Grid User</div>
  <div class="title">Lorem Ipsum</div>
  <div class="statement-list">
    Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna. Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus
    lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna.
  </div>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean laoreet a odio quis commodo. In nisl justo, tincidunt vel aliquet eget, mollis eget lorem. Aenean sit amet nibh eget nunc sodales vestibulum id ac ante. Nullam eleifend sodales ipsum, sed
    porta tellus posuere molestie. Vestibulum congue porta odio sed iaculis. Phasellus varius sodales ullamcorper. Praesent consectetur ante eget turpis pretium, eget sagittis leo volutpat. Aenean posuere, sapien quis placerat pulvinar, lectus est interdum
    dui, at pretium risus sapien et neque. Sed eu fringilla turpis. Ut viverra, nisl non euismod sollicitudin, tellus lectus finibus leo, in ornare sem mauris non eros. Fusce augue est, rhoncus vitae tristique in, malesuada nec libero. Sed venenatis vehicula
    ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce interdum auctor ante a fermentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam malesuada
    scelerisque tortor ac faucibus. Integer pharetra eget velit a tempus. Aenean at lobortis massa, vel accumsan ligula.
  </div>
</body>

3 Answers 3

2

Once you create explicit tracks, which are rows and columns created using the following properties:

  • grid-template-rows
  • grid-template-columns
  • grid-template-areas
  • grid (a shorthand)

... you are stuck with those tracks. They don't go away.

Your attempt to remove an explicit row with display: none on a grid item (.username) cannot work. The command is operating at the item level, but the row was created at the container level.

If you want to build a grid that has a dynamic inflow and outflow of tracks, then use implicit, not explicit, tracks.

Implicit tracks are rows and columns created automatically to accommodate grid items that are positioned outside of the explicit grid.

When there is no grid item to occupy an implicit track, that track simply doesn't exist.

I've posted two examples below, based on your code.

  • the first example displays a row for .username, the other example does not;
  • grid-template-rows has been removed, so there are no explicit rows; all rows are implicit;
  • heights previously set on grid-template-rows have been moved to their respective grid items;
  • implicit row heights are governed by grid-auto-rows, whose initial value is auto (content-based), so it works well with the previous point; and,
  • because you're dealing with implicit tracks, source order matters.

with username row

.layout {
  display: grid;
  grid-template-columns: minmax(200px, auto) minmax(200px, 300px) minmax(900px, auto) minmax(200px, auto);
  grid-gap: 5px;
  height: 100vh;
}


/* implicit first row */
.navbar {
  height: 60px;
  grid-column: 1 / -1;
  background-color: #3a3f51;
  border-bottom: 1px solid #797d89;
  text-align: center;
  color: aliceblue;
}


/* implicit second row */
.username {
  /* display: none; */
  height: 60px;
  grid-column: 1 / -1;
  background-color: #f7f9f9;
  border-bottom: 1px solid #dee5e7;
  text-align: center;
}


/* implicit third row (start) */
.statement-list {
  height: 60px;
  grid-column: 2 / 3;
  max-height: 600px;
}


/* implicit third row */
.title {
  height: 60px;
  grid-column: 3 / 4;
  grid-row: 3 / 4;
}

.content {
  min-height: 700px;
  grid-column: 3 / 4;
  overflow-x: auto;
  overflow-y: auto;
}

body {
  margin: 0;
}
<body class="layout">
  <div class="navbar">About</div>
  <div class="username">CSS Grid User</div>
  <div class="title">Lorem Ipsum</div>
  <div class="statement-list">
    Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna. Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus
    lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna.
  </div>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean laoreet a odio quis commodo. In nisl justo, tincidunt vel aliquet eget, mollis eget lorem. Aenean sit amet nibh eget nunc sodales vestibulum id ac ante. Nullam eleifend sodales ipsum, sed
    porta tellus posuere molestie. Vestibulum congue porta odio sed iaculis. Phasellus varius sodales ullamcorper. Praesent consectetur ante eget turpis pretium, eget sagittis leo volutpat. Aenean posuere, sapien quis placerat pulvinar, lectus est interdum
    dui, at pretium risus sapien et neque. Sed eu fringilla turpis. Ut viverra, nisl non euismod sollicitudin, tellus lectus finibus leo, in ornare sem mauris non eros. Fusce augue est, rhoncus vitae tristique in, malesuada nec libero. Sed venenatis vehicula
    ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce interdum auctor ante a fermentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam malesuada
    scelerisque tortor ac faucibus. Integer pharetra eget velit a tempus. Aenean at lobortis massa, vel accumsan ligula.
  </div>

without username row (by just adding display: none)

.layout {
  display: grid;
  grid-template-columns: minmax(200px, auto) minmax(200px, 300px) minmax(900px, auto) minmax(200px, auto);
  grid-gap: 5px;
  height: 100vh;
}


/* implicit first row */
.navbar {
  height: 60px;
  grid-column: 1 / -1;
  background-color: #3a3f51;
  border-bottom: 1px solid #797d89;
  text-align: center;
  color: aliceblue;
}


/* implicit second row */
.username {
  display: none; /* ADDED */
  height: 60px;
  grid-column: 1 / -1;
  background-color: #f7f9f9;
  border-bottom: 1px solid #dee5e7;
  text-align: center;
}


/* implicit third row (start) */
.statement-list {
  height: 60px;
  grid-column: 2 / 3;
  max-height: 600px;
}


/* implicit third row */
.title {
  height: 60px;
  grid-column: 3 / 4;
  grid-row: 3 / 4;
}

.content {
  min-height: 700px;
  grid-column: 3 / 4;
  overflow-x: auto;
  overflow-y: auto;
}

body {
  margin: 0;
}
<body class="layout">
  <div class="navbar">About</div>
  <div class="username">CSS Grid User</div>
  <div class="title">Lorem Ipsum</div>
  <div class="statement-list">
    Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna. Phasellus commodo sit amet eros non pharetra. Phasellus consequat augue est, ornare finibus
    lectus auctor non. Praesent rutrum odio tortor. Proin id massa magna.
  </div>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean laoreet a odio quis commodo. In nisl justo, tincidunt vel aliquet eget, mollis eget lorem. Aenean sit amet nibh eget nunc sodales vestibulum id ac ante. Nullam eleifend sodales ipsum, sed
    porta tellus posuere molestie. Vestibulum congue porta odio sed iaculis. Phasellus varius sodales ullamcorper. Praesent consectetur ante eget turpis pretium, eget sagittis leo volutpat. Aenean posuere, sapien quis placerat pulvinar, lectus est interdum
    dui, at pretium risus sapien et neque. Sed eu fringilla turpis. Ut viverra, nisl non euismod sollicitudin, tellus lectus finibus leo, in ornare sem mauris non eros. Fusce augue est, rhoncus vitae tristique in, malesuada nec libero. Sed venenatis vehicula
    ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce interdum auctor ante a fermentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam malesuada
    scelerisque tortor ac faucibus. Integer pharetra eget velit a tempus. Aenean at lobortis massa, vel accumsan ligula.
  </div>


Spec references:

Sign up to request clarification or add additional context in comments.

1 Comment

I have already accepted an answer that works. However, this is really helpful, thanks!
1

You could set a class on the div.layout element (or some other parent tag) based on the username variable you are setting, and then adjust your CSS grid to redefine the CSS grid columns/rows based on that class.

(I'm not super familiar with React, but if memory serves you can set a class conditionally like this)

<div className={"layout " + (this.props.usernameShown ? 'username-avail' : 'username-unavail')}>

Then in your CSS file, you can define your CSS grid such as

.layout {
    display: grid;
    grid-template-columns: minmax(200px, auto) minmax(200px, 300px) minmax(900px, auto) minmax(200px, auto);
    grid-gap: 5px;
    height: calc(100vh);
}

.username-avail.layout {
    /* Four rows */
    grid-template-rows: 60px 60px 60px minmax(700px, auto);
}

.username-unavail.layout {
    /* Three rows */
    grid-template-rows: 60px 60px minmax(700px, auto);
}

1 Comment

Clean and elegant. Thanks!
0

Personally, I like to write my own functions. So this would be my approach ...

JavaScript

function removeElementsByClass(className){
    var elements = document.getElementsByClassName(className);
    while(elements.length > 0){
        elements[0].parentNode.removeChild(elements[0]);
    }
}

Then just ...

removeElementsByClass('.username')

Of course, there's no shame in taking the easy option (but it's helpful to know what happens behind the scenes).

jQuery

$('.username').remove();

NOTE: This will only remove the element with the assigned class name. So, you'll either need to give a class name to the targeted row, or drill back further by including an additional parentNode ...

elements[0].parentNode.parentNode.removeChild(elements[0]);

2 Comments

I an using react/redux and directly manipulating the dom isn't advised in react.
@yadav_vi -- React is a JavaScript library. It’s not a framework. It simplifies the process of building out user interfaces, but still implemented with standard JavaScript (and is best used for quick demos, IMHO). Redux does a bit more and is probably the one you're most concerned about. Unfortunately, their simplicity also takes away control -- and before long, you run into issues like this; a function that would normally take a single line to implement, instead, requires this: stackoverflow.com/questions/43893508/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.