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 top

Responsive

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>
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6