CSS » Page layout

With m-lay­out.css, m.css provides a full-fledged whole page lay­out, in­clud­ing top nav­ig­a­tion bar, foot­er nav­ig­a­tion, art­icle styl­ing, act­ive sec­tion high­light­ing and more.

Ba­sic markup struc­ture

A bare­bones HTML markup struc­ture us­ing m.css looks like be­low. There is the usu­al pre­amble, with <html lang="en"> and a <meta> tag spe­cify­ing the file en­cod­ing, which should be the first thing in <head>. Some browsers as­sume UTF-8 by de­fault (as per the HTM­L5 stand­ard), but some not, so it’s bet­ter to al­ways in­clude it. In the <head> ele­ment it’s im­port­ant to also spe­cify that the site is re­spons­ive via the <meta name="viewport"> tag.

The <body> ele­ment is di­vided in­to three parts — top nav­ig­a­tion bar, main page con­tent and the foot­er nav­ig­a­tion, ex­plained be­low. Their mean­ing is im­pli­cit, so it’s not needed to put any CSS classes on these ele­ments, but you have to stick to the shown struc­ture.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Page title</title>
    <link rel="stylesheet" href="m-dark.css" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <header><nav>
      <!-- here comes the top navbar -->
    </nav></header>
    <main>
      <!-- here comes the main page content -->
    </main>
    <footer><nav>
      <!-- here comes the footer navigation -->
    </nav></footer>
  </body>
</html>

Theme col­or

Some browsers (such as Viv­aldi or Chrome on An­droid) are able to col­or the tab based on page theme col­or. This can be spe­cified us­ing the fol­low­ing <meta> tag. The col­or shown matches the de­fault (dark) style, see the CSS themes page for col­ors match­ing oth­er themes.

<meta name="theme-color" content="#22272e" />

Top nav­ig­a­tion bar

The top nav­ig­a­tion bar is lin­ear on me­di­um and lar­ger screens and hid­den un­der a “ham­burger menu” on smal­ler screens. It has a dis­tinct back­ground that spans the whole win­dow width, but the con­tent is lim­ited to page width as defined by the grid sys­tem.

A very simple nav­ig­a­tion bar with a homepage link and three ad­di­tion­al menu items is shown be­low.

<header><nav id="navigation">
  <div class="m-container">
    <div class="m-row">
      <a href="#" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your Brand</a>
      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
        <ol>
          <li><a href="#">Features</a></li>
          <li><a href="#">Showcase</a></li>
          <li><a href="#">Download</a></li>
        </ol>
      </div>
    </div>
  </div>
</nav></header>

The #m-navbar-brand ele­ment is po­si­tioned on the left, in the de­fault dark theme shown in bold and up­per­case. On me­di­um and large screens, the con­tents of #m-navbar-collapse are shown, lin­early, aligned to the right.

On small and tiny screens, the #m-navbar-show and #m-navbar-hide show the glyph aligned to the right in­stead of #m-navbar-collapse. Click­ing on this “ham­burger menu” icon will ap­pend either #navigation or # to the page URL, which trig­gers the #m-navbar-collapse ele­ment to be shown un­der as a list or hid­den again.

Sim­il­arly to head­ings you can wrap a part of the #m-navbar-brand ele­ment in a .m-thin CSS class to add a thin­ner sub­title.

Two-column nav­ig­a­tion on small screens

To save ver­tic­al space on small screens, it’s pos­sible to split the navbar con­tents in­to two (or more) columns us­ing stand­ard m.css grid func­tion­al­ity. For bet­ter ac­cess­ib­il­ity, spe­cify the start in­dex on the second <ol> ele­ment.

<header><nav id="navigation">
  <div class="m-container">
    <div class="m-row">
      <a href="#" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your Brand</a>
      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
        <div class="m-row">
          <ol class="m-col-t-6 m-col-m-none">
            <li><a href="#">Features</a></li>
            <li><a href="#">Showcase</a></li>
            <li><a href="#">Download</a></li>
          </ol>
          <ol class="m-col-t-6 m-col-m-none" start="4">
            <li><a href="#">Blog</a></li>
            <li><a href="#">Contact</a></li>
          </ol>
        </div>
      </div>
    </div>
  </div>
