MJC SEO & Web Development Blog > Image free responsive mobile menu buttons using the ≡ character and pure CSS

Image free responsive mobile menu buttons using the ≡ character and pure CSS

Pure CSS scalable menu toggle buttons with three, four, five and six lines – tutorial and download

Different pure CSS buttons at 60px, 90px, 115px, 145px and 170px. The top row uses CSS3 styling whereas the bottom row is CSS2
Download the CSS – 4.3KB (full version)
‘lite’ version – 772B (3 line button only, minimal comments)

A lot of responsively designed sites call for menu toggle buttons, so that menus don’t take up a lot of vertical screen space on mobile devices where elements are often stretched to 100% width. This can be to toggle a separate touch enabled menu, or to display the normal menu from a position:fixed header. Rather than creating a lot of button graphics I wondered if there way a way to make such a simple icon using pure CSS, and came up with these. The CSS3 version is fully compatible with IE 9 and the CSS2 version should work with any browser that has proper support of the after property – for example IE8 but not IE7. All smartphone browsers from recent years should be compatible with the basic button and most will support the CSS3 effects.

The buttons render in the box model with the same horiontal and vertical dimensions as the font-size specified, in pixels, with all other values in the code using relative units in order to scale with this value. The buttons themselves can also be sized in ems if preferred.

Instead of an image, an ‘equal sign with three bars’ ≡, meaning ‘identical to’ is used, equivalent to the triple equals operator in programming languages. This is represented as \2261 when escaped in CSS files, with the HTML entity code being ≡.

Basic three line button

The HTML:

<div id="menu-button"></div>

You could use other elements than a div, such as <span> or <button>, but it may require more lines of CSS due to element default styles. The element is ideally output with JavaScript anyway as it has no function if JavaScript is disabled in a typical usage scenario. On a few sites it might be necessary to add a &nsbp; inside the div if the button doesn’t appear, depending on existing CSS rules.

The CSS:

#menu-button {
        font-size:60px; /* Change to alter button size */
        font-family:verdana !important;
        font-weight:normal !important;
        font-style:normal !important;
        height:0.9em;
        width:0.9em;
        background:#777;
        cursor:pointer;
        position:relative; /* Also works with absolute */
        border:0.05em solid #555;
}

#menu-button:after {
        content:'\2261';
        color:#fff;
        position:absolute;
        top:0.39em;
        left:0.036em;
        line-height:0em;
}

#menu-button:active {
        top:1px;
        left:1px;
}

CSS Notes

Using an :after pseudoclass means the button can be made from a single empty element, not needing a parent container or child element or any text nodes, with the side benefit that the &equiv; character doen’t end up cluttering the source code.

Font-family, weight and style needs to be specified to ensure consistent rendering – characters are displayed very differently in terms of position, scaling and style across different fontfaces, and some fonts may not contain the ≡ character. You could use a different font and adjust the top and left values if looking for a different thickness or spacing of lines, though scaling may present issues.

Simple Button Usage

An easy usage to display a large, black button:

<div id="menu-button" style="background:black; font-size:120px"></div>

Four, Five and Six Line Buttons

Four Bars

Five Bars

Six Bars

<div id="menu-button" class="four"></div>
<div id="menu-button" class="five"></div>
<div id="menu-button" class="six"></div>

Solving scaling issues with CSS3 transforms and reciprocal functions

To get the four, five and six line versions, instead of just one ≡, there are four in the :after content property. Two render on each line, and letter-spacing and line-height are used to superimpose the four characters to make what appears to be one of the required number of lines and width.

Due to the increase in the number of characters, the element needs to be larger to contain them. This means it no longer renders at the same pixel size as specified in font-size, but larger by the ratio of the value in ems the width and height of the element is increased by – for example 1.2ems for the four bar version and 1.8 for the six.

To get scaling back to how it was before, we can use the CSS3 transform scale property to reduce the size. To get the ratio to scale at, we need the reciprocal of the ratio mentioned above. So for the six line version we scale at 1/1.8 or 0.556.

But wait, what about the border? The 0.05em border becomes very thin on the six line version, so it is doubled to 0.1em. We are also forgetting to include the border in scaling calculations (and so it will be slightly bigger than it should be) – we should actually be scaling the six line version by 1.8em + 0.1em + 0.1em = 2em – or a factor of two. So the CSS scale value is set at 0.5, or 50%, resulting in actual size output.

Finally, while the size the buttons are rendered at has changed, they still take up the same amount of space on the page, as if they have a massive margin. To get around this, a negative margin is set. I have not yet worked out the mathematical relationship between this value and the scaling ratio, and the value required is subjected to any rounding errors carried over from the reciprocal calculation. In shorter terms, it has been hand coded for each of the four, five and six line box types.

Note: Some browser compatibility code has been omitted in the following and later code sections, but it’s all in the CSS download.

#menu-button.four {
        height:1.2em;
        width:1.2em;
        border:0.07em solid #555;
        -webkit-transform:scale(0.7462);
        transform:scale(0.7462);
        margin:-0.162em;
}

#menu-button.four:after {
        content:'\2261 \2261  \2261 \2261';
        line-height:0.2em;
        letter-spacing:-0.6em;
        left:0.09em;
        top:0.33em;
        width:0;
}

#menu-button.five {
        height:1.7em;
        width:1.7em;
        border:0.1em solid #555;
        -webkit-transform:scale(0.5263);
        transform:scale(0.5263);
        margin:-0.443em;
}

#menu-button.five:after {
        content:'\2261 \2261  \2261 \2261';
        line-height:0.42em;
        letter-spacing:-0.35em;
        left:0.2em;
        width:0;
}

#menu-button.six {
        height:1.8em;
        width:1.8em;
        border:0.1em solid #555;
        -webkit-transform:scale(0.5);
        transform:scale(0.5);
        margin:-0.493em;
}

#menu-button.six:after {
        content:'\2261 \2261  \2261 \2261';
        line-height:0.62em;
        letter-spacing:-0.25em;
        left: 0.215em;
        top: 0.25em;
        width:0;
}

The CSS3 transform property doesn’t have to be used if the button doesn’t need to render at the same size as the font-size, meaning that the code can be made compatible with older browsers like the three line version is.

Adding some CSS3 effects to the menu buttons

#menu-button {
        border-radius: 0.09em;
        text-shadow: 0.05em 0.05em 0.1em rgba(0,0,0,0.4);
        box-shadow: 0.05em 0.05em 0.1em rgba(0,0,0,0.2), inset 0 0 0.2em rgba(0,0,0,0.3);
}

The ability to use text-shadow to give relief to the inner glyph is a great advantage of having a text element. However, it only looks OK on the basic three line version and the six line, as others overlap characters and cause part of the shadow to be more intense.

A double box shadow is used, the second inset in order to give a subtle embossing effect to the border.

#menu-button {
        background: radial-gradient(1.2em 1.1em at 0.65em 0.7em, darkturquoise,teal);
}

Finally, a radial-gradient is added if a flat colour look is not wished for.

Adding a hover style for non-touch users

While in the typical usage on the web will see the button used in a touch device only context, sometimes the button may also be used in pointer driven or combined interfaces. In these cases it’s useful to add a :hover state.

#menu-button:hover {
box-shadow:none;
}

If you’re using CSS2 buttons the above won’t do anything, but other things such as changing the background, font or border color will.

Thanks for reading and I hope you have fun making your own buttons.

One Comment

  1. Troy
    Posted March 12, 2014 at 10:03 pm | Permalink

    Thanks, Awsome CSS Button!!

Post a Comment

Your email is never shared. Required fields are marked *

*
*