CSS » Page layout

Be­sides sep­a­rate com­po­nents, m.css pro­vides a ful­ly-fledged whole page lay­out, in­clud­ing top nav­i­ga­tion bar, foot­er nav­i­ga­tion, ar­ti­cle styling 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­am­ble, with <html lang="en"> and a <meta> tag spec­i­fy­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 stan­dard), but some not, so it’s bet­ter to al­ways in­clude it. In the <head> el­e­ment it’s im­por­tant to al­so spec­i­fy that the site is re­spon­sive via the <meta name="viewport"> tag.

The <body> el­e­ment is di­vid­ed in­to three parts — top nav­i­ga­tion bar, main page con­tent and the foot­er nav­i­ga­tion, ex­plained be­low. Their mean­ing is im­plic­it, so it’s not need­ed to put any CSS class­es on these el­e­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 Vi­val­di or Chrome on An­droid) are able to col­or the tab based on page theme col­or. This can be spec­i­fied us­ing the fol­low­ing <meta> tag. The col­or shown match­es 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­i­ga­tion bar

The top nav­i­ga­tion bar is lin­ear on me­di­um and larg­er screens and hid­den un­der a “ham­burg­er menu” on small­er screens. It has a dis­tinct back­ground that spans the whole win­dow width, but the con­tent is lim­it­ed to page width as de­fined by the grid sys­tem.

A very sim­ple nav­i­ga­tion bar with a home­page 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 el­e­ment is po­si­tioned on the left, in the de­fault dark theme shown in bold and up­per­case. On medi­um and large screens, the con­tents of #m-navbar-collapse are shown, lin­ear­ly, 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­burg­er menu” icon will ap­pend ei­ther #navigation or # to the page URL, which trig­gers the #m-navbar-collapse el­e­ment to be shown un­der as a list or hid­den again.

Sim­i­lar­ly to head­in­gs you can wrap a part of the #m-navbar-brand el­e­ment in a .m-thin CSS class to add a thin­ner sub­ti­tle.

Two-col­umn nav­i­ga­tion on small screens

To save ver­ti­cal space on small screens, it’s pos­si­ble to split the navbar con­tents in­to two (or more) col­umns us­ing stan­dard m.css grid func­tion­al­i­ty. For bet­ter ac­ces­si­bil­i­ty, spec­i­fy the start in­dex on the sec­ond <ol> el­e­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>

Ac­tive menu item high­light­ing

Add #m-navbar-current ID to the <a> el­e­ment of a menu item that’s cur­rent­ly ac­tive to high­light it. This works for both top-lev­el menu items and sub-menus. Doesn’t do any­thing on the #m-navbar-brand el­e­ment.

Main con­tent

The <main> con­tent is sep­a­rat­ed from the head­er and foot­er by 1rem pad­ding, be­sides that there is no ad­di­tion­al im­plic­it styling. It’s rec­om­mend­ed to make use of m.css grid fea­tures for con­tent lay­out — in par­tic­u­lar, the <main> el­e­ment by it­self doesn’t even put any width re­stric­tion on the con­tent.

To fol­low HTM­L5 se­man­tic fea­tures, m.css ex­pects you to put your main page con­tent in­to an <article> el­e­ment, be it an ar­ti­cle or not. Head­ing is al­ways in an <h1> in­side the ar­ti­cle el­e­ment, sub-sec­tions are wrapped in nest­ed <section> el­e­ments with <h2> and fur­ther. Ex­am­ple markup to­geth­er with 10-col­umn grid set­up 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> el­e­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­po­nent 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 el­e­ment. The im­age is cov­ered by #m-landing-cover el­e­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­am­ple a lo­go, a short in­tro­duc­tionary para­graph and a down­load but­ton. Note that the grid set­up has to on­ly 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" folows -->
  </div>
</article></main>

The cov­er im­age al­ways spans the whole screen width and goes al­so 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> el­e­ment — this makes navbar dim­mer with trans­par­ent back­ground. Usu­al­ly the brand link on the left is su­per­flu­ous as the land­ing page re­peats it in a more prom­i­nent place, to hide it put a .m-navbar-brand-hidden on the #m-navbar-brand el­e­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­i­tors from nav­i­gat­ing the web­site — be­cause of that the top navbar is not hid­den com­plete­ly and hov­er­ing it will make it more vis­i­ble. This works sim­i­lar­ly with the ham­burg­er 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, sim­ply put the fol­low­ing markup in front of your page con­tent — an out­er #m-cover-image el­e­ment with back­ground im­age and an in­ner emp­ty <div> that takes care of the fade out gra­di­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> el­e­ments gives you one ad­van­tage — it gives you the foun­da­tion that makes link­ing to par­tic­u­lar ar­ti­cle sec­tions pos­si­ble. Con­sid­er 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 ei­ther the “Fea­tures” or “Pric­ing” head­ing will give the us­er a di­rect link to giv­en sec­tion and the sec­tion will be high­lighed ac­cord­ing­ly. This works for nest­ed sec­tions as well.

Ar­ti­cles

For blog-like ar­ti­cles, m.css pro­vides styling for ar­ti­cle head­er, sum­ma­ry and foot­er — just put <header> and <footer> el­e­ments di­rect­ly in­to the sur­round­ing <article> tag. Ar­ti­cle head­er is ren­dered in a big­ger and brighter font, while foot­er is ren­dered in a small­er and dim­mer font. Ex­am­ple markup and cor­re­spond­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­i­cat­ed styling for ar­ti­cle date in the time.m-date el­e­ment to go in­to <h1> of ar­ti­cle <header>. For se­man­tic pur­pos­es and SEO it’s good to in­clude the date/time in a ma­chine-read­able for­mat as well. You can get this for­mat­ting via date -Iseconds Unix com­mand. The same is then re­peat­ed in ar­ti­cle <footer>.

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

Jum­bo ar­ti­cles

For “jum­bo” ar­ti­cles with a big cov­er im­age, a dif­fer­ent lay­out is avail­able. Ex­am­ple markup, cor­re­spond­ing in con­tent to the above ar­ti­cle, 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 col­umns. Date and au­thor name is ren­dered 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 ren­dered white, add an ad­di­tion­al .m-inverted CSS class to have it black. The ar­ti­cle con­tents are marked with .m-container-inflatable to make in­flat­ed nest­ed lay­outs such as im­age grid pos­si­ble.

<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­i­lar­ly to land­ing pages, the cov­er im­age of the jum­bo ar­ti­cle al­ways spans the whole screen width and goes be­low the top navbar. If you want the navbar to be se­mi-trans­par­ent, put .m-navbar-cover on the <nav> el­e­ment. Com­pared to land­ing pages the navbar re­tains se­mi-trans­par­ent back­ground at all times.

Cat­e­go­ry, au­thor list and tag cloud

Wrap <h3> head­ers and <ol> list in nav.m-navpanel, you can al­so make use of the .m-block-bar-* CSS class to make the list lin­ear on small screen sizes and save ver­ti­cal space. For a tag cloud, mark the <ul> with .m-tagcloud and wrap in­di­vid­u­al <li> in .m-tag-1 to .m-tag-5 CSS class­es to scale them from small­est 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 ar­ti­cles in it. The <h3> can be used to link to the blog front page; if you use the <time> tag for spec­i­fy­ing ar­ti­cle dates, it will be aligned to the right. Ex­am­ple:

<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>