</nav></header>

Act­ive menu item high­light­ing

Add #m-navbar-current ID to the <a> ele­ment of a menu item that’s cur­rently act­ive to high­light it. This works for both top-level menu items and sub-menus. Doesn’t do any­thing on the #m-navbar-brand ele­ment.

Main con­tent

The <main> con­tent is sep­ar­ated from the head­er and foot­er by 1rem pad­ding, be­sides that there is no ad­di­tion­al im­pli­cit styl­ing. It’s re­com­men­ded to make use of m.css grid fea­tures for con­tent lay­out — in par­tic­u­lar, the <main> ele­ment by it­self doesn’t even put any width re­stric­tion on the con­tent.

To fol­low HTM­L5 se­mant­ic fea­tures, m.css ex­pects you to put your main page con­tent in­to an <article> ele­ment, be it an art­icle or not. Head­ing is al­ways in an <h1> in­side the art­icle ele­ment, sub-sec­tions are wrapped in nes­ted <section> ele­ments with <h2> and fur­ther. Ex­ample markup to­geth­er with 10-column grid setup around the main con­tent:

<main><div class="m-container">
  <div class="m-row">
    <article class="m-col-m-10 m-push-m-1">
      <h1>A page</h1>
      <p>Some introductionary paragraph.</p>
      <section>
        <h2>Features</h2>
        <p>Section providing feature overview.</p>
      </section>
      <section>
        <h2>Pricing</h2>
        <p>Information about product pricing.</p>
      </section>
    </article>
  </div>
</div></main>

Land­ing pages

Be­sides usu­al pages, which have the <article> ele­ment filled with <h1> fol­lowed by a wall of con­tent, m.css has first-class sup­port for land­ing pages. The ma­jor com­pon­ent of a land­ing page is a cov­er im­age in the back­ground, span­ning the whole page width in a #m-landing-image ele­ment. The im­age is covered by #m-landing-cover ele­ment that blends the im­age in­to the back­ground on the bot­tom. On top of it you have full free­dom to put any lay­out you need, for ex­ample a logo, a short in­tro­duc­tion­ary para­graph and a down­load but­ton. Note that the grid setup has to only wrap the con­tent “be­low the fold”, not the cov­er im­age.

<main><article>
  <div id="m-landing-image" style="background-image: url('landing.jpg');">
    <div id="m-landing-cover">
      <div class="m-container">
        <!-- content displayed over the cover image -->
      </div>
    </div>
  </div>
  <div class="m-container">
    <!-- content "below the fold" follows -->
  </div>
</article></main>

The cov­er im­age al­ways spans the whole screen width and goes also un­der the top navbar. In or­der to make the navbar aware of the im­age, put a .m-navbar-landing CSS class on the <nav> ele­ment — this makes navbar dim­mer with trans­par­ent back­ground. Usu­ally the brand link on the left is su­per­flu­ous as the land­ing page re­peats it in a more prom­in­ent place, to hide it put a .m-navbar-brand-hidden on the #m-navbar-brand ele­ment. While the land­ing page is de­signed to catch at­ten­tion of new users, it shouldn’t pre­vent reg­u­lar vis­it­ors from nav­ig­at­ing the web­site — be­cause of that the top navbar is not hid­den com­pletely and hov­er­ing it will make it more vis­ible. This works sim­il­arly with the ham­burger menu on small screen sizes.

Pages with cov­er im­age

If you just want slide a cov­er im­age un­der con­tent of your page and don’t need to have con­trol over what con­tent is over the im­age and what un­der, simply put the fol­low­ing markup in front of your page con­tent — an out­er #m-cover-image ele­ment with back­ground im­age and an in­ner empty <div> that takes care of the fade out gradi­ent over it.

<main>
  <div id="m-cover-image" style="background-image: url('cover.jpg');">
    <div></div>
  </div>
  <article>
    <div class="m-container">
      <!-- the whole content of your page goes here -->
    </div>
  </article>
