Creating a versatile TailwindCSS grid that can adjust to varying numbers of grid columns

I am currently working with Vue3 and TailwindCSS, attempting to create a grid using a dynamic grid-cols-{n} class. While I am aware that TailwindCSS typically supports up to 12 columns by default, the challenge arises when the number of columns needed is entirely dynamic and cannot be customized within the theme.

For example, consider the following simple HTML / JS snippet:

const amountOfItemsPerRow = 16;

const container = document.getElementById("container");

for (let i = 0; i < amountOfItemsPerRow; i++) {
  const item = document.createElement("div");
  item.innerText = i;
  container.appendChild(item);
}

container.classList.add(`grid-cols-${amountOfItemsPerRow}`); // this doesn't work if the value is greater than 12
<script src="https://cdn.tailwindcss.com"></script>

<div id="container" class="grid"></div>

In this scenario, the code functions correctly if the value of amountOfItemsPerRow is less than or equal to 12, but breaks the CSS style when exceeding 12 columns.

Is there a way to address this issue without resorting to writing custom CSS styles, perhaps through a dynamic solution within Tailwind?


An Alternative Approach:

Following guidance from the TailwindCSS documentation, I attempted to modify the line

container.classList.add(`grid-cols-${amountOfItemsPerRow}`);

to

container.classList.add(`grid-template-columns:repeat(${amountOfItemsPerRow},minmax(0,1fr))`);

In an effort to develop a more "native" solution, however, this adjustment did not yield the desired outcome.

Answer №1

Unfortunately, plain TailwindCSS does not support dynamic grid template columns.

Even though @Ajay Raja's suggestion is for JIT (just-in-time) compilation, it won't work for dynamic changes after deployment. The only option is to set up Javascript listeners to dynamically modify the style attribute based on the implementation of the desired class.

To achieve this, you can refer to the implementation of the .grid-columns-12 class from the documentation.

