Adjustable number of columns in CSS grid

As of now, my webpage consists of a grid of articles with an absolutely positioned footer. My goal is to make the article grid have a variable number of columns based on the window height. I've considered calculating the distance between the filter bar (located above the article grid) and the footer, then dividing it by the height of each article row. However, I'm struggling to implement this method.

Would appreciate any suggestions or solutions!

Code:

<FilterBar>
        <div role="button" onClick={filterArticles} className="work-filter-container">
          <input type="checkbox" className={`${checkedFilter ? 'checked' : ''} work-filter`} />
          <p>ALLEEN WERK </p>
        </div>

        <div>
          <p>sorteer op</p>
          <button
            type="button"
            id="buttonrecent"
            className={activeRecent ? 'active' : ''}
            onClick={orderRecent}
          >
            recent
          </button>
          <span>/</span>
          <button
            type="button"
            id="buttona-z"
            onClick={orderAlphabetical}
            className={activeAlphabetical ? 'active' : ''}
          >
            A - Z
          </button>
        </div>
      </FilterBar>
      <div>
        <GridWrapper>
          {articlesOrder &&
            articlesOrder.map(article => {
              const data = article.node;
              const date = data._meta?.firstPublicationDate;
              const formattedDate = dateTimeService.getDate({ dateTime: date });

              return (
                <Article key={data._meta.id}>
                  <Link href={`/articles/${data._meta.uid}`}>
                    <a>
                      <span>{formattedDate}</span>
                      <p>{data.title?.[0]?.text}</p>
                    </a>
                  </Link>
                </Article>
              );
            })}
          <br />
        </GridWrapper>
      </div>

      <Footer position="absolute" textColor="white" />
    

CSS:

export const GridWrapper = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  width: fit-content;
  padding: 0 2.3rem;

  @media (${({ theme }) => theme.respondTo.desktop}) {
    width: 100vw;
    overflow-x: auto;
    white-space: nowrap;
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(min(5), 1fr);
  }
  &::-webkit-scrollbar {
    display: none;
  }