</main>

Click­able sec­tions

Us­ing the <section> ele­ments gives you one ad­vant­age — it gives you the found­a­tion that makes link­ing to par­tic­u­lar art­icle sec­tions pos­sible. Con­sider the fol­low­ing code snip­pet:

<article>
  <h1>A page</h1>
  <p>Some introductionary paragraph.</p>
  <section id="features">
    <h2><a href="#features">Features</a></h2>
    <p>Section providing feature overview.</p>
  </section>
  <section id="pricing">
    <h2><a href="#pricing">Pricing</a></h2>
    <p>Information about product pricing.</p>
  </section>
</article>

Click­ing on either the “Fea­tures” or “Pri­cing” head­ing will give the user a dir­ect link to giv­en sec­tion and the sec­tion will be high­lighed ac­cord­ingly. This works for nes­ted sec­tions as well.

Art­icles

For blog-like art­icles, m.css provides styl­ing for art­icle head­er, sum­mary and foot­er — just put <header> and <footer> ele­ments dir­ectly in­to the sur­round­ing <article> tag. Art­icle head­er is rendered in a big­ger and bright­er font, while foot­er is rendered in a smal­ler and dim­mer font. Ex­ample markup and cor­res­pond­ing ren­der­ing:

<article>
  <header>
    <h1><a href="#" rel="bookmark" title="Permalink to An article">
      <time class="m-date" datetime="2017-09-08T00:00:00+02:00">
      Sep <span class="m-date-day">8</span> 2017
      </time>
      An article
    </a></h1>
    <p>Article summary paragraph. Lorem ipsum dolor sit amet, consectetur
    adipiscing elit. Aenean id elit posuere, consectetur magna congue, sagittis
    est.</p>
  </header>
  <p>Article contents. Pellentesque est neque, aliquet nec consectetur in,
  mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus
  consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu
  sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae
  euismod quis, venenatis eu nulla.</p>
  <footer>
    <p>Posted by <a href="#">The Author</a> on
    <time datetime="2017-09-08T00:00:00+02:00">Sep 8 2017</time>.</p>
  </footer>
</article>

An article

Article summary paragraph. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id elit posuere, consectetur magna congue, sagittis est.

Article contents. Pellentesque est neque, aliquet nec consectetur in, mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae euismod quis, venenatis eu nulla.

There’s a ded­ic­ated styl­ing for art­icle date in the time.m-date ele­ment to go in­to <h1> of art­icle <header>. For se­mant­ic pur­poses and SEO it’s good to in­clude the date/time in a ma­chine-read­able format as well. You can get this format­ting via date -Iseconds Unix com­mand. The same is then re­peated in art­icle <footer>.

It’s good to in­clude the <a rel="bookmark"> at­trib­ute in the permalink to hint search en­gines about pur­pose of the link and then give the same via the title at­trib­ute.

Jumbo art­icles

For “jumbo” art­icles with a big cov­er im­age, a dif­fer­ent lay­out is avail­able. Ex­ample markup, cor­res­pond­ing in con­tent to the above art­icle, but with a cov­er im­age in back­ground, is shown be­low. The markup is meant to be straight in <main> as it ar­ranges the con­tent by it­self in the cen­ter 10 columns. Date and au­thor name is rendered on top left and right in front of the cov­er im­age, the head­ing (and op­tion­al sub­head­ing) as well. By de­fault, the text on top of the cov­er im­age is rendered white, add an ad­di­tion­al .m-inverted CSS class to have it black. The art­icle con­tents are marked with .m-container-inflatable to make in­flated nes­ted lay­outs such as im­age grid pos­sible.

