Using FEWER loops to create column classes on Twitter - What is their functionality?

Bootstrap utilizes various LESS mixins to create its column classes, along with other classes;

.make-grid-columns() {
  // Common styles for all sizes of grid columns, widths 1-12
  .col(@index) when (@index = 1) { // initial
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
    .col((@index + 1), @item);
  }
  .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
    .col((@index + 1), ~"@{list}, @{item}");
  }
  .col(@index, @list) when (@index > @grid-columns) { // terminal
    @{list} {
      position: relative;
      // Prevent columns from collapsing when empty
      min-height: 1px;
      // Inner gutter via padding
      padding-left:  (@grid-gutter-width / 2);
      padding-right: (@grid-gutter-width / 2);
    }
  }
  .col(1); // kickstart it
}

The use of LESS mixin guards helps in creating loops, as demonstrated in the LESS documentation examples;

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // next iteration
  width: (10px * @counter); // code for each iteration
}

div {
  .loop(5); // launch the loop
}

Understanding the intricate nested guard expressions used by Bootstrap can be challenging. Would appreciate a detailed comment on the above Bootstrap code to shed more light on its functionality.

Answer №1

The main objective of the .make-grid-columns() mixin is to dynamically generate multiple selectors that share common properties. It's crucial for this list to be generated dynamically as the number of columns (@grid-columns) may vary and cannot be hardcoded into the code.

You provided a good example illustrating how loops work in Less within your question.

To fully grasp mixins, it's important to understand that Less allows you to use the same mixin name multiple times. All 'matching' mixins will be included in the final CSS output. Using mixin guards like when () allows you to set conditions for when a particular mixin should be compiled. If the condition isn't met, the mixin won't be included. Additionally, pattern matching can be employed to match values based on different criteria:

.mixin1(a,@width){}
.mixin1(b,@width){}

When calling .mixin(a,20px);, only the first mixin will be matched. Matching can also be based on the number of arguments passed (arity). For instance, .col(@index) when (@index = 1) doesn't require a guard because it has only one argument. Therefore, .col(1); will only match based on arity, not the guard condition. The .col(@index) mixin calls the .col(@index, @list) mixin(s). In cases where two mixins are needed instead of an if/else statement, Less supports the usage of multiple mixins to achieve the desired result.

Alternatively, a mixin with additional arguments can be utilized:

.mixin(@iterator; @item:~""; @seperator:~"") when (@iterator < 5){
@list: ~"@{item} @{seperator} @{iterator}";
.mixin((@iterator + 1); @list; ",");
}
.mixin(@iterator; @list; @seperator) when (@iterator = 5){
.selector{
@{list}: value;
}
}
.mixin(1);

In this setup, the @seperator variable changes between iterations to reflect the appropriate joining character needed within the selector list.

Selector interpolation is used in @{list} { } to incorporate the list of selectors along with their respective properties. Understanding and implementing these concepts is vital in working effectively with mixins in Less.

For more insights, I recommend reading the informative blog post by @seven-phases-max on generating selector lists using such structures.

Lastly, Bootstrap relies on an extensive list of selectors to avoid attribute selectors partially or entirely. The recommended CSS/Less approach offers an alternative way to handle column styling without relying heavily on attribute selectors, which could impact performance in certain situations.

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 create a stylish vertical line separating two divs stacked vertically?

I am trying to connect two divs that are positioned vertically with a clean and elegant vertical line. Although I attempted using the pipe (|) font, it did not produce the desired result. Can anyone provide guidance on how to create a more aesthetically pl ...

Creating engaging animations for variable content in Safari using CSS

This multi-step wizard is designed to smoothly transition between its 3 steps. Upon clicking the "next" button in step 1, the content is pushed down to reveal step 2. Similarly, when advancing from step 2 to step 3, the contents of both previous steps are ...

Creating maps in R using loops

I am currently working with a large data frame containing 500 species and 25,000 point locality observations for each species. My goal is to create individual point maps for each species, where each point represents an occurrence of that particular species ...

I am experiencing difficulty locating the style.css file within my Node.js/Express application

I am currently working on a Node.js/Express app and I'm facing an issue where my browser is unable to find my style.css file, even though I am using a static file. Here is the directory structure: public -> css -> styles.css server -> serv ...