.grid-columns-12 {
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

For a Vue application, consider implementing two-way data binding like in Angular or React instead of directly applying style directives to class attributes as previously attempted.


An alternative solution is to pre-generate a range of custom grid classes in the tailwind.config.js file during build time, allowing safe usage at runtime:

You can create your own custom grid modifiers following the guidelines in the documentation.

module.exports = {  
  theme: {    
    extend: {      
      gridTemplateColumns: {        
        // Simple 16 column grid        
        '16': 'repeat(16, minmax(0, 1fr))',     
      }    
    }  
  }
}

Add a function in the config file that generates a series of grid columns and remember to specify to preserve all grid-columns-* classes during purging to avoid unintentional removal.

Answer №2

In my expertise with React.js & Next.js:

import { AllHTMLAttributes } from "react";
import classNames from "classnames";

// Defining interface IGrid to include all properties of <div />
interface IGrid extends AllHTMLAttributes<HTMLDivElement> {}

export default function Grid({
  className = "",
  cols = 8,
  rows = 4,
  ...rest
}: IGrid) {
  const props = { className: classNames(className, "grid"), ...rest };
  const gridTemplateColumns = `repeat(${cols}, 1fr)`;

  const gridItems = new Array(cols * rows)
    .fill("")
    .map((_, i) => <div key={`gridItem-${i}`}>{i}</div>);

  return (
    <div {...props} style={{ gridTemplateColumns }}>
      {gridItems}
    </div>
  );
}

✅ Tested in:

<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2753464e4b504e4943445454671409140914">[email protected]</a>
without any further setup needed.

⚠️ Although not considered the best practice:

Microsoft Edge Tools: (no-inline-styles)

Answer №3

Generating Dynamic Class Names with Tailwindcss is a breeze. You have the flexibility to include dynamic classes within square brackets using TailwindCSS.

const amountOfRows = 16;
const amountOfCellsPerRow = 16;

const container = document.getElementById("container");

for (let rowIndex = 0; rowIndex < amountOfRows; rowIndex++) {
  for (let columnIndex = 0; columnIndex < amountOfCellsPerRow; columnIndex++) {
    const cell = document.createElement("div");
    cell.innerText = `${rowIndex}|${columnIndex}`;
    container.appendChild(cell);
  }
}

container.classList.add(`grid-cols-[${amountOfCellsPerRow}]`)

For a more in-depth explanation, visit this link.

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

Tips for sending an icon as a prop in React components

I'm struggling to implement an icon as a prop while using props for "optionText" and "optionIcon". The optionText is working fine, but I'm facing issues with the OptionIcon. File where I'm creating props import Icon from ...

Tips on rearranging the location of a div element within a directive

I have created a custom directive that displays two divs, Div1 and Div2, with a splitter in the middle: Splitter Image Now, I am looking for a way to swap the positions of these two divs dynamically using an Angular directive. I thought about using ng-swi ...

Using AJAX to send data with a POST request in Django may not function properly

Let me preface by saying I have searched for solutions online, but none of them seem to address my specific issue (mainly because they use outdated methods like Jason). I am currently working on a Django project and trying to implement ajax for a particul ...

Angular 6: Issue with displaying data on the user interface

Hello! I am attempting to fetch and display a single data entry by ID from an API. Here is the current setup: API GET Method: app.get('/movies/:id', (req, res) => { const id = req.params.id; request('https://api.themoviedb.org/ ...

Function that contains a JavaScript reference and observation

I'm experiencing issues with the code below and I'm having trouble figuring out what's causing the problem. function some(){ for (var i=0;i<....;i++) { var oneObject; ...some logic where this object is set oneObject.watch(prop ...

The FormData object appears to be blank, even though it was supposed to be populated when attempting to send a PDF file using a multipart FormData POST request in Cypress

I am attempting to send a PDF file as a POST request. The API supports the use of @RequestPart and @RequestParam: @RequestPart("file") MultipartFile file; @RequestParam(value = "document-types", required = false) Set<String> documentTypes; My appro ...

If an element exists in one of the dimensions of a multi-dimensional array

I am facing an issue with my 2D array structure. Here is an example of how it looks: `var arr = [["1", "2", "3"], ["4", "5"], ["6"]];' Despite having the value "4" in one of the inner arrays, when I try running $.inArray("4", arr); or arr.indexOf("4" ...

Tips for retrieving nested objects in a get request

A dilemma I'm facing involves a form that effectively sends and saves JSON data to MongoDB using mongoose. However, the issue arises when attempting to access this data as the nested objects display on the get route html page as: { synth: { patch_na ...

Specialized Node.js extension for automatic dependency installation

My current setup involves a custom Yeoman generator for specific applications, which comes with its own set of dependencies and configurations. - GruntJS must be installed globally; - Bower must be installed globally; - Yeoman must be installed globally ...

Modifying attributes for individual components in Vue.js classes

Recently, I integrated a reusable component called "LightBox" into my website, which displays images in higher resolution. The LightBox functionality is linked to each element having a thumbnail. However, I encountered an issue. There are multiple elements ...

Data modifications in polymer are not being accurately displayed

I need help with hiding/unhiding a UI element using a button in Polymer. Despite having the necessary elements and code set up, it is not working as expected: <button id="runPredictionButton"> <i>Button text</i> </button> <p ...

Please provide instructions on how to update a webpage section using ajax/json

Currently, I am in the process of developing a chat website and focusing on managing ONLINE USERS. I have implemented AJAX to handle refreshing data, however, I am facing issues with using Append(); method. Whenever I refresh the section, the same data k ...

What are the steps to manually activate input validation in Angular 2?

Having two inputs is the scenario here: The first input undergoes custom validator application The second input has a dynamic and editable value utilized in the custom validator If the custom validator is applied on the first input, then focus shifts to ...

Is there a way to retrieve the Boolean value from an ng-show attribute without having to re-evaluate the expression?

I'm currently working on a project that involves displaying and hiding a lot of content dynamically using ng-show. Some of the expressions being evaluated are quite lengthy, like this... <div ng-show="some.object.with.nested.values && ...

Different methods to retrieve content within a div that is located on a separate, included page

It's a bit tricky to come up with a title for this topic, but essentially, I'm trying to figure out how to get content from an included page into a specific div using HTML and PHP. Let me break it down: In the header.php file, we have the follo ...

Encountering Errors with Angular JS Following Update from Version 1.1.0 to 1.1.1

After upgrading, I noticed that the ng-repeat function is taking significantly longer to load and is attempting to display additional content boxes without serving the actual content provided by $resource. I have pinpointed the issue to the update from ve ...

In the iOS app when the Ionic HTML5 select keypad is opened, a bug causes the view to scroll upwards and create empty space after tapping the tab

I am currently working with Ionic v1 and AngularJS, utilizing ion tabs: <ion-tabs class="tabs-icon-top tabs-color-active-positive"> <!-- Home Tab --> <ion-tab icon-off="ion-home" icon-on="ion-home" href="#/tab/home"> <ion-nav ...

Assist me in minimizing redundant code in a basic jQuery function

I successfully created a carousel using the jQuery cycle plugin with 4 links that correspond to different slides. Currently, I have separate blocks of code for each link, but I'm looking to optimize by creating a single function. $('#features-sl ...

Is the element loaded but not appearing on screen?

I am facing an issue when using ajax to send data to a PHP server and displaying it in the view. Even though the data loads successfully (checked in console), it does not display in the view. Can someone please help me resolve this? Here is my code : Vie ...

Is it possible to utilize the default error handling page rather than a specific view for expressing

Currently, I'm going through a tutorial on MDN Express for building a "Local Library" application that utilizes Pug (Jade) as its templating engine. In this segment of the tutorial, it explains the process of creating a controller to manage a form POS ...