<article id="m-jumbo">
  <header>
    <div id="m-jumbo-image" style="background-image: url('ship.jpg');">
      <div id="m-jumbo-cover">
        <div class="m-container">
          <div class="m-row">
            <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-left">Sep 8 2017</div>
            <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-right"><a href="#">An Au­thor</a></div>
          </div>
          <div class="m-row">
            <div class="m-col-t-12 m-col-s-10 m-push-s-1 m-col-m-8 m-push-m-2">
              <h1><a href="#" rel="bookmark" title="Permalink to An Ar­ti­cle — a jum­bo one">
                An article
              </a></h1>
              <h2>a jumbo one</h2>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="m-container">
      <div class="m-row">
        <div class="m-col-m-10 m-push-m-1 m-nopady">
          <p>Article summary paragraph. Lorem ipsum dolor sit amet, consectetur
          adipiscing elit. Aenean id elit posuere, consectetur magna congue,
          sagittis est.</p>
        </div>
      </div>
    </div>
  </header>
  <div class="m-container m-container-inflatable">
    <div class="m-row">
      <div class="m-col-m-10 m-push-m-1 m-nopady">
      Article contents. Pellentesque est neque, aliquet nec consectetur in,
      mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat
      lacus consequat. Mauris id suscipit mauris, in scelerisque lectus.
      Aenean nec nunc eu sem tincidunt imperdiet ut non elit. Integer nisi
      tellus, ullamcorper vitae euismod quis, venenatis eu nulla.
      </div>
    </div>
  </div>
  <footer class="m-container">
    <div class="m-row">
      <div class="m-col-m-10 m-push-m-1 m-nopadb">
        <p>Posted by <a href="#">An Au­thor</a> on
        <time datetime="2017-09-08T00:00:00+02:00">Sep 8 2017</time>.</p>
      </div>
    </div>
  </footer>
</article>

Sim­il­arly to land­ing pages, the cov­er im­age of the jumbo art­icle al­ways spans the whole screen width and goes be­low the top navbar. If you want the navbar to be semi-trans­par­ent, put .m-navbar-cover on the <nav> ele­ment. Com­pared to land­ing pages the navbar re­tains semi-trans­par­ent back­ground at all times.

Cat­egory, au­thor list and tag cloud

Wrap <h3> head­ers and <ol> list in nav.m-navpanel, you can also make use of the .m-block-bar-* CSS class to make the list lin­ear on small screen sizes and save ver­tic­al space. For a tag cloud, mark the <ul> with .m-tagcloud and wrap in­di­vidu­al <li> in .m-tag-1 to .m-tag-5 CSS classes to scale them from smal­lest to largest.

<nav class="m-navpanel">
  <h3>Categories</h3>
  <ol class="m-block-bar-m">
    <li><a href="#">News</a></li>
    <li><a href="#">Archive</a></li>
  </ol>
  <h3>Authors</h3>
  <ol class="m-block-bar-m">
    <li><a href="#">An Author</a></li>
    <li><a href="#">Some Other Author</a></li>
  </ol>
  <h3>Tag cloud</h3>
  <ul class="m-tagcloud">
    <li class="m-tag-1"><a href="#">Announcement</a></li>
    <li class="m-tag-5"><a href="#">C++</a></li>
    <li class="m-tag-3"><a href="#">Games</a></li>
    <li class="m-tag-4"><a href="#">Rants</a></li>
  </ul>
</nav>

News list on in­dex page

Some­times you may want just a small list of news items tucked to the bot­tom of an in­dex page that’s oth­er­wise full of oth­er con­tent. Mark a block with .m-landing-news and put a list of art­icles in it. The <h3> can be used to link to the blog front page; if you use the <time> tag for spe­cify­ing art­icle dates, it will be aligned to the right. Ex­ample:

<div class="m-row">
  <div class="m-col-m-8 m-push-m-2">
    <div class="m-landing-news m-note m-default">
      <h3><a href="#">Latest news on our blog &raquo;</a></h3>
      <ul class="m-unstyled">
        <li><time class="m-text m-dim" datetime="2018-01-16T00:00:00+00:00">Jan 16, 2018</time><a href="article2.html">The latest article</a></li>
        <li><time class="m-text m-dim" datetime="2017-12-09T00:00:00+00:00">Dec 09, 2017</time><a href="article.html">A slightly older article</a></li>
      </ul>
      </div>
    </div>
  </div>
</div>