Layouts
The CSS Grid
Basic structure
The Mohunky HTML/CSS framework (v7) is a Flexbox based adaptive column layout.
The basic structure is as follows:
<main id="p_viewName">
<section id="sectionOneName">
<div class="container">
<div class="row">
<div class="col">.col</div>
<div class="col">.col</div>
<div class="col">.col</div>
<div class="col">.col</div>
</div>
</div>
</section>
<section id="sectionTwoName">
<div class="container">
<div class="row">
<div class="col">.col</div>
<div class="col">.col</div>
</div>
</div>
</section>
</main>
Which renders like this:
.col
.col
.col
.col
.col
.col
Lets break that down
Main
The <main>
wraps everything on a given view, separating it from any surrounding headers, sidebars and footers. Give this element an ID to target the view using CSS/JS and to help out any other developer.
If you want the whole view to have a background colour or image, stick some classes on this element.
Section
Each <section>
is generally a full width block. Giving each section a contextual ID will help you and other developers navigate the view. The ID's' can also be used to jump the end-user to a section and apply any unique CSS/JS.
If you want to apply background colours, extra padding or anything along those lines, stick a couple of classes on the <section>
.
Container
The <div class="container">
constrains the width of the content in this section. Normally to a max-width of 1220px but there are some utility classes to adjust this, for instance .container.wide
sets the max-width to 1920px or .container.widest
removes the maximum width.
Row
The <div class="row">
comes next and as you can see it's possible to have multiple .row
's within a container.
As the class name implies, these set out a row of columns. Although columns will break onto their own "row" if thye run out of room. So think of a row as another container for separating groups of columns.
Column
Now we're into the final level element. <div class="col">
's. If you only apply the .col
class and stack a few within a row, they will equally divide the available space.
Defining column widths
To control the width, you'll want to apply a .span#
class alongside each .col
.
(# being = to the number of columns you want it to "span"... hence the class name.)
We have the following number of columns to work with at each breakpoint:
Breakpoint | Columns |
---|---|
Desktop 1,400px and over | 12 columns |
Laptop (Large) 1,201px to 1,400px | 12 columns |
Laptop (Small) 1,001px to 1,200px | 12 columns |
Tablet (Large) 801px to 1,000px | 8 columns |
Tablet (Small) 601px to 800px | 6 columns |
Mobile (Large) 401px to 600px | 4 columns |
Mobile (Small) Under 400px | 2 columns |
So if we want a 2 thirds / 1 third split layout we'd add a .span8
and .span4
as follows:
<main id="p_viewName">
<section id="sectionName">
<div class="container">
<div class="row">
<div class="col span8"></div>
<div class="col span4"></div>
</div>
</div>
</section>
</main>
Which renders like this:
.col.span8
.col.span4
Manipulating Columns
At this point the system isn't actually using a 12 column grid, it's more freeform. If left like this, columns would always equalise. Two columns would share the row 50/50, four would be 25% each and so on. To break out of this we can start adding .span#
classes to the <div class="col">
's. This column for instance is <div class="col .span9">
. (It's also centred, again breaking the 12 column grid, but more on that later.)
Defining the column widths using the above example:
<section id="sectionOne">
<div class="container">
<div class="row">
<div class="col span6">.col</div>
<div class="col span2">.col</div>
<div class="col span2">.col</div>
<div class="col span2">.col</div>
</div>
</div>
</section>
<section id="sectionTwo">
<div class="container">
<div class="row">
<div class="col span8">.col</div>
<div class="col span4">.col</div>
</div>
</div>
</section>
Giving us the following:
.col .span6
.col .span2
.col .span2
.col .span2
.col .span8
.col .span4
Offsetting Columns
Lets say you want to align a column with the row above but you don't need the row aboves left most column. In this case you need to offset the column by the width of the column you're removing, thats a really confusing way to describe what will make a lot more sense if you just look at the example below.
<div class="row">
<div class="col demo span2"><code>.col.span2</code></div>
<div class="col demo span6"><code>.col.span6</code></div>
<div class="col demo span4"><code>.col.span4</code></div>
</div>
<div class="row">
<div class="col demo span6 offset2"><code>.col.span6.offset2</code></div>
</div>
And that renders a little something like this:
.col.span2
.col.span6
.col.span4
.col.span6
Centering Columns
It's very common to need to center columns, in both directions. For horizontal centering, if you're using the 12 column grid and columns who's total width add up to an even number. You can offset the first column by half the remaining width to center them all.
Example:
<div class="row">
<div class="col span2 demo"><code>.col.span2</code></div>
<div class="col span2 demo"><code>.col.span2</code></div>
<div class="col span2 demo"><code>.col.span2</code></div>
</div>
.col.span2
.col.span2
.col.span2
Or do it the easy way
However, if you're using an number of columns who's width add up to an odd number, or if you just want an easier way to do it, then just stick .hCenter
on the parent .row
.
Example:
<div class="row hCenter">
<div class="col span2 demo"><code>.col.span2</code></div>
<div class="col span2 demo"><code>.col.span2</code></div>
<div class="col span2 demo"><code>.col.span2</code></div>
</div>
.col.span2
.col.span2
.col.span2
You can even break out of the grid
You might not need to do this very often, but its another quick and easy tool at your disposal. This explainer is breaking the grid. The example below shows 12 single width columns and a centred column breaking the grid. I'm sure you dont need to see the HTML at this point.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
.col.span9 centered
.col.span3 centered
.col.span3 centered
.col.span3 centered
.col.span7 centered
And lastly, vertical centering
And probably most commonly needed in a grid system. Vertical centering, I bet you've guessed it, stick .vCenter
on the parent .row
.
Example:
<div class="row vCenter">
<div class="col span4 demo"><code>.col.span4</code>Lorem Ipsum...</div>
<div class="col span8 demo"><code>.col.span8</code></div>
</div>
.col.span4
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing vitae proin sagittis nisl. Adipiscing elit duis tristique sollicitudin. Eu ultrices vitae auctor eu augue ut lectus arcu. Tristique risus nec feugiat in fermentum posuere urna.
.col.span8
To align the colmns to their bottom, add .vBottom
on the parent .row
.
Example:
<div class="row vBottom">
<div class="col span4 demo"><code>.col.span4</code>Lorem Ipsum...</div>
<div class="col span8 demo"><code>.col.span8</code></div>
</div>
.col.span4
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing vitae proin sagittis nisl. Adipiscing elit duis tristique sollicitudin. Eu ultrices vitae auctor eu augue ut lectus arcu. Tristique risus nec feugiat in fermentum posuere urna.
.col.span8
Nesting Rows and Columns
More .row
's and .col
's can be nested within one another to give extra flexibility.
Using the same example again:
<section id="sectionOne">
<div class="container">
<div class="row">
<div class="col span6">.col</div>
<div class="col span2">.col</div>
<div class="col span2">.col</div>
<div class="col span2">.col</div>
</div>
</div>
</section>
<section id="sectionTwo">
<div class="container">
<div class="row">
<div class="col span8">
.col .span8
<div class="row pdTop1">
<div class="col span8">.span8</div>
<div class="col span4">.span4</div>
</div>
</div>
<div class="col span4">
.col .span4
<div class="row pdTop1">
<div class="col span6">.span6</div>
<div class="col span6">.span6</div>
</div>
</div>
</div>
</div>
</section>
Giving us the following:
.col .span6
.col .span2
.col .span2
.col .span2
.col .span8
.span8
.span4
.col .span4
.span6
.span6
And that'll about wrap up the basics.
Back to the topResponsive
If you're a "mobile first" person, take a long walk off a short pier. Every device and breakpoint should be considered equally, however we start with big screens and work down. If you start small with no consideration of the big picture you are going to trip yourself up! So start with the big picture and trim back. That's a rant for another day. Now that's out the way, everything to do with a specific breakpoint has a short 3-letter prefix as seen in the table below. The table also shows when those breakpoints occur
Note:- Although I've listed an pixel range, we leverage inheritance so if you've applied something at .tbs
it'll also apply to .mbl
and .mbs
.
Equivalent | Class Prefix | Viewport Widths | Container Width |
---|---|---|---|
Desktop | 1920px and bigger | See Basics above | |
Laptop | .lap |
1270px to 1025px | 960px |
Tablet Large | .tbl |
1024px to 811px | 760px |
Tablet Small | .tbs |
810px to 601px | 540px |
Mobile Large | .mbl |
600px to 401px | 100% / Fluid |
Mobile Small | .mbs |
400px and smaller | 100% / Fluid |
Using these prefixes
For instance, if you want to switch a column from .span6
to being full width on smaller tablet devices you'd add .tbsSpan12
. Giving a full class string of class="col span6 tbsSpan12"
.
.span6.tbsSpan12
.span6.tbsSpan12
Offseting columns at breakpoints
Just like with .span
's, stick a prefix onto any of the 12 offset classes to change an offset at that breakpoint.
Note:- There's also an .offset0
for all but desktop breakpoints.
Example:
<div class="row">
<div class="col demo span2"><code>.col.span2</code></div>
<div class="col demo span2"><code>.col.span2</code></div>
<div class="col demo span6"><code>.col.span6</code></div>
</div>
<div class="row">
<div class="col demo span6 offset2 lapOffset4"><code>.col.span6.offset2.ll-offset4</code></div>
</div>
.col.span2
.col.span2
.col.span6
.col.span6.offset2.ll-offset4
Display and Visibility
OH MY FERKING GAWD the dreaded display:none;
. Get over yourself! Ready to move on?
Sometimes a bit of content needs hiding on smaller devices. It's just not needed / relevant or in the worst case you have to render if completely different for mobiles.
In that case we have several helper classes that use the prefixes already meantioned above.
None | Block | Inline-block | Flex | |
---|---|---|---|---|
Desktop | .dispNone |
.dispBlock |
.dispInlBlck |
.dispFlex |
Laptop | .lapDispNone |
.lapDispBlock |
.lapDispInlBlck |
.lapDispFlex |
Tablet Large | .tblDispNone |
.tblDispBlock |
.tblDispInlBlck |
.tblDispFlex |
Tablet Small | .tbsDispNone |
.tbsDispBlock |
.tbsDispInlBlck |
.tbsDispFlex |
Mobile Large | .mblDispNone |
.mblDispBlock |
.mblDispInlBlck |
.mblDispFlex |
Mobile Small | .mbsDispNone |
.mbsDispBlock |
.mbsDispInlBlck |
.mbsDispFlex |
Remember these inherit downwards so revealing content at Tablet Small using .dispNone.tbsDispBlock
would have it visible at Mobile Large and Mobile Small. Similarly hiding something at Tablet Small with .tbsDispNone
would again hide it at both Mobile sizes.
One of the most common uses for this is shortening long form dates to better fit on mobile devices so in the most convoluted example so far:
<p>
<span class="mblDispNone">
Fri<span class="lapDispNone">day</span>
18 Dec<span class="tblDispNone">ember</span>
<span class="tbsDispNone">20</span><span class="dispNone tbsDispInlBlck">'</span>20
</span>
<span class="dispNone mblDispInlBlck">18/12/20</span>
</p>
Friday 18 December 20'20 18/12/20
Reordering Content
It's not very often but sometimes we find the need to reoder content at different breakpoints. That left sidebar thats kinda handy on Desktop but just a pain in the ass for Mobile users? Reorder it using something like .mbsOrder2
, get it out of the way (and then maybe even collapse it or do something else fancy).
Since you can't really, and probably won't need more than 12 columns in any one row, we've got .order1
through to .order12
and they each have their breakpoint prefixes.
Example:
<div class="row">
<div class="col demo lapOrder6 tblOrder5 tbsOrder3 mblOrder3 mbsOrder2">Col 1</div>
<div class="col demo lapOrder1 tblOrder6 tbsOrder5 mblOrder4 mbsOrder3">Col 2</div>
<div class="col demo lapOrder2 tblOrder1 tbsOrder6 mblOrder5 mbsOrder4">Col 3</div>
<div class="col demo lapOrder3 tblOrder2 tbsOrder1 mblOrder6 mbsOrder5">Col 4</div>
<div class="col demo lapOrder4 tblOrder3 tbsOrder2 mblOrder1 mbsOrder6">Col 5</div>
<div class="col demo lapOrder5 tblOrder4 tbsOrder3 mblOrder2 mbsOrder1">Col 6</div>
</div>