diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4194589c..df6a4e2f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+* Add `header` and `footer` directives ([#22](https://github.com/marp-team/marpit/pull/22))
+
## v0.0.5 - 2018-05-12
* Add `paginate` local directive ([#17](https://github.com/marp-team/marpit/pull/17))
diff --git a/README.md b/README.md
index 8c00cb9a..d29cd54f 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,57 @@ Simply you have to move a definition of `paginate` directive to an inside of a s
It will paginate slide from a this page.
```
+#### Header and footer
+
+When you have to be shown the same content across multiple slides like a title of the slide deck, you can use `header` or `footer` local directives.
+
+```markdown
+---
+header: "Header content"
+footer: "Footer content"
+---
+
+# Page 1
+
+---
+
+## Page 2
+```
+
+In above case, it will render to HTML like this:
+
+```html
+
+ Header content
+
Page 1
+
+
+
+ Header content
+
Page 2
+
+
+```
+
+The specified contents will wrap by a corresponding element, and insert to a right place of each slide.
+
+If you want to place these contents in the marginals of the slide, **you have to use a theme that is supported it.** If not, you could simply see header and footer as the part of slide content.
+
+##### Styling header and footer
+
+In addition, you can format the header and footer content with inline styling through markdown syntax. You can also insert inline images.
+
+```html
+---
+header: "**bold** _italic_"
+footer: "![image](https://example.com/image.jpg)"
+---
+```
+
+> :warning: Marpit uses YAML for parsing directives, so **you should wrap with quotes** when the value includes invalid chars in YAML.
+
+> :information_source: Due to the parsing order of Markdown, you cannot use [slide background images](#slide-background) in `header` and `footer` directives.
+
### Slide backgrounds
We provide a background image syntax to specify slide's background through Markdown. Include `bg` to the alternate text.
@@ -119,8 +170,6 @@ This feature is available regardless of `backgroundSyntax` option in Marpit cons
```
-Marpit uses YAML for parsing directives, so you should wrap by quote when the value includes space.
-
##### Directives
| Spot directive | Description | Default |
@@ -205,10 +254,6 @@ Naturally multiple filters can apply to a image.
![brightness:.8 sepia:50%](https://example.com/image.jpg)
```
-### ToDo
-
-* [ ] Header and footer directive
-
## Markup
### HTML output
@@ -295,6 +340,38 @@ Please refer to [the default style of `section::after` in a scaffold theme](src/
> :information_source: The root `section::after` has preserved a content of page number from Marpit. At present, you cannot use the root `section::after` selector for other use.
+#### Header and footer
+
+`header` element and `footer` element have a possible to be rendered by [local directives](#header-and-footer). _Marpit has no default style for these elements._
+
+If you want to place to marginals of slide, using `position: absolute` would be a good solution.
+
+```css
+section {
+ padding: 50px;
+}
+
+header,
+footer {
+ position: absolute;
+ left: 50px;
+ right: 50px;
+ height: 20px;
+}
+
+header {
+ top: 30px;
+}
+
+footer {
+ bottom: 30px;
+}
+```
+
+Of course, you can use the other way as needed (Flexbox, Grid, etc...).
+
+You can even hide by `display: none` when you are scared a corrupted layout caused by inserted elements. Poof!
+
#### Theme set
The `Marpit` instance has a `themeSet` member that manages usable themes in the `theme` directive of Marpit Markdown. You have to add theme CSS by using `themeSet.add(string)`.
diff --git a/src/markdown/directives/apply.js b/src/markdown/directives/apply.js
index 7e76feb3..fd73657e 100644
--- a/src/markdown/directives/apply.js
+++ b/src/markdown/directives/apply.js
@@ -76,6 +76,12 @@ function apply(md, opts = {}) {
if (marpitDirectives.paginate)
token.attrSet('data-marpit-pagination', marpitSlide + 1)
+ if (marpitDirectives.header)
+ token.meta.marpitHeader = marpitDirectives.header
+
+ if (marpitDirectives.footer)
+ token.meta.marpitFooter = marpitDirectives.footer
+
const styleStr = style.toString()
if (styleStr !== '') token.attrSet('style', styleStr)
})
diff --git a/src/markdown/directives/directives.js b/src/markdown/directives/directives.js
index 4629bce2..1b75ad80 100644
--- a/src/markdown/directives/directives.js
+++ b/src/markdown/directives/directives.js
@@ -45,6 +45,10 @@ export const globals = {
* @prop {Directive} backgroundSize Specify background-size style. The default
* value while setting backgroundImage is `cover`.
* @prop {Directive} class Specify HTML class of section element(s).
+ * @prop {Directive} footer Specify the content of slide footer. It will insert
+ * a `