This document describes the parts required to create a JavaScript function for evaluating container queries, and this document itself is also executable JavaScript code for such a plugin. By the time you are finished reading this document you should not only understand how container queries work, but have read the source code to a usable, testable container queries function.

/* To define a */ function /* for */ containerQueries /* we will need to supply a */ (selectorList, /* of CSS selectors to match elements in the document, a JavaScript function to serve as a */ test, /* to determine which elements our styles should apply to, and a */ stylesheet) /* with the CSS we wish to apply to all elements passing the test. */ {

/* Inside of our function we need to define a */ var /* for all */ matchingTags /* that is */ = /* to taking the */ document /* and running a */ .querySelectorAll /* for the */ (selectorList); /* supplied to the function. */

/* Next we can create a */ var /* to keep track of our */ generatedCSS /* that is */ = /* to a */ new String;

/* The last piece of setup we require is a */ var /* to keep track of our current element */ count /* that is */ = /* to */ 0;

/* Now we are ready to take all */ matchingTags /* and run the following logic */ .forEach( tag => {

/* The first thing we need to create for each tag is a new */ var /* called */ uniqueAttribute /* that is */ = /* to the text of our */ (selectorList + test) /* added together, with all non-Word characters removed. We can do this with a */ .replace /* using the regular expression */ (/\W+/g, /* and swapping every non-Word character you find with */ '' /* , the empty string */ );

/* Now we're ready to test each of our tags! */ if /* we */ (test /* the current */ (tag) /* and the result is */ == /* to */ true) /* then we can go ahead with the following three actions: */ {

/* First we will take the */ tag /* that passes our test and */ .setAttribute /* equal to */ ('data-' + /* our */ uniqueAttribute, /* and set this attribute to the current */ count);

/* Second we will take our */ generatedCSS /* and make sure it is */ = /* to the existing */ generatedCSS + /* the supplied */ stylesheet /* with all instances of "$this" replaced with a selector using our unique attribute. We can do this with a a */ .replace /* using the following regular expression */ (/\$this/g, /* and swapping each instance with */ '[data-' + /* our */ uniqueAttribute + '="' + /* our current matching tag */ count + '"]');

/* Third, we will increment the */ count++; /* of matching tags by 1. */

} /* This ends the three things we do to each tag passing the test. */

if /* we */ (test /* the current */ (tag) /* and the result is */ == /* to */ false) /* then we need to take the */ tag /* failing our test and */ .setAttribute /* equal to */ ('data-' + /* our */ uniqueAttribute, /* and remove any pre-existing value with */ '');

}) /* This ends the logic we run for each matching tag. */

/* The last thing we need to do is */ return /* all of our */ generatedCSS

} /* And this ends our container queries function */

The above code, run through uglifyjs and then prettier outputs the following JS code:

function containerQueries(selectorList, test, stylesheet) {
  var matchingTags = document.querySelectorAll(selectorList);
  var generatedCSS = new String();
  var count = 0;
  matchingTags.forEach(tag => {
    var uniqueAttribute = (selectorList + test).replace(/\W+/g, "");
    if (test(tag) == true) {
      tag.setAttribute("data-" + uniqueAttribute, count);
      generatedCSS =
        generatedCSS +
        stylesheet.replace(
          /\$this/g,
          "[data-" + uniqueAttribute + '="' + count + '"]'
        );
      count++;
    }
    if (test(tag) == false) tag.setAttribute("data-" + uniqueAttribute, "");
  });
  return generatedCSS;
}

And a short test of the plugin:

Click here for a slightly cleaner version of this plugin written in ES5 and ES6

And here's a flowchart of the logic:


4,045 0 11