Pure CSS Push Menu


Published: 2015-12-30
Updated: 2016-01-02
Web: https://fritzthecat-blog.blogspot.com/2015/12/pure-css-push-menu.html


Conceptual Differences
CSS
HTML
Demo

To finish the intense CSS-blogging of this month, here is a pure CSS push menu.

Restrictions and concepts are the same as with my slide menu, with slight differences that I will explain in the following. This article strongly builds upon that slide-menu Blog, so you might want to read this first.

For smooth scroll behaviour, the demo has been shifted to bottom of this page (click here to see it).

Conceptual Differences to Slide Menu

I 've put the push-menu to left upper corner of the page. Thus it pushes the element to the right of it.

I used the same CSS event-mechanism as in slide-menu, the :focus pseudo-class. Nevertheless the layout had to be done differently, because the push-menu pushes aside page-content, and thus actively takes part in layout, while the slide-menu appears "hover" the page without touching anything.

For pushing, we need to distribute space between the participants, which are the menu and the page-content. Basically we would like to leave the space requirement to the actual text width in the menu, but unfortunately there is no way to express "take preferred size" in CSS. So I have set it to 30 : 70, which means the menu will take 30% of the width when open, while the page-content will keep 70%.

To enable that space distribution, we need to pack the page-content into a wrapping DIV that we can resize when the menu opens. Such was not necessary with the slide-menu.

CSS

If you compare the following CSS to the slide-menu, you will see that parts of it are the same. Different are just pushmenu versus slidemenu classes, and pushmenu-content versus slidemenu-content, and the integration of the page-content class. Of course the CSS state-change treatment also is different, because in a "push" two elements have to be adjusted.

      /* common styles for menu and menu-button */
.pushmenu {
position: fixed;
top: 0; /* be in left upper corner */
left: 0;
background-color: lightGray; /* menu would be transparent without background-color */
}
/* the open-menu button */
.menu-button {
padding: 0.4em;
margin: 0;
border: none; /* else border shadow */
}
/* initially invisible menu */
.pushmenu-content {
width: 0; /* initially invisible */
height: 0;
overflow: hidden; /* without this, the menu would be visible even when having zero width */
transition: 0.5s;
white-space: nowrap; /* avoids text formatting work during animation */
}
/* the content which the menu shares place with */
.page-content {
float: right; /* without this, the menu would be a slide-menu, not a push-menu */
width: 100%; /* initially taking all space, needed due to float right */
margin-top: 1em; /* leave place for the menu button */
transition: 0.5s;
box-sizing: border-box; /* calculate the border as element part */
}
/* make menu visible when menu-button is clicked, or mouse is over the menu */
.menu-button:focus + .pushmenu-content, .pushmenu-content:hover {
width: 30%; /* take some place when ... */
height: 100%; /* ... getting visible */
padding: 1em; /* define padding only when visible! */
box-sizing: border-box; /* calculate padding as element part */
}
/* push page-content when menu-button is clicked, or mouse is over the menu */
.menu-button:focus ~ .page-content, .pushmenu-content:hover ~ .page-content {
width: 70%;
border-left: 0.3em solid transparent; /* when a scrollbar is showing, distance to menu is too small */
}

Hope the comments were sufficient! When not, here are some further explanations.

The .pushmenu declaration puts the menu into left upper corner.
To use that CSS for push-menus within internal scroll-panes, just change position to absolute, and use scroll-panes like I described in my fixed position Blog.
To put the menu to right side, you would have to change left: 0 to right: 1.3em, and set the float: right property of page-content to left.

Button-styling in .menu-button is exactly the same as in slide-menu.

The .pushmenu-content differs in that it uses width and height instead of max-width and max-height. This is because here we set the width and height to a definite value, we can't use the menu's preferred size as the page-content would not know that value (CSS is too weak for such).

.page-content is the class for the pushed content. It floats to the right, and thus initially must be given 100% width, else it would stick to the right with its preferred size. (I tried to replace the float: right by a relative positioning, but this did not work properly, and most of all it can not be animated).
The margin-top provides space for the menu-button on top.
The border and box-sizing was necessary because there is a sizing issue when a scrollbar is present (page-content was cut on left edge, did not find out the reason).

Finally, the two .menu-button:focus declarations manage the CSS state change, and materialize the push by distributing the space 30 : 70 when the menu-button receives focus.
Mind that the two pushing elements are not in the same layout-layer. The menu is absolute and thus does not take part in normal layout flow, but the static page-content does. Therefore it is not sufficient to size just one of them, both must be sized complementarily.

Mind that both the pushmenu-content and the page-content need the same animation delay, given by transition: 0.5s, for the push to work properly.

HTML

The HTML difference to the slide-menu is just the existence of the content-wrapper with CSS-class page-content. You can also introduce this wrapper into the slide-menu HTML if you like, it won't break it.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>

<style type="text/css">
/* CSS goes here */
</style>
</head>

<body>

<input class="pushmenu menu-button" type="button" value="&#9776;" title="Click to open menu">

<div class="pushmenu pushmenu-content">
<a href="#one">1 Push Menu</a><br>
<a href="#two">2 Push Menu</a><br>
<a href="#three">3 Push Menu</a><br>
<a href="#four">4 Push Menu</a><br>
</div>

<div class="page-content">

<h1 id="one">1 Push Menu</h1>
<p>
Lore ipsum ...
</p>

