├── .gitignore
├── README.md
├── _config.yml
├── _layouts
└── base.html
├── index.md
└── stylesheets
├── normalize.css
└── styles.css
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project Files #
2 | #################
3 | .project
4 |
5 | # OS Files #
6 | ############
7 | .DS_Store*
8 | ehthumbs.db
9 | Icon?
10 | Thumbs.db
11 |
12 | # Temp Files #
13 | ##############
14 | *~
15 | *.tmp*
16 | *.orig
17 | *.cache
18 | *.log
19 |
20 |
21 | # Jekyll #
22 | ##########
23 | _site/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Responsive, Two Column Documentation Layout With Markdown and CSS
2 |
3 | Using Markdown and CSS to achieve a responsive, two column layout, with code examples and their explanations appear next to each other.
4 |
5 | Checkout the [live example][site] for an explanation of how this layout works, or view the [index.md][index] and [style][style] files in this repo for the complete source. The [Bennu project site][bennu] shows a more elaborate version of this layout in action.
6 |
7 | The example uses uses [Jekyll](http://jekyllrb.com). Simply run: `$ jekyll build` to build it.
8 |
9 |
10 | [site]: http://mattbierner.github.io/markdown-two-column-documentation-example
11 |
12 | [bennu]: http://bennu-js.com
13 |
14 | [src]: https://github.com/mattbierner/markdown-two-column-documentation-example
15 | [index]: https://raw.githubusercontent.com/mattbierner/markdown-two-column-documentation-example/master/index.md
16 | [style]: https://github.com/mattbierner/markdown-two-column-documentation-example/blob/master/stylesheets/styles.css
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | markdown: redcarpet
2 | redcarpet:
3 | extensions: ["fenced_code_blocks", "with_toc_data"]
--------------------------------------------------------------------------------
/_layouts/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | MD2
5 |
6 |
7 |
8 |
9 |
10 | {{ content }}
11 |
12 |
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | ---
4 |
5 | # Responsive, Two Column Documentation Layout With Markdown and CSS
6 |
7 | Markdown makes it easy to write and maintain documentation, but is normally limited to single column layouts. For documenting code, and on larger screens particularly, single column layouts do not utilize space well and separate explanatory text too much from code samples:
8 |
9 | This page documents how to use plain old Markdown and CSS to achieve a responsive, two column layout, with code examples their explanations appear next to each other. It targets code documentation, but can easily be adapted to other contexts as well.
10 |
11 | For maximum metaness, the page itself uses the two column layout it documents. More complete examples are demonstrated on the [Bennu][bennu] and [Nu][nu] project sites.
12 |
13 | Checkout the complete code on [github][src]. It uses [Jekyll](http://jekyllrb.com). Simply run: `$ jekyll build` to build it.
14 |
15 |
16 |
17 | ## The Markdown
18 | We'll abuse some Markdown elements to get the layout we want. You can choose to style your page differently, but here we'll have code examples on the right, and code explanations on the left.
19 |
20 | ### First, we need to tell Markdown where the two column layout begins.
21 | Anything before this element will be rendered normally.
22 |
23 | ```
24 |
25 | ```
26 |
27 | And we should also tell it where the two column layout ends.
28 |
29 | ```
30 |
31 | ```
32 |
33 | ### `h2` will be an example section header.
34 |
35 | ```
36 | ## Section title
37 | ```
38 |
39 | And any text directly after the section title will not be split into two columns.
40 |
41 | ```
42 | ## Section title
43 | This text, along with the title, remains in a single column
44 | ```
45 |
46 | ### Each point in a section starts with an `h3`.
47 |
48 | ```
49 | ### Main you want to make point here
50 | ```
51 |
52 | ### Normal text elements (`p`) are used for more detailed explanations.
53 | You can put them after the main point.
54 |
55 | ```
56 | ### Main point
57 | Some explanatory text.
58 | ```
59 |
60 | ### Code is interleaved with explanatory text.
61 |
62 | The main point or explanation for a piece of code should come directly before it.
63 |
64 | ### Main point about code block 1
65 |
66 | ```
67 | code block 1
68 | ```
69 |
70 | More text explaining code block 2
71 |
72 | ```
73 | code block 2
74 | ```
75 |
76 | ## Styling
77 | We can use CSS to style the Markdown output to create a two column layout when readers view our page on a larger screen.
78 |
79 | ### The main section and subsection headings both take up the entire width of the page.
80 |
81 | ```
82 | article .begin-examples ~ h2,
83 | article .begin-examples ~ h2 + p {
84 | width: 100%;
85 | clear: both;
86 | }
87 | ```
88 |
89 | ### Each column element is 50% width
90 |
91 | ```
92 | article .begin-examples ~ h3,
93 | article .begin-examples ~ p,
94 | article .begin-examples ~ .highlight {
95 | width: 50%;
96 | }
97 | ```
98 |
99 | ### The left column has the main point and explanation text (`h3` and `p`).
100 | We'll add some padding here too for good measure.
101 |
102 | ```
103 | article .begin-examples ~ h3,
104 | article .begin-examples ~ p {
105 | float: left;
106 | box-sizing: border-box;
107 | padding-right: 1rem;
108 | clear: both;
109 | }
110 | ```
111 |
112 | ### While the right column has only the code examples `.highlight`.
113 | And some spacing between the sections.
114 |
115 | ```
116 | article .begin-examples ~ .highlight {
117 | float: right;
118 | clear: right;
119 | margin-bottom: 1rem;
120 | }
121 | ```
122 |
123 | ### That's it!
124 | But we have to ensure that nothing goes past the end of content.
125 |
126 | ```
127 | .end-examples {
128 | clear: both;
129 | }
130 | ```
131 |
132 | ### But we should clean up after ourselves.
133 | Reset the styles to stop the two column layout. This must come after all the other styles in the CSS file.
134 |
135 | ```
136 | article .end-examples ~ p,
137 | article .end-examples ~ h3,
138 | article .end-examples ~ .highlight {
139 | width: auto;
140 | float: none;
141 | clear: none;
142 | }
143 | ```
144 |
145 |
146 | ## Style For Small Screens
147 | Using a media query on screens less that 580px in width, we'll create a single column layout again.
148 |
149 | ### All you have to do is reset the styling on the main elements of the two column layout
150 |
151 | ```
152 | article .begin-examples ~ h3,
153 | article .begin-examples ~ p,
154 | article .begin-examples ~ .highlight {
155 | width: 100%;
156 | float: none;
157 | clear: none;
158 | }
159 | ```
160 |
161 |
162 |
163 | # Conclusion
164 | This example and the [source][src] intentionally keep any other fancy styling to a minimum, but it is very easy to style the two column layout. For styles that only apply inside the layout, add styles for `.begin-examples ~ * { }` and then reset them with `.end-examples ~ * { }`.
165 |
166 |
167 |
168 | [Nu]: http://mattbierner.github.io/nu/
169 | [bennu]: http://bennu-js.com
170 |
171 | [src]: https://github.com/mattbierner/markdown-two-column-documentation-example
172 |
--------------------------------------------------------------------------------
/stylesheets/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | button,
291 | html input[type="button"], /* 1 */
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/stylesheets/styles.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-size: 14px;
3 | }
4 |
5 |
6 | h1, h2, h3, h4, h5, h6 {
7 | color: #444;
8 | margin: 0 0 10px;
9 | }
10 |
11 | p, ul, ol, table, pre, dl {
12 | margin: 0 0 20px;
13 | }
14 |
15 | .wrapper {
16 | max-width: 650px;
17 | margin: 0 auto;
18 | position: relative;
19 | padding: 0 20px;
20 | }
21 |
22 |
23 | pre {
24 | overflow-x: visible;
25 | }
26 |
27 | section {
28 | max-width: 650px;
29 | padding: 30px 0px 50px 0px;
30 | margin: 20px 0;
31 | margin-top: 70px;
32 | }
33 |
34 |
35 | /*----------------------------
36 | Two column layout stuff
37 | ---------------------------*/
38 | /* Main Section Headings and sub headings */
39 | article .begin-examples ~ h2,
40 | article .begin-examples ~ h2 + p {
41 | width: 100%;
42 | clear: both;
43 | }
44 |
45 | /* Columns */
46 | article .begin-examples ~ h3,
47 | article .begin-examples ~ p,
48 | article .begin-examples ~ .highlight {
49 | width: 50%;
50 | }
51 |
52 | /* Left Column */
53 | article .begin-examples ~ h3,
54 | article .begin-examples ~ p {
55 | float: left;
56 | box-sizing: border-box;
57 | padding-right: 1rem;
58 | clear: both;
59 | }
60 |
61 | /* Right Column */
62 | article .begin-examples ~ .highlight {
63 | float: right;
64 | clear: right;
65 | margin-bottom: 1rem;
66 | }
67 |
68 | /* Reset */
69 | article .end-examples ~ p,
70 | article .end-examples ~ h3,
71 | article .end-examples ~ .highlight {
72 | width: auto;
73 | float: none;
74 | clear: none;
75 | }
76 |
77 | .end-examples {
78 | clear: both;
79 | }
80 |
81 | @media print, screen and (max-width: 580px) {
82 |
83 | /*----------------------------
84 | Two column layout media
85 | ---------------------------*/
86 | article .begin-examples ~ h3,
87 | article .begin-examples ~ p,
88 | article .begin-examples ~ .highlight {
89 | width: 100%;
90 | float: none;
91 | clear: none;
92 | }
93 |
94 | }
95 |
96 |
97 | /*----------------------------------------------------------
98 | Other Styling
99 |
100 | Normally you would just put this in the sections above.
101 | ---------------------------------------------------------*/
102 |
103 | h3 {
104 | font-weight: normal;
105 | text-size: 1rem;
106 | }
107 |
108 |
109 | .begin-examples ~ p {
110 | font-style: italic;
111 | font-size: 0.9rem;
112 | }
113 |
114 | .end-examples ~ p {
115 | font-style: normal;
116 | font-size: 1rem;
117 | }
118 |
119 | /*----------------------------
120 | Other media
121 | ---------------------------*/
122 | @media print, screen and (max-width: 580px) {
123 | article > h3,
124 | article > p {
125 | padding: 0;
126 | margin-bottom: 0.2rem;
127 | }
128 |
129 | article .highlight {
130 | margin-bottom: 1.4rem;
131 | background: #f7f7f7;
132 | padding: 0.2rem;
133 |
134 | word-wrap: break-word;
135 | }
136 |
137 | article .highlight pre {
138 | margin-bottom: 0;
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------