`;

Below is a screenshot illustrating the issue:

I aim to extend the columns to the footer dynamically, without having a fixed number, depending on the window's height.

https://i.sstatic.net/9ijD3.png

Answer №1

Tackling the Issue with Innovative Solutions

To overcome this challenge, start by determining the ideal window.innerHeight for a single column layout. Then, gradually increase the screen height using inspect elements until you achieve a responsive design where dual columns align perfectly. For instance, if one column looks optimal at 500px window.innerHeight and two columns at 530px, it indicates that adding 30px to your innerHeight necessitates an additional column.

Initiate the process by utilizing React's useState function to monitor the number of columns effectively:

const [columnsAmount, setColumnsAmount] = useState();

You can then implement a concise for loop based on the aforementioned details:

useEffect(() => {
    let columns = 1;
    for (let i = 500; i < window.innerHeight; i += 30) {
      columns += 1;
    }
    setColumnsAmount(columns);
  }, []);

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

Personalize the X feature in react-native-video

Is there any possibility to customize the event on X for react-native-video? In my app, I have implemented a feature where pressing play triggers a modal with a fullscreen video that starts playing automatically. Here is an example. However, my issue aris ...

Create a smooth transition: How to make a hidden button appear after a function finishes in JavaScript

I am completely new to the world of JavaScript, HTML, and CSS, so I'm feeling a bit lost on how to proceed with this task. My goal is to create a script that will initially display some text through a specific function. Once that text has been displa ...

The window fails to retain the scroll position when overflow is enabled

Whenever I click on a specific div, I use jQuery to dynamically apply overflow: hidden to the html and body. $(".mydiv").on("click", function() { $("html, body").css("overflow", "hidden"); }); However, this action causes the window to scroll to the to ...

Calculate the total cost for each row in a table by multiplying the quantity and price using jQuery, then display the result

I'm encountering an issue with my table row calculations involving price and quantity. The calculation results show up correctly in the console, but when I try to display them back on the table, the total sum of the first row gets duplicated into all ...

Different language implementations of AES ECB mode yield varying outputs

I have encountered an issue while attempting to transfer an AES encrypted string from a python script to a nodejs script using ECB mode. The relevant code snippets are as follows: Firstly, I utilize pycryptodome to encrypt a string with AES: from Crypto.C ...

Experimenting with animating an element through onClick event using JavaScript

I would like to create an animated div using JavaScript that activates on click. <div class="Designs"> <p>Designs</p> <div class="Thumbnails" data-animation="animated pulse"> <a href=" ...

Is there a chart component in bootstrap that allows for customization of time frames?

You can find this image in the search results when looking for rates online I'm interested in creating a similar chart, but I'm not sure what it's called. Can I use bootstrap line charts to create something like this? ...

React: Problem with preloaded image sizing

I am currently working on a project where I need to display various images sourced from URLs. These images come in different sizes and are contained within responsive div elements with a width set to 100%. While this setup initially seemed promising, there ...

Root: the tiny media inquiry does not appear on mobile devices

Currently troubleshooting on the this page. Can anyone help me understand why the site is not displaying correctly on a smartphone? The medium Query appears instead of the small one. I have included the foundation js files like this: <script src="file ...

Tips for resolving alignment issues in a chat box:

I am currently working on adjusting the alignment of my chat box app. I have placed 3 div elements with the class .bubble inside a div with the class .chatlines, but they appear to be clustered together instead of aligned properly. It's challenging to ...

Creating objects in JavaScript using Object.create can sometimes cause issues in Internet

I have been working on software development for SharePoint 2013, specifically dealing with overriding SharePoint's file previewer (changing filepreview.debug.js to myfilepreview.debug.js). Unfortunately, we have encountered a problem with IE8, while e ...

Ways to update the content within an IFRAME using server-side methods

I've searched through many posts, but I still haven't found a clear solution to my problem. Here's what's going on: I have a page with an IFRAME that is pulling content from a different domain. The style of the frame doesn't match ...

Loopback Model Property Somehow Resurrected After Deletion

Within my function, I am working with an object called 'ctx.instance' that contains various properties: firstName: 'Ron', lastName: 'Santo', minor: true, accepted: false, emailChanged: false, organizationId: 00000000000000000 ...

How to efficiently update multiple values using GraphQL Apollo Mutation

I need to perform updates on my backend user using TypeORM and have set up a mutation in React with Apollo GraphQL. The mutation calls the UserUpdateInput class. @Mutation(() => Boolean) async updateUser( @Arg("user_id", () => Int) ...

"Enhance your website with Ajax code that enables automatic refreshing of a PHP file, keeping its values up-to-date

Before diving in, I want to make it clear that my understanding of ajax is limited. I'm currently working on a small application where I have a load.php file that echoes 3 variables: $loadout[0]; $loadout[1]; $loadout[2]; The PHP file is functioning p ...

What role does Next.js play within the realm of React development?

As a newcomer to React, I recently discovered Next.js. While I have a basic understanding that it is a popular tool among React developers, I am unsure of the specific issues it aims to solve within React development. Would anyone be able to provide some ...

Calculating the number of days between two given dates, including both the start and end dates

I need to calculate the number of days between two dates, including both of the dates. My current method for this task is as follows: numDaysBetweenDates(startDate, endDate) { let millisecondsPerDay = 24 * 60 * 60 * 1000; return (endDate - startDate) ...

What is the best way to pause function execution until a user action is completed within a separate Modal?

I'm currently working on a drink tracking application. Users have the ability to add drinks, but there is also a drink limit feature in place to alert them when they reach their set limit. A modal will pop up with options to cancel or continue adding ...

Leverage JavaScript to add the rel=0 attribute to a specific URL

Currently, I am integrating videos into my WordPress website using a plugin and I'm looking for a way to ensure that all the YouTube URLs contain rel=0 to eliminate related videos at the end. Can anyone suggest the best approach to achieve this? Any ...

What is the best way to interweave my objects within this tree using recursion?

I am working on creating a new function called customAdd() that will build a nested tree structure like the one shown below: let obj = [] let obj1 = { key: "detail1Tests", id: "94d3d1a2c3d8c4e1d77011a7162a23576e7d8a30d6beeabfadcee5df0876bb0e" } ...