Skip to content

Instantly share code, notes, and snippets.

@Munawwar
Last active September 9, 2021 07:02
Show Gist options
  • Save Munawwar/7926618 to your computer and use it in GitHub Desktop.
Save Munawwar/7926618 to your computer and use it in GitHub Desktop.
HBox and VBox layout with CSS3 flexbox
<!DOCTYPE HTML>
<html>
<head>
<!-- HBox and VBox layouts have been implementated with many libraries/toolkits on
different platforms and languages (like ExtJS,QT,GTK,.NET...).
This tries to achieve the same but with CSS only.
Supported browsers: IE 10+, Safari 6.1, Latest FF, Chrome -->
<style type="text/css">
html, body {
margin: 0;
height: 100%;
}
</style>
<style>
/*Stack child items vertically*/
.vbox {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/*Align children vetically*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-content: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start;
}
/*Stack child items horizontally*/
.hbox {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/*Align children horizontally*/
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-content: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start;
}
/*Stretch item along parent's main-axis*/
.flex {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
/*Stretch item along parent's cross-axis*/
.stretch {
align-self: stretch;
}
/*Stack child items to the main-axis start*/
.main-start {
-webkit-justify-content: flex-start;
-ms-flex-pack: flex-start;
justify-content: flex-start;
}
/*Stack child items to the cross-axis start*/
.cross-start {
-webkit-align-items: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
-webkit-align-content: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start;
}
/*Stack child items to the main-axis center*/
.main-center {
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
/*Stack child items to the cross-axis center*/
.cross-center {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center;
}
/*Stack child items to the main-axis end.*/
.main-end {
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
}
/*Stack child items to the cross-axis end.*/
.cross-end {
-webkit-align-items: flex-end;
-ms-flex-align: flex-end;
align-items: flex-end;
-webkit-align-content: flex-end;
-ms-flex-line-pack: end;
align-content: flex-end;
}
/*Stretch child items along the cross-axis*/
.cross-stretch {
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;
}
/*Wrap items to next line on main-axis*/
.wrap {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
</style>
</head>
<body class="vbox" style="height: 100%; width: 100%;">
<div>Hello 1</div>
<div class="flex hbox main-center cross-center wrap">
<div>Hello 2.1</div>
<div>Hello 2.2</div>
<div>Hello 2.3</div>
</div>
<div>Hello 3</div>
</body>
</html>
@Munawwar
Copy link
Author

Safari 6.0 doesn't support wrapping on overflow unfortunately.
but Safari 6.1 does :)

@Munawwar
Copy link
Author

Documentation:
vbox - Stack child items vertically (the "main axis" for child items now becomes the vertical axis)
hbox - Stack child items horizontally (the "main axis" for child items now becomes the horizontal axis)
flex - Stretch item along parent's main-axis
stretch - Stretch item along parent's cross-axis

main-start - Stack child items to the main-axis start
main-center - Stack child items to the main-axis center
main-end - Stack child items to the main-axis end
cross-start, cross-center, cross-end - Similar to the 'main' counterparts, except these decide the stacking of child items along the cross-axis.

cross-stretch - Stretch child items along the cross-axis
wrap - Wrap child items to next line on main-axis

@Munawwar
Copy link
Author

Code and documentation moved to https://github.com/Munawwar/flex-helper. it also has and visual examples.

@shlomitc
Copy link

shlomitc commented Jan 2, 2018

@Munawwar
Copy link
Author

Munawwar commented Sep 26, 2018

@shlomitc Thanks.

Since this I've moved to using CSS preprocessor (less, sass) mixins for flexbox. The problem with helper classes for larger scale projects is CSS specificity issues (same applied to bootstrap and other helper class based frameworks).
Rather we namespaced each element we style and called https://github.com/Munawwar/flexbox-simplified mixins.. this generates more CSS yes, but less chances of CSS-overriding-each-other bugs. Also there are only 2 mixins in the repo and they are very easy to learn.

@rubyFeedback
Copy link

It may be useful to improve the original example shown above. I found
it just now, when I tried to design a generic DSL for classical GUIs
as well as the www.

For example:

vbox = gtk_vbox
vbox.add(text('hello world'))

I need that to work on ruby-gtk as well as HTML/CSS. I am fine with
ruby-gtk but am a semi-noob in regards to "higher" CSS, so anything
that allows hbox/vbox layout is SUPER helpful. I can then go on to
design and treat HTML/CSS like a widget set with classes, in an OOP
centric way.

Biggest hurdle for me is to understand hbox / vbox in HTML/CSS so
really this is actually helpful. The initial example above, though, is
kind of huge; may be more useful to demonstrate with smaller div
elements perhaps, like when you can say "ok this text is put into
a hbox at width 100 px, then the next text comes in".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment