@area17/a17-tailwind-plugins
Version:
A collection of Tailwind plugins to help build responsive design systems in collaboration with A17 design and development build methodologies
1,312 lines (1,146 loc) • 42.1 kB
HTML
---
title: Layout
---
{% include_relative includes/_header.html %}
<div class="copy">
<h2 id="description">Description</h2>
<p>This plugin creates classes to handle column layouts:</p>
<p>
Where <code>N</code> can be a number of columns, up to the largest amount of
columns defined or a fraction (<code>1/2</code>, <code>1/3</code>,
<code>1/4</code>, <code>2/3</code> or <code>3/4</code>)
</p>
<h3>
For use inside <code>.container</code> or a descendant of
<code>.container</code>
</h3>
<ul>
<li>
<strong><a href="#demo">Element width:</a></strong>
<ul>
<li>
<code>.w-cols-N</code> sets <code>width</code> to
<code>N</code> columns/fraction wide, if inside of
<code>.cols-container</code> also includes an inner gutter
<code>margin-left</code>
</li>
</ul>
</li>
<li class="mt-20">
<strong><a href="#flexed">Flex based grid</a></strong> <br>
<strong>🚨 deprecated in <code>v5.0.0</code></strong>
<ul>
<li>
<code>.cols-container</code> makes a container for columns,
<code>flex: row wrap</code> with a negative inner gutter
<code>margin-left</code>
</li>
<li>
<code>.ml-0</code> on child, resets <code>margin-left</code> to 0,
adds specificity to the class
</li>
</ul>
</li>
<li class="mt-20">
<strong><a href="#margins">Margins:</a></strong>
<ul>
<li>
<code>.ml-cols-N</code> on child, sets a <code>margin-left</code> of
<code>N</code> columns wide
</li>
<li>
<code>.mr-cols-N</code> on child, sets a <code>margin-right</code> of
<code>N</code> columns wide
</li>
<li>
<code>.mx-cols-N</code> on child, sets a <code>margin-right</code> and
<code>margin-left</code> of <code>N</code> columns wide
</li>
<li class="mt-20">
<code>.ml-cols-N</code> on child, sets a negative
<code>margin-left</code> of <code>N</code> columns wide
</li>
<li>
<code>.mr-cols-N</code> on child, sets a negative
<code>margin-right</code> of <code>N</code> columns wide
</li>
<li>
<code>.mx-cols-N</code> on child, sets a negative
<code>margin-right</code> and a negative <code>margin-left</code> of
<code>N</code> columns wide
</li>
<li class="mt-20">
<code>.ms-cols-N</code> on child, sets a
<code>margin-inline-start</code> of <code>N</code> columns wide
</li>
<li>
<code>.me-cols-N</code> on child, sets a
<code>margin-inline-end</code> of <code>N</code> columns wide
</li>
<li>
<code>.ms-cols-N</code> on child, sets a negative
<code>margin-inline-start</code> of <code>N</code> columns wide
</li>
<li>
<code>.me-cols-N</code> on child, sets a negative
<code>margin-inline-end</code> of <code>N</code> columns wide
</li>
</ul>
</li>
<li class="mt-20">
<strong><a href="#padding">Padding:</a></strong>
<ul>
<li>
<code>.pl-cols-N</code> on child, sets a <code>padding-left</code> of
<code>N</code> columns wide
</li>
<li>
<code>.pr-cols-N</code> on child, sets a <code>padding-right</code> of
<code>N</code> columns wide
</li>
<li>
<code>.px-cols-N</code> on child, sets a
<code>padding-right</code> and <code>padding-left</code> of
<code>N</code> columns wide
</li>
<li class="mt-20">
<code>.ps-cols-N</code> on child, sets a <code>padding-inline-start</code> of
<code>N</code> columns wide
</li>
<li>
<code>.pe-cols-N</code> on child, sets a <code>padding-inline-end</code> of
<code>N</code> columns wide
</li>
</ul>
</li>
<li class="mt-20">
<strong><a href="#positioning">Positioning:</a></strong>
<ul>
<li>
<code>.left-cols-N</code> sets <code>left</code> to
<code>N</code> columns
</li>
<li>
<code>.right-cols-N</code> sets <code>right</code> to
<code>N</code> columns
</li>
<li>
<code>.inset.x-cols-N</code> sets <code>left</code> and
<code>right</code> to <code>N</code> columns
</li>
<li class="mt-20">
<code>.left-cols-N</code> sets negative <code>left</code> to
<code>N</code> columns
</li>
<li>
<code>.right-cols-N</code> sets negative <code>right</code> to
<code>N</code> columns
</li>
<li>
<code>.-inset.x-cols-N</code> sets negative <code>left</code> and
negative <code>right</code> to <code>N</code> columns
</li>
<li class="mt-20">
<code>.start-cols-N</code> sets <code>inset-inline-start</code> to
<code>N</code> columns
</li>
<li>
<code>.end-cols-N</code> sets <code>inset-inline-end</code> to
<code>N</code> columns
</li>
<code>.start-cols-N</code> sets negative <code>inset-inline-start</code> to
<code>N</code> columns
</li>
<li>
<code>.end-cols-N</code> sets negative <code>inset-inline-end</code> to
<code>N</code> columns
</li>
</ul>
</li>
<li class="mt-20">
<strong><a href="#gutterless">gutter-less spacing</a></strong> variants:
<ul>
<li>
<code>.ml-cols-no-gutter-N</code> on child, sets a
<code>margin-left</code>of <code>N</code> columns wide minus an inner
gutter
</li>
<li>
<code>.mr-cols-no-gutter-N</code> on child, sets a
<code>margin-right</code> of <code>N</code> columns minus an inner
gutter
</li>
<li>
<code>.mx-cols-no-gutter-N</code> on child, sets a
<code>margin-right</code> and <code>margin-left</code> of
<code>N</code> columns minus an inner gutter
</li>
<li class="mt-20">
<code>.ml-cols-no-gutter-N</code> on child, sets a negative
<code>margin-left</code> of <code>N</code> columns wide minus an inner
gutter
</li>
<li>
<code>.mr-cols-no-gutter-N</code> on child, sets a negative
<code>margin-right</code> of <code>N</code> columns wide minus an
inner gutter
</li>
<li>
<code>.mx-cols-no-gutter-N</code> on child, sets a negative
<code>margin-right</code> and a negative <code>margin-left</code> of
<code>N</code> columns minus an inner gutter
</li>
<li class="mt-20">
<code>.ms-cols-no-gutter-N</code> on child, sets a
<code>margin-inline-start</code>of <code>N</code> columns wide minus an inner
gutter
</li>
<li>
<code>.me-cols-no-gutter-N</code> on child, sets a
<code>margin-inline-end</code> of <code>N</code> columns minus an inner
gutter
</li>
<li>
<code>.ms-cols-no-gutter-N</code> on child, sets a negative
<code>margin-inline-startt</code> of <code>N</code> columns wide minus an inner
gutter
</li>
<li>
<code>.me-cols-no-gutter-N</code> on child, sets a negative
<code>margin-inline-end</code> of <code>N</code> columns wide minus an
inner gutter
</li>
<li class="mt-20">
<code>.pl-cols-no-gutter-N</code> on child, sets a
<code>padding-left</code> of <code>N</code> columns minus an inner
gutter
</li>
<li>
<code>.pr-cols-no-gutter-N</code> on child, sets a
<code>padding-right</code> of <code>N</code> columns minus an inner
gutter
</li>
<li>
<code>.px-cols-no-gutter-N</code> on child, sets a
<code>padding-right</code> and <code>padding-left</code> of
<code>N</code> columns minus an inner gutter
</li>
<li class="mt-20">
<code>.ps-cols-no-gutter-N</code> on child, sets a
<code>padding-inline-start</code> of <code>N</code> columns minus an inner
gutter
</li>
<li>
<code>.pe-cols-no-gutter-N</code> on child, sets a
<code>padding-inline-end</code> of <code>N</code> columns minus an inner
gutter
</li>
<li class="mt-20">
<code>.left-cols-no-gutter-N</code> sets <code>left</code> to
<code>N</code> columns minus an inner gutter
</li>
<li>
<code>.right-cols-no-gutter-N</code> sets <code>right</code> to
<code>N</code> columns minus an inner gutter
</li>
<li>
<code>.inset.x-cols-no-gutter-N</code> sets <code>left</code> and
<code>right</code> to <code>N</code> columns minus an inner gutter
</li>
<li class="mt-20">
<code>.left-cols-no-gutter-N</code> sets negative
<code>left</code> to <code>N</code> columns minus an inner gutter
</li>
<li>
<code>.right-cols-no-gutter-N</code> sets negative
<code>right</code> to <code>N</code> columns minus an inner gutter
</li>
<li>
<code>.-inset.x-cols-no-gutter-N</code> sets negative
<code>left</code> and <code>right</code> to <code>N</code> columns
minus an inner gutter
</li>
<li class="mt-20">
<code>.start-cols-no-gutter-N</code> sets <code>inset-inline-start</code> to
<code>N</code> columns minus an inner gutter
</li>
<li>
<code>.end-cols-no-gutter-N</code> sets <code>inset-inline-end</code> to
<code>N</code> columns minus an inner gutter
</li>
<li>
<code>.start-cols-no-gutter-N</code> sets negative
<code>inset-inline-start</code> to <code>N</code> columns minus an inner gutter
</li>
<li>
<code>.end-cols-no-gutter-N</code> sets negative
<code>inset-inline-end</code> to <code>N</code> columns minus an inner gutter
</li>
</ul>
</li>
</ul>
<h3>
For use outside of <code>.container</code>, or <code>.breakout</code> or
some other width of container
</h3>
<ul>
<li>
<strong><a href="#vwvariants">viewwidth calc</a></strong> variants:
<ul>
<li>
<code>.*-vw</code> where <code>*</code> is any of the above classes,
eg: <code>.w-cols-vw-4</code>, <code>.mr-cols-vw-2</code> etc. useful
if your element's container is not
</li>
</ul>
</li>
</ul>
<p>
Each of these have tailwind responsive classes and all settings are
breakpoint+, <a href="#responsive">read about responsive usage</a>.
</p>
<p>
Nesting of elements is also possible,
<a href="#nesting">read about nesting usage</a>.
</p>
<h3 id="v5-0-0">Breaking changes in <code>v5.0.0</code></h3>
<p>The format of the class names has been updated and <code>.cols-container</code> was deprecated in <code>v5.0.0</code></p>
<p>Before <code>v5.0.0</code> class names came in the format <code>.w-N-cols</code> - CSS attr, number of columns then <code>-cols/-cols-vw/-cols-no-gutter</code>.</p>
<p>From <code>v5.0.0</code> onwards, class names will come in an updated format of <code>.w-cols-N</code> - CSS attr, <code>-cols/-cols-vw/-cols-no-gutter</code> and lastly the number of columns. This change was necessary as Tailwind <code>v4.0.0</code> changes the undocumented rules on how Plugins are generated and our old method was no longer compatible.</p>
<small>:troll perhaps we should have stuck with our pre <code>v3.0.0</code> names...</small>
<h4>Migrating to <code>v5.0.0</code> from <code>v4.x.x/v3.x.x</code></h4>
<p>
If you're ok with doing some regex, its possible to transition to
<code>v5.0.0</code> by:
</p>
<ol>
<li>Search for <code>(\w*)-(\d\/\d|\d*)-cols(-no-gutter|-vw)?</code></li>
<li>Replace with <code>$1-cols$3-$2</code></li>
</ol>
<p>And for any fraction class usage:</p>
<ol>
<li>Search for <code>(\w*)-(\d\/\d)-cols</code></li>
<li>Replace with <code>$1-cols-$2</code></li>
</ol>
<h2 id="setup">Setup</h2>
<figure class="code-example">
<figcaption class="code-example-filename">tailwind.config.js</figcaption>
<pre
class="code-example-code"
><code class="language-javascript">const { Setup, Layout } = require('@area17/a17-tailwind-plugins');
module.exports = {
...
plugins: [Setup, Layout],
theme: {
screens: {
xs: "0",
sm: "544px",
md: "650px",
lg: "990px",
xl: "1300px",
xxl: "1520px"
},
mainColWidths: {
xs: "auto",
sm: "auto",
md: "auto",
lg: "auto",
xl: "auto",
xxl: "1440px"
},
innerGutters: {
xs: "10px",
sm: "15px",
md: "20px",
lg: "30px",
xl: "40px",
xxl: "40px"
},
outerGutters: {
xs: "20px",
sm: "30px",
md: "40px",
lg: "40px",
xl: "40px",
xxl: "0px"
},
columnCount: {
xs: "4",
sm: "4",
md: "8",
lg: "12",
xl: "12",
xxl: "12"
},
}
...
};</code></pre>
</figure>
<p>
Requires <code>Setup</code> plugin with <code>theme.screens</code>,
<code>theme.mainColWidths</code>, <code>theme.innerGutters</code>,
<code>theme.outerGutters</code> and
<code>theme.columnCount</code> configured.
</p>
<h2 id="demo">Demo</h2>
<h3 class="number">Using number of desired columns</h3>
<p>Basic usage of the <code>.w-cols-N</code> classes:</p>
</div>
<div class="show-grid">
<div class="w-cols-1 h-40 bg-column mt-20">w-cols-1</div>
<div class="w-cols-2 h-40 bg-column mt-20">w-cols-2</div>
<div class="w-cols-3 h-40 bg-column mt-20">w-cols-3</div>
<div class="w-cols-4 h-40 bg-column mt-20">w-cols-4</div>
<div class="w-cols-5 h-40 bg-column mt-20">w-cols-5</div>
<div class="w-cols-6 h-40 bg-column mt-20">w-cols-6</div>
<div class="w-cols-7 h-40 bg-column mt-20">w-cols-7</div>
<div class="w-cols-8 h-40 bg-column mt-20">w-cols-8</div>
<div class="w-cols-9 h-40 bg-column mt-20">w-cols-9</div>
<div class="w-cols-10 h-40 bg-column mt-20">w-cols-10</div>
<div class="w-cols-11 h-40 bg-column mt-20">w-cols-11</div>
<div class="w-cols-12 h-40 bg-column mt-20">w-cols-12</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-1"></div>
<div class="w-cols-2"></div>
<div class="w-cols-3"></div>
<div class="w-cols-4"></div>
<div class="w-cols-5"></div>
<div class="w-cols-6"></div>
<div class="w-cols-7"></div>
<div class="w-cols-8"></div>
<div class="w-cols-9"></div>
<div class="w-cols-10"></div>
<div class="w-cols-11"></div>
<div class="w-cols-12"></div></code></pre>
</figure>
<p>
As the plugin reads the config, it works out the maximum amount of columns
it needs - so if your smallest breakpoint has 4 design columns and the
largest has 12 - then it will create classes <code>.w-cols-1</code> through
<code>.w-cols-12</code>.
</p>
<h3 class="fraction">Using a fraction</h3>
<p>
Sometimes you want a simpler layout scheme, using %ages of the container
width rather than column numbers, but still taking into account the inner
gutters. For this you can use fractions.
</p>
<p>
Fractions can be any of <code>1/2</code>, <code>1/3</code>,
<code>1/4</code>, <code>2/3</code> or <code>3/4</code>.
</p>
<p>
<strong>Note</strong> Fractions are consistent across all breakpoints. So,
<code>1/2</code> will be 50% minus some inner gutter on all breakpoints set,
unlike setting via columns whose apparent width will change if the total
number of design columns at a breakpoint changes.
</p>
</div>
<div class="show-grid">
<div class="w-cols-1/4 h-40 bg-column mt-20">w-cols-1/4</div>
<div class="w-cols-1/3 h-40 bg-column mt-20">w-cols-1/3</div>
<div class="w-cols-1/2 h-40 bg-column mt-20">w-cols-1/2</div>
<div class="w-cols-2/3 h-40 bg-column mt-20">w-cols-2/3</div>
<div class="w-cols-3/4 h-40 bg-column mt-20">w-cols-3/4</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-1/4 h-40 bg-column mt-20"></div>
<div class="w-cols-1/3 h-40 bg-column mt-20"></div>
<div class="w-cols-1/2 h-40 bg-column mt-20"></div>
<div class="w-cols-2/3 h-40 bg-column mt-20"></div>
<div class="w-cols-3/4 h-40 bg-column mt-20"></div></code></pre>
</figure>
<hr />
<h3 id="responsive">Responsive</h3>
<p>
If you use <code>w-cols-10</code> and your smallest breakpoint only has 4
design columns then you may also want to use <code>max-w-full</code> to stop
a container being wider than 100%. Or better, use <code>w-cols-4</code> and
<code>lg:w-cols-10</code>.
</p>
<p>
Which will be 4 design columns wide until the <code>lg</code> breakpoint,
when it will become 10 columns wide:
</p>
</div>
<div class="show-grid">
<div class="w-cols-4 lg:w-cols-10 h-40 bg-column mt-20">
w-cols-4 lg:w-cols-10
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-4 lg:w-cols-10"></div></code></pre>
</figure>
<p>And of course, can assign different sizes at all of your breakpoints:</p>
</div>
<div class="show-grid">
<div
class="w-cols-4 sm:w-cols-3 md:w-cols-6 lg:w-cols-10 xl:w-cols-8 xxl:w-cols-6 h-40 bg-column mt-20"
>
w-cols-4 sm:w-cols-3 md:w-cols-6 lg:w-cols-10 xl:w-cols-8 xxl:w-cols-6
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-4 sm:w-cols-3 md:w-cols-6 lg:w-cols-10 xl:w-cols-8 xxl:w-cols-6"></div></code></pre>
</figure>
<p>
As previously mentioned, fractions will be consistent on all breakpoints.
They can of course be changed per breakpoint:
</p>
</div>
<div class="show-grid">
<div
class="w-cols-3/4 md:w-cols-1/2 lg:w-cols-2/3 xl:w-cols-1/2 h-40 bg-column mt-20"
>
w-cols-3/4 md:w-cols-1/2 lg:w-cols-2/3 xl:w-cols-1/2
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-3/4 md:w-cols-1/2 lg:w-cols-2/3 xl:w-cols-1/2 h-40 bg-column mt-20"></div></code></pre>
</figure>
<hr />
<h3 id="nesting">Nesting</h3>
<p>When using a <code>N</code> number of columns, you can nest elements:</p>
</div>
<div class="show-grid">
<div class="w-cols-10 xl:w-cols-8 h-120 bg-column mt-20 py-20">
<div class="w-cols-6 h-80 bg-column-alt py-20">
<div class="w-cols-4 h-40 bg-column">
w-cols-4 inside w-cols-6 inside w-cols-8
</div>
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-10 xl:w-cols-8 h-120 bg-column mt-20 py-20">
<div class="w-cols-6 h-80 bg-column-alt py-20">
<div class="w-cols-4 h-40 bg-column">8</div>
</div>
</div></code></pre>
</figure>
<h4>Warning - Nesting Fractional Columns</h4>
<p>
Nesting fractions inside fractions will work, but instead halving the
breakpoint's total columns, you'll the containers total columns. And so, if
you have 12 design columns and you insert <code>w-cols-1/2</code> inside
<code>w-cols-1/2</code>, you'll get one 6 design column wide element
wrapping a 3 design column wide element:
</p>
</div>
<div class="show-grid">
<div class="w-cols-1/2 h-80 bg-column-alt mt-20 py-20">
<div class="w-cols-1/2 h-40 bg-column">w-cols-1/2 inside w-cols-1/2</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-1/2">
<div class="w-cols-1/2"></div>
</div></code></pre>
</figure>
<h4>
Warning - Mixing and matching fractional and <code>N</code> cols widths
</h4>
<p>
Mixing and matching <code>N</code> cols widths and fractional widths when
nesting may give you unexpected results. A fraction as a child of a
<code>N</code> cols width will work as expected:
</p>
</div>
<div class="show-grid">
<div class="w-cols-8 h-80 bg-column-alt mt-20 py-20">
<div class="w-cols-1/2 h-40 bg-column">w-cols-1/2 inside w-cols-8</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-8">
<div class="w-cols-1/2"></div>
</div></code></pre>
</figure>
<p>
<strong>But</strong>, placing a <code>N</code> cols widths inside a
fractional width column <strong>will not work</strong> as fractional widths
work cross breakpoint regardless of column count and so don't set/reset the
columns total inside themselves. In this scenario, the <code>N</code> cols
width assumes the fractional width column container has total columns at
that breakpoint. So, if you have 12 design columns and you set a
<code>w-cols-3</code> inside of <code>w-cols-1/2</code>, you'll end up with
a 1.5 column wide child column:
</p>
</div>
<div class="show-grid">
<div class="w-cols-1/2 h-80 bg-column-alt mt-20 py-20">
<div class="w-cols-3 h-40 bg-column">w-cols-3 inside w-cols-1/2</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-1/2 h-80">
<div class="w-cols-3 h-40"></div>
</div></code></pre>
</figure>
<p>
You end up with a 1.5 wide column in that example because 3/12 columns is
1/4 of the total columns, the fractional 1/2 shrinks the 12 columns to fit
in a 6 col wide contaner, 1/4 of 6 is 1.5.
</p>
<hr />
<h3 id="grid">Compatibility with <code>GridLayout</code> plugin</h3>
<p>
As both plugins use the same set of <code>:root</code> variables, they can
be nested inside of each other:
</p>
</div>
<div class="show-grid">
<div class="w-cols-8 bg-column mt-20">
<div class="grid-layout">
<div class="grid-col-span-2 h-40 bg-column-alt"></div>
<div class="grid-col-span-3 h-40 bg-column-alt"></div>
<div class="grid-col-span-1 h-40 bg-column-alt"></div>
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="w-cols-8">
<div class="grid-layout">
<div class="grid-col-span-2"></div>
<div class="grid-col-span-3"></div>
<div class="grid-col-span-1"></div>
</div>
</div></code></pre>
</figure>
<hr />
<h3 id="flexed">Inside <code>.cols-container</code></h3>
<p>
🚨 <strong>Note:</strong> deprecated in <code>v5.0.0</code>.
</p>
<p>
Previously we used <code>.cols-container</code>, which added a left gutter and some auto margins because support for <code>gap</code> with <code>flex</code> layouts was poor. But this isn't the case in 2024 and so we no longer recommend using <code>.cols-container</code>.
</p>
<p>
If you want to make layout grids, using flex as opposed to CSS Grid, use <code>flex gap-gutter</code>:
</p>
</div>
<div class="show-grid">
<div class="flex gap-gutter mt-20">
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex gap-gutter">
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
</div></code></pre>
</figure>
<p>
For legacy usage of <code>.cols-container</code>:
</p>
</div>
<div class="show-grid">
<div class="cols-container mt-20">
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-1 h-40 bg-column"></div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="cols-container">
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
<div class="w-cols-1"></div>
</div></code></pre>
</figure>
<p>
<code>.cols-container</code> has a negative gutter margin left.
<br />Fractions, responsive and nesting works within
<code>.cols-container</code>.
</p>
<p>
If you need to zero out the margin left for some reason, you can use
<code>ml-0</code>:
</p>
</div>
<div class="show-grid">
<div class="cols-container mt-20">
<div class="w-cols-1 h-40 bg-column"></div>
<div class="w-cols-2 ml-0 h-40 bg-column-alt"></div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="cols-container">
<div class="w-cols-1"></div>
<div class="w-cols-2 ml-0"></div>
</div></code></pre>
</figure>
<p>
(<code>ml-0</code> is essentially Tailwind's <code>ml-0</code> but with a
child relationship selector to add weight to the selector)
</p>
<hr />
<h3 id="margins">Margins</h3>
<p>
Classes for <code>.ml-</code>, <code>.mr-</code> and <code>.mx-</code>, and
their negative equivalents (<code>.-ml-</code>, <code>.-mr-</code>,
<code>.-mx-</code>) are also generated.
</p>
<p>
From <code>3.10.0</code>, <code>ms-</code> and <code>me-</code> classes and
their negative equivalents <code>-ms-</code> and <code>-me-</code> are also
generated (using CSS <code>margin-inline-start</code> and
<code>margin-inline-end</code>).
</p>
</div>
<div class="show-grid">
<div class="flex gap-gutter mt-20">
<div class="w-cols-1 ml-cols-2 h-40 bg-column"></div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex gap-gutter">
<div class="w-cols-1 ml-cols-2"></div>
</div></code></pre>
</figure>
<p>
If your content is aligned right, say with <code>justify-end</code> and you
want to push items away from the right, you can use <code.mr-cols-N</code>:
</p>
</div>
<div class="show-grid">
<div class="flex flex-row justify-end">
<div class="w-cols-1 mr-cols-1 h-40 bg-column"></div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex flex-row justify-end">
<div class="w-cols-1 mr-cols-1 h-40 bg-column"></div>
</div></code></pre>
</figure>
<p>
You can also push by fractions, which by their design, account for gutters:
</p>
</div>
<div class="show-grid">
<div class="flex flex-row mt-20">
<div class="w-cols-1/3 ml-cols-2/3 h-40 bg-column">
w-cols-1/3 ml-cols-2/3
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex flex-row">
<div class="w-cols-1/3 ml-cols-2/3"></div>
</div></code></pre>
</figure>
<p>And, within <code>.cols-container</code>:</p>
</div>
<div class="show-grid">
<div class="cols-container mt-20">
<div class="w-cols-1/2 h-40 bg-column">
w-cols-1/2
</div>
<div class="w-cols-1/4 h-40 bg-column">
w-cols-1/4
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="cols-container">
<div class="w-cols-1/2"></div>
</div>
<div class="w-cols-1/4"></div>
</div>
</code></pre>
</figure>
<p>
New in <code>3.10.0</code>, <code>margin-inline-start</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/margin-inline-start"
target="_blank"
>MDN</a
>) and <code>margin-inline-end</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/margin-inline-end"
target="_blank"
>MDN</a
>) with <code.ms-cols-N</code> and <code.me-cols-N</code>:
</p>
</div>
<div class="show-grid">
<div class="flex flex-row mt-20">
<div class="w-cols-4 ms-cols-2 h-40 bg-column">w-cols-4 ms-cols-2</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex flex-row mt-20">
<div class="w-cols-4 ms-cols-2"></div>
</div></code></pre>
</figure>
</div>
<div class="show-grid">
<div class="flex flex-row mt-20">
<div class="w-cols-4 ml-auto me-cols-2 h-40 bg-column">
w-cols-4 ml-auto me-cols-2
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex flex-row mt-20">
<div class="w-cols-4 ml-auto me-cols-2"></div>
</div></code></pre>
</figure>
<h3 id="padding">Padding</h3>
<p>
Much like margins, padding classes are also generated: <code>.pl-</code>,
<code>.pr-</code> and <code>.px-</code>
</p>
<p>
From <code>3.10.0</code>, <code>ps-</code> and <code>pe-</code> classes are
also generated (using CSS <code>padding-inline-start</code> and
<code>padding-inline-end</code>).
</p>
</div>
<div class="show-grid">
<div class="pl-cols-2 pr-cols-4 bg-column-alt h-80 pt-20 mt-20">
<div class="bg-column h-40">100% wide inside of pl-cols-2 pr-cols-4</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="pl-cols-2 pr-cols-4">
<div></div>
</div></code></pre>
</figure>
<p>
Padding and nesting do not mix very well, as the padded amount isn't
accounted for in the width calc. Fractional widths will still align to the
grid:
</p>
</div>
<div class="show-grid">
<div class="pl-cols-2 bg-column-alt h-80 pt-20 mt-20">
<div class="w-cols-1/2 bg-column h-40">w-cols-1/2 inside of pl-cols-2</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="pl-cols-2">
<div class="w-cols-1/2"></div>
</div></code></pre>
</figure>
<p>
In our 12 design columm grid, padding the left by 2 columns leaves 10
columns, 1/2 of 10 is 5 and so the child div in the example above is 5
design columns wide.
</p>
<p>
New in <code>3.10.0</code>, <code>padding-inline-start</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/padding-inline-start"
target="_blank"
>MDN</a
>) and <code>padding-inline-end</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/padding-inline-end"
target="_blank"
>MDN</a
>) with <code.ps-cols-N</code> and <code.pe-cols-N</code>:
</p>
</div>
<div class="show-grid">
<div class="ps-cols-2 pe-cols-4 bg-column-alt h-80 pt-20 mt-20">
<div class="bg-column h-40">100% wide inside of ps-cols-2 pe-cols-4</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="ps-cols-2 pe-cols-4">
<div></div>
</div></code></pre>
</figure>
<hr />
<h3 id="positioning">Positioning</h3>
<p>
You can also <code>.left-cols-N</code>, <code>.left-cols-N-gutter</code>,
<code>.right-cols-N</code> and <code>.right-cols-N-gutter</code> for
<code>position: absolute;</code> type positioning (or maybe with
<code>position: relative;</code> depending on your use case).
</p>
<p>
From <code>3.10.0</code>, <code>start-</code> and <code>end-</code> classes
and their negative equivalents <code>-start-</code> and
<code>-end-</code> are also generated (using CSS
<code>inset-inline-start</code> and <code>inset-inline-end</code>).
</p>
<p>
Fractions and responsive work as expected and nesting will work, if you
apply a <code.w-cols-N</code> class.
</p>
</div>
<div class="show-grid">
<div class="relative h-96 mt-20">
<div class="w-cols-3 h-40 bg-column absolute top-0 left-cols-1">
w-cols-3 left-cols-1
</div>
<div class="w-cols-1/3 h-40 bg-column absolute top-56 left-cols-1/3">
w-cols-1/3 left-cols-1/3
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="relative h-96 mt-20">
<div class="w-cols-3 h-40 bg-column absolute top-0 left-cols-1">w-cols-3 left-cols-1</div>
<div class="w-cols-1/3 h-40 bg-column absolute top-56 left-cols-1/3">w-cols-1/3 left-cols-1/3</div>
</div></code></pre>
</figure>
<p>Push and pull classes, with or without gutters, will also work:</p>
</div>
<div class="show-grid">
<div class="relative h-100 mt-20">
<div class="w-cols-2 h-40 bg-column absolute top-0 left-0 ml-cols-2">
left-0 ml-cols-2
</div>
<div class="w-cols-2 h-40 bg-column absolute top-60 right-0 mr-cols-2">
right-0 mr-cols-2
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="relative h-80">
<div class="w-cols-2 h-40 bg-column absolute top-0 left-0 ml-cols-2"></div>
<div class="w-cols-2 h-40 bg-column absolute top-40 right-0 mr-cols-2"></div>
</div></code></pre>
</figure>
<p>
New in <code>3.10.0</code>, <code>inset-inline-start</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-start"
target="_blank"
>MDN</a
>) and <code>inset-inline-end</code> (<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-end"
target="_blank"
>MDN</a
>) with <code.start-cols-N</code> and <code.end-cols-N</code>:
</p>
</div>
<div class="show-grid">
<div class="relative h-80 mt-20">
<div class="w-cols-2 h-40 bg-column absolute top-0 start-cols-2">
start-cols-2
</div>
<div class="w-cols-2 h-40 bg-column absolute top-40 end-cols-4">
end-cols-4
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="relative h-80">
<div class="w-cols-2 absolute top-0 start-cols-2"></div>
<div class="w-cols-2 absolute top-40 end-cols-4"></div>
</div></code></pre>
</figure>
<h2 id="gutterless">Gutter-less classes</h2>
<p>
Margin, padding and positioning classes also have gutter-less versions. That
is, you can position things to the edge of the preceding column rather than
the following column:
</p>
</div>
<div class="show-grid">
<div class="flex gap-gutter mt-20">
<div class="w-cols-3 ml-cols-no-gutter-2 h-40 bg-column">
w-cols-3 ml-cols-no-gutter-2
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="flex gap-gutter">
<div class="w-cols-3 ml-cols-no-gutter-2"></div>
</div></code></pre>
</figure>
<h2 id="vwvariants"><code>vw</code> calc variants</h2>
<p>
Regular layout classes <code>w-cols-3</code> use a CSS
<code>calc()</code> based on <code>100%</code> container width and a
<code>--grid-columns</code> variable to split the container width as
required.
</p>
<p>
Sometimes, you might need to set an element on the grid, where you container
is some other width, such as inside <code>.breakout</code>'s or perhaps
inside a carousel. In these case the standard <code>w-cols-3</code> type
classes may not work, and you may need to use <code>vw</code> based
alternatives.
</p>
</div>
<div class="show-grid">
<div class="breakout mt-20">
<div class="w-cols-4 mx-auto bg-column">
<p>using <code>w-cols-4</code> ❌ - too wide</p>
</div>
<div class="w-cols-vw-4 mx-auto bg-column mt-20">
<p>using <code>w-cols-vw-4</code> ✅ - on grid</p>
</div>
</div>
</div>
<div class="copy">
<figure class="code-example">
<figcaption class="code-example-filename">document.html</figcaption>
<pre
class="code-example-code"
><code class="language-html"><div class="breakout">
<div class="w-cols-4 ml-outer-gutter">
<p>using <code>w-cols-4</code> ❌ - too wide</p>
</div>
<div class="w-cols-vw-4 ml-outer-gutter">
<p>using <code>w-cols-vw-4</code> ✅ - on grid</p>
</div>
</div></code></pre>
</figure>
<p>
<code>w-cols-4</code> draws the <code>div</code> too wide, as the parent
container is wider than <code>.container</code>. The suffix of
<code>-vw</code> alters the calc to base the calcs off of
<code>100vw</code>.
</p>
<p>But, to make this work, we need to account for the scroll bar width.</p>
<h3 id="scrollbarwidth">
Additional set up for working with gutters inside <code>.breakout</code>
</h3>
<p>
The <code>.*-vw</code> type classes uses <code>100vw</code> as its base,
which, frustratingly is likely wider than the document as the document can
take up <code>100vw</code> minus the scroll bar width. So, to use
<code>.*-vw</code> type classes, we need to account for the scrollbar width:
</p>
<figure class="code-example">
<figcaption class="code-example-filename">application.js</figcaption>
<pre
class="code-example-code"
><code class="language-javascript">const scrollbox = document.createElement('div');
scrollbox.style.overflow = 'scroll';
document.body.appendChild(scrollbox);
// Compare inner and out widths of the box to determine scroll bar width
const scrollBarWidth = scrollbox.offsetWidth - scrollbox.clientWidth;
document.body.removeChild(scrollbox);
document.documentElement.style.setProperty('--scrollbar-width', `${ scrollBarWidth }px`);
// test is scroll bar is visible
function setScrollBarVisible() {
const scrollBarVisible = document.documentElement.scrollHeight > document.documentElement.clientHeight;
const overflowYSet = window.getComputedStyle(document.documentElement, null).getPropertyValue('overflow-y') === 'scroll';
document.documentElement.style.setProperty('--scrollbar-visible-width', `${ scrollBarVisible || overflowYSet ? scrollBarWidth : 0 }px`);
}
window.addEventListener('load', setScrollBarVisible, false);
window.addEventListener('resized', setScrollBarVisible, false);
setScrollBarVisible();</code></pre>
</figure>
<p>
This also makes sure the <code>.p?-outer-gutter</code> type
<a href="./Container.html">Breakout</a> classes (<code>.w-cols-vw-2</code>,
<code>.ml-cols-vw-2</code> etc.) will work correctly inside of
<code>.breakout</code> type content.
</p>
</div>
{% include_relative includes/_footer.html %}