<h1 id="two">2 Push Menu</h1>
<p>
Lore ipsum ...
</p>

</div> <!-- end page-content -->

</body>

</html>

Mind that the HTML elements with CSS classes menu-button and pushmenu-content must be siblings, the first directly preceding the second. The page-content element also must be a sibling of them, but it may follow anywhere behind pushmenu-content (the '~' CSS operator).

Demo

Now here is the demo, nested in an internal scroll-pane.

<- Use this to navigate

1 Push Menu

Lorem ipsum dolor sit amet, qui meliore deserunt at. Percipitur intellegam appellantur cu vim, mei soluta complectitur id, partem reprimique ullamcorper in vim. Eam an porro accusamus dissentiunt, te sit impedit tacimates, movet laboramus mea ad. Putent concludaturque per ei, cu utamur eleifend recteque vel, ancillae suscipit sit no. No qui erat dicunt lucilius. Ullum epicurei ea nec. Elitr laudem eam et, no dicit dissentias sea. Nec an stet decore honestatis, omittam maiestatis ei quo, eripuit facilis recusabo ius cu. Eu oblique detraxit honestatis vim, hinc sonet definitiones has ea. Debet propriae ut his, ne lorem aeque oportere ius, duo autem equidem gloriatur ad. Ei vel illud adolescens. Meis ocurreret ex sit. Ea ferri facer per. Odio gubergren democritum cum ad, ei quaeque philosophia contentiones sit. At atqui choro theophrastus sit, ne erroribus vulputate vis, eam et antiopam scripserit. Et sea altera salutandi iudicabit. Vidisse probatus moderatius cum te, et vis feugiat luptatum consulatu.

2 Push Menu

Lorem ipsum dolor sit amet, qui meliore deserunt at. Percipitur intellegam appellantur cu vim, mei soluta complectitur id, partem reprimique ullamcorper in vim. Eam an porro accusamus dissentiunt, te sit impedit tacimates, movet laboramus mea ad. Putent concludaturque per ei, cu utamur eleifend recteque vel, ancillae suscipit sit no. No qui erat dicunt lucilius. Ullum epicurei ea nec. Elitr laudem eam et, no dicit dissentias sea. Nec an stet decore honestatis, omittam maiestatis ei quo, eripuit facilis recusabo ius cu. Eu oblique detraxit honestatis vim, hinc sonet definitiones has ea. Debet propriae ut his, ne lorem aeque oportere ius, duo autem equidem gloriatur ad. Ei vel illud adolescens. Meis ocurreret ex sit. Ea ferri facer per. Odio gubergren democritum cum ad, ei quaeque philosophia contentiones sit. At atqui choro theophrastus sit, ne erroribus vulputate vis, eam et antiopam scripserit. Et sea altera salutandi iudicabit. Vidisse probatus moderatius cum te, et vis feugiat luptatum consulatu.

3 Push Menu

Lorem ipsum dolor sit amet, qui meliore deserunt at. Percipitur intellegam appellantur cu vim, mei soluta complectitur id, partem reprimique ullamcorper in vim. Eam an porro accusamus dissentiunt, te sit impedit tacimates, movet laboramus mea ad. Putent concludaturque per ei, cu utamur eleifend recteque vel, ancillae suscipit sit no. No qui erat dicunt lucilius. Ullum epicurei ea nec. Elitr laudem eam et, no dicit dissentias sea. Nec an stet decore honestatis, omittam maiestatis ei quo, eripuit facilis recusabo ius cu. Eu oblique detraxit honestatis vim, hinc sonet definitiones has ea. Debet propriae ut his, ne lorem aeque oportere ius, duo autem equidem gloriatur ad. Ei vel illud adolescens. Meis ocurreret ex sit. Ea ferri facer per. Odio gubergren democritum cum ad, ei quaeque philosophia contentiones sit. At atqui choro theophrastus sit, ne erroribus vulputate vis, eam et antiopam scripserit. Et sea altera salutandi iudicabit. Vidisse probatus moderatius cum te, et vis feugiat luptatum consulatu.

4 Push Menu

Lorem ipsum dolor sit amet, qui meliore deserunt at. Percipitur intellegam appellantur cu vim, mei soluta complectitur id, partem reprimique ullamcorper in vim. Eam an porro accusamus dissentiunt, te sit impedit tacimates, movet laboramus mea ad. Putent concludaturque per ei, cu utamur eleifend recteque vel, ancillae suscipit sit no. No qui erat dicunt lucilius. Ullum epicurei ea nec. Elitr laudem eam et, no dicit dissentias sea. Nec an stet decore honestatis, omittam maiestatis ei quo, eripuit facilis recusabo ius cu. Eu oblique detraxit honestatis vim, hinc sonet definitiones has ea. Debet propriae ut his, ne lorem aeque oportere ius, duo autem equidem gloriatur ad. Ei vel illud adolescens. Meis ocurreret ex sit. Ea ferri facer per. Odio gubergren democritum cum ad, ei quaeque philosophia contentiones sit. At atqui choro theophrastus sit, ne erroribus vulputate vis, eam et antiopam scripserit. Et sea altera salutandi iudicabit. Vidisse probatus moderatius cum te, et vis feugiat luptatum consulatu.

For more experiences with pure CSS push-menus you can visit my homepage demo.





ɔ⃝ Fritz Ritzberger, 2015-12-30