What is the best way to create a navbar with a grid that spans the full height and includes two rows

My approach to structuring the layout using CSS grid is as follows: nav content nav footer This means that the 'nav' will occupy the entire height of the page with a specified width, and the remaining space will be divided between the 'cont ...

Using Jquery to switch between different CSS styles

I'm currently working with a jQuery code that is functioning properly. $(window).load(function() { $('.menuBtn').click(function(e) { e.preventDefault(); (this.classList.contains('is-active') === true) ? this.c ...

Increasing and decreasing the display of content using JQuery based on height rather than character count

I'm attempting to create a show more/show less link with a set height of 200px that, when clicked, will reveal the rest of the content. Anything exceeding 200px will be hidden, and there will be a "show more" link to display the remaining text. I&apos ...

Adding HTML components to an image with adjustable dimensions

A graphic designer has provided us with an image featuring three selection boxes. I implemented the necessary HTML elements and CSS to display three overlapped selection boxes on top of the image, using pixel values for positioning. However, the original ...

What is the best way to showcase a Table and an Image side by side in HTML using inline

Can someone help me figure out how to align my image and table on the same level? I've been struggling to get "inline-block" to work. :( <p id="play"> hey </p> <div id="menu"> <table> <tr> <td>Models</td& ...

Implementing a pop-up notification at the center of the display for empty fields

I am currently working on a task that requires me to display a pop-up message at the top-middle of the screen stating "please fill in all fields before submitting". This custom box should be stylable using CSS. Although the solution seems simple, I am str ...

Using CSS to center the text and adding a separator line in blank spaces for a clean and stylish look

Request to Create Centered Date Element with Line Borders I am looking to design an element where the date is positioned at the center, while two horizontal lines fill the empty space on either side. Ideal Design I Want to Achieve: My Current Approach a ...

"Having issues with Django not properly applying the JavaScript and CSS files I've linked in

I have completed my project and organized all the necessary files, including index.html, css, js, and settings.py within the appropriate folders. I am encountering an issue with applying a pen from the following source: CodePen index.html <!DOCTYPE h ...

Utilize the CSS exclusively for the specific element

nav ul { } nav ul li { margin-left: 7px; } nav.ul li a, a:link, a:visited { float: left; padding: 7px; margin-left: 15px; color: #ffffff; text-decoration: none; font-weight: bold; } nav ul li a:hover { } The styling above is ...

Navigating through a nested array within a JSON object using Vue.js - a guide

I have a JSON data array that includes outer and inner subarrays. My goal is to loop through both levels and create a table. Below you'll find a snippet of the sample array: { class:'I', subDdiv:[ { ...

"Step-by-step guide on placing an order for the button

I am currently working with material-ui and encountering a roadblock. My goal is to design a homepage for a dashboard where the various services are listed. I am attempting to organize these 6 buttons into 2 rows and 3 columns, totaling 6 buttons in all. A ...

css determining the width through calculation

I am facing a challenge with a math problem. My content box is 700 pixels wide, and my hentry (inside content) is 100% wide with padding of 10 pixels. This causes the hentry to be wider than the content, resulting in an overflow... Does anyone have a so ...

Customize the background color of a particular select element within an array of dynamically created select elements

I've been experimenting with jQuery to dynamically adjust the background color of a select element based on the chosen option. The select elements are being generated using the following code: while ($qrow = $qquery->fetch(PDO::FETCH_ASSOC)) { ...

The sidebar is not correctly displaying at full height

Having trouble getting the sidebar to fit perfectly between the header/nav and footer in full height. <html> <head> <meta charset="utf-8"> </head> <body> <header> <div class="header"> & ...

Using the $.get() method within a loop of .each(), retrieve the specific $(this) value within the $.get function

Apologies for the poorly worded question, but I'm struggling to find a better way to phrase it. I'm currently working with a .each() loop where I need to update a specific css() parameter of each item in the loop. However, I can't seem to g ...

Revealing CSS elements moving from the left to the right

On my website, I have implemented two different menu bars. The first one, in black, stays fixed at the top of the page. The second one, in orange, becomes sticky once it reaches the black bar. At the same time, a small logo image is revealed, previously hi ...