Disabling the final grid cell(s)

I am currently working on a 4 column grid in ReactJS. The grid includes various elements with images and text. I want to ensure that if there are five elements filled, the last three should be inactive so that each row always has four columns without any empty spaces. Essentially, the last cell(s) (up to 3) should not be interactive - no hover effects or focus states, just empty elements.

The data for the grid elements is fetched from a hardcoded JSON. Currently, my solution for the last cells is simply {[name: '', img: '']}.

As someone who is new to ReactJS, I haven't been able to find a suitable solution on platforms like Stack Overflow. Any guidance or pointers in the right direction would be greatly appreciated.

const GridItem = ({ name, path, altText }) => {
return (
    <li className={'grid-item'} key={name}>
        <a className={'link'}>
            <div className={'image'}>
                <img src={path} alt={altText} />
            </div>
            <div className={'image-text'}>{name}</div>
        </a>
    </li>
);

};

Desired output:
[img] [img] [img] [img]
[img] [null] [null] [null]

Answer №1

This question mainly pertains to CSS, and there are numerous ways to accomplish the desired outcome.

I suggest utilizing display: grid and grid-template-columns for creating grid-based layouts:

.grid {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 2px;
}

.grid img {
  width: 100%;
}
<div class="grid">
  <img src="https://picsum.photos/200/200" />
  <img src="https://picsum.photos/200/200" />
  <img src="https://picsum.photos/200/200" />
  <img src="https://picsum.photos/200/200" />
  <img src="https://picsum.photos/200/200" />
</div>

If you wish to create placeholder cells, you can simply add some CSS to hide them:

.grid {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 2px;
}

.grid img {
  width: 100%;
}

.grid img[src=""] {
  display: none;
}
<div class="grid">
  <img src="https://picsum.photos/200/200" />
  <img src="https://picsum.photos/200/200" />
  <img src="" />
  <img src="" />
</div>


Update

To enhance your code, consider this approach - if the name field is empty, provide a visual hint for easier styling:

const GridItem = ({ name, path, altText }) => {
return (
    <li className={'grid-item'} key={name}>
        <a className={`${name ? 'link' : 'link link__empty'}`}>
            <div className={'image'}>
                <img src={path} alt={altText} />
            </div>
            <div className={'image-text'}>{name}</div>
        </a>
    </li>
);

Alternatively, leave the cell empty:

const GridItem = ({ name, path, altText }) => {
return (
    <li className={'grid-item'} key={name}>
        <a className={'link'}>
            (name && 
            <React.Fragment>
                <div className={'image'}>
                    <img src={path} alt={altText} />
                </div>
                <div className={'image-text'}>{name}</div>
            </React.Fragment>)
        </a>
    </li>
);

The rendering will look similar to this:

* {
  box-sizing: border-box;
}

.grid {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
}

.grid-item {
  /* Exclude border to create a 4-column grid */
  flex: 0 1 calc(25% - 2px);
  
  /* Adjust for 1px border */
  border: solid #000 1px;
}

.link {
  text-decoration: none;
}

.image {
  width: 100%;
}

.image-text {
  text-align: center;
}

.link__empty *{
  /* Hide all children in case of emptiness */
  display: none;
}
<ul class="grid">
  <li class="grid-item">
    <a class="link" href="#">
      <img class="image" src="example.jpg" alt="Example Image" />
      <div class="image-text">Example Text</div>
    </a>
  </li>
  <li class="grid-item">
    <a class="link" href="#">
      <img class="image" src="example.jpg" alt="Example Image" />
      <div class="image-text">Example Text</div>
    </a>
  </li>
  <li class="grid-item">
    <a class="link link__empty" href="#">
      <img class="image" src="" alt="" />
      <div class="image-text"></div>
    </a>
  </li>
</ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to send props to a child component in JSX with TypeScript?

While passing props to the child, I encountered an error message stating "Property 'isClicked' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes". I defined "isClicked?: boolean" in my code. What additional steps sho ...

What strategies can I use to include multiple spans within div elements without causing the code to become overly lengthy?

I'm working with 20 spans representing movie genres, each accompanied by another span that "closes" the genre when selected. The closing span has an .active class, similar to this example: My version currently looks like this: To achieve this, I hav ...

What is the best way to isolate the CSS of individual components in Angular 2?

For the first component: CSS-- ngx-dnd-container { color:black; background-color: white; } HTML- <ngx-dnd-container [model]="targetItemsA" dropZone="multiple-target-a" </ngx-dnd-container> For the sec ...

To align a div or text to the right using inline-flex, simply

I am facing an issue with aligning my animated links to the right. Currently, I am using display: inline-flex, which works well but doesn't align the links properly. I have tried using float: right for alignment, but I feel there must be a better way ...

The scroll event listener activates based on the distance I have scrolled

const processChatRead = useCallback(() => { const chatWindow = refEntries.current; if ( chatWindow.scrollTop > chatWindow.scrollHeight - 800 && activeRoom && conversations?.content?.length > 0 && ...

Stop mega menu items from disappearing when hovered over

I'm currently working on a web page that features a mega menu. When I hover over the mega menu, it displays its items. However, when I try to hover over the items, they disappear. Here is the HTML code snippet: <li class="dropdown mega-dropdown m ...

Error message: Typescript and Styled-Component conflict: GlobalStylesProps does not share any properties with type { theme?: DefaultTheme | undefined; }

I've encountered an issue while passing props inside GlobalStyles in the preview.js file of my storybook. The props successfully remove the background from the default theme, but I'm receiving an error from Typescript: The error message states " ...

The Ultimate Guide to Setting Default Values in Material Ui Multiple Select Using React

I'm looking to populate multiple select options with specific values. Can someone assist with this? The valueSheet.userFullName array contains all user names, and I need to set some values for the dropdown. Thanks in advance :)) export default functio ...

Utilizing opera and applying an inset box-shadow when active

Check out this link When viewing in Chrome, the button looks great. However, when switching to Opera, the box-shadow is not visible when the button is pressed (:active). This issue only occurs when the box-shadow on the :active state is set to inset, like ...

Exploring the World of React Variables

Recently, I've been diving into the world of React and encountered some challenges while styling my components. Personally, I find it more organized to style within the same JavaScript file instead of having a separate one. However, I'm curious a ...

Is there a way to add a border around a div that extends beyond the div, similar to what

I'm attempting to create a border around this section, as seen in the image. However, I'm unsure of how to move it a few pixels outside of the main box. Here is what I've tried so far, but it's not quite achieving the desired result. H ...

Displaying a single item per click using jQuery

Hey there, I have a small issue with some HTML divs and show/hide functionality. I'm trying to make it so that only one div is shown per click, but my current jQuery code is showing all the divs at once. Any suggestions on how to fix this? Check ou ...

Creating an interactive navigation bar with React.js

I'm working on creating a dynamic navbar that displays different components based on whether the user is logged in or not. If the user is not logged in, the navbar will show three navlinks: About Login Signup If the user is logged in, the navbar wil ...

How can I position divs in a way that the top right corner of the child div touches the bottom left corner

I am currently working on implementing a message box feature on my website. When a user clicks on the inbox icon, I want a messages box to appear, similar to how stackoverflow handles it. Stackoverflow achieves this by placing a div outside the ordered lis ...

Navigate to a dedicated product detail page within a React application from the main product listing page

I am facing an issue with my product page. When a user clicks on a specific product card, it should redirect them to a new page displaying only that product's details. However, even after redirecting, the entire product list is still shown on the deta ...

Update the font URL in Bootstrap 5

I am looking to update the URL that Bootstrap uses to access fonts, as I want to host them on my server instead of relying on users to fetch them from Google with each page load. However, despite my efforts, I cannot locate the specific URLs mentioned when ...

What steps can be taken to avoid including empty tasks in React code?

Is there a way to prevent my application from adding empty tasks? Below is the code snippet for adding a new task to an array. How can I implement a condition to block the addition of empty tasks? This application follows Mozilla's guidelines for a R ...

Is it possible to adjust the height of input fields in MUI Reactjs?

Having trouble adjusting the height of input textfields using in-line css. <FormControl sx={{ "& .MuiOutlinedInput-notchedOutline": { borderColor: "blue", }, "&.Mui-focused .MuiOutlinedInpu ...

Error message: The variable "data" is not defined in next.js

Being new to React, I recently used getStaticprops to retrieve data from an API for a filter gallery project. However, I encountered an issue when trying to access the {props: data} outside of the blog function - it resulted in a Reference Error stating th ...

When a change occurs in the <input/> element within a <div>, the onChange event in React will be triggered

Upon entering text into the input, the onChange function is triggered on this code snippet. How is it possible for the onChange event to occur on a div element? Is there documentation available that explains this behavior? class App extends Component { ...