The "interactive-examples" repository provides interactive examples for MDN Web Docs.
If you're interested in contributing to this project, great! This file should help you get started.
There are many ways you can help improve this repository! For example:
- Write a brand-new example: for example, you might notice that there are no examples for a particular CSS property.
- Improve an existing example: for example, you might notice a problem with an existing example, or some way it could be made more helpful.
- Fix a bug: we have a list of issues, or maybe you found your own.
This guide focuses on contributing examples, although we welcome contributions to the editor and infrastructure code as well.
To contribute live examples all you need is a text editor, git, a GitHub account, and Nodejs.
As far as text/code editors go, there are more editors than you can shake a stick at, so it's down to personal preference. Atom is a great, open source editor we can definitely recommend.
For more information on setting up Git on your machine, read this article.
With the above dependencies satisfied, create your new account on Github.
Lastly, install Nodejs for your operating system.
Next up, you need to fork and clone the repo to be able to contribute to it. You can learn about forking on Github. Once you have your own fork, clone it to your local machine.
Finally, change into the new directory created by the clone and run the following command:
npm install
This will ensure that you have all the required development modules installed to build and test your contributions. You are now ready to contribute. Thank you o/\o
You start off by creating a new file inside the subfolder live-examples\css-examples\
. The name of this file should match the example you are adding. For example, if you are adding examples for border-radius
you would call this file border-radius.html
. On the other hand, the folder name should match the name of the CSS Specification to which the example belongs. For example, border-radius
is part of "CSS Backgrounds and Borders Level 3", hence the example should be created in the "backgrounds-and-borders" folder. This information is available in the specifications section of the documentation on MDN. For example, for border-radius this can be found here.
Inside this newly created file, copy and paste the following code:
<section id="example-choice-list" class="example-choice-list large" data-property="border-radius">
<div class="example-choice" initial-choice="true">
<pre><code class="language-css">Your CSS goes here</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
</section>
<div id="output" class="output large hidden">
<section id="default-example" class="default-example">
<div id="example-element" class="transition-all"></div>
</section>
</div>
This is the base starting point for all CSS examples.
It consists of two main pieces:
-
The example CSS: the
section#example-choice-list
contains one or morediv.example-choice
elements. These are the choices that will be presented to the user on the left-hand side of the editor. Each choice contains some CSS declarations that will be applied to the example element when the user selects that choice. -
The example element: the
section#default-example
contains all the markup for the editor's output pane. At a minimum this will contain a node withid="example-element"
: this is the element that the chosen example CSS will be applied to.
Let's fill this in for border-radius
.
First, we'll specify the example element. For border-radius
it makes sense to have a simple <div>
element with a solid background color. The already present div#example-element
will do. However, let's give it the text "Style Me":
<div id="output" class="output large hidden">
<section id="default-example" class="default-example">
<div id="example-element" class="transition-all">Style Me!</div>
</section>
</div>
When it makes sense to do so, you can also supply additional DOM elements here. For example, the position
example has one box which is the "example-element", but also includes extra boxes to show how setting the position
property for an element interacts with the other elements in a layout.
Next, let's add the example CSS choices. Think of a few different ways that border-radius
can be specified. For each of these, create a new div.example-choice
element nested inside section#example-choice-list
. For example:
<section id="example-choice-list" class="example-choice-list large" data-property="border-radius">
<div class="example-choice" initial-choice="true">
<pre><code class="language-css">border-radius: 10px;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
<div class="example-choice">
<pre><code class="language-css">border-radius: 10px 50%;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
<div class="example-choice">
<pre><code class="language-css">border-radius: 10px 5px 6em / 20px 25px 30%;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
</section>
The first thing to note is that the section
element has a data-property
attribute whose value is the name of the property, border-radius
in this case. The editor uses this to test whether the user's browser supports the property. If it doesn't, then an interactive example won't work, and we just display the CSS options without their output. If you know that the example property has good cross-browser support, you can omit this attribute (for example, the border-radius
example could certainly omit it).
Next, we have three div
elements, one for each example CSS choice. You can choose which option will be shown at first by setting the initial-choice
attribute to true
(only one choice should have this).
Now we've finished writing the HTML for the example. The final version of border-radius.html
should look like this:
<section id="example-choice-list" class="example-choice-list large" data-property="border-radius">
<div class="example-choice" initial-choice="true">
<pre><code class="language-css">border-radius: 10px;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
<div class="example-choice">
<pre><code class="language-css">border-radius: 10px 50%;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
<div class="example-choice">
<pre><code class="language-css">border-radius: 10px 5px 6em / 20px 25px 30%;</code></pre>
<button type="button" class="copy hidden" aria-hidden="true">
<span class="visually-hidden">Copy to Clipboard</span>
</button>
</div>
</section>
<div id="output" class="output large hidden">
<section id="default-example" class="default-example">
<div id="example-element" class="transition-all">Style Me!</div>
</section>
</div>
When you're writing examples, please make sure that they conform to the CSS Example Style Guide.
Next, let's provide some extra styling for the example element. Create a new CSS file inside the current folder. Call this CSS file the same as the HTML file i.e. border-radius.css
. Add the following code to it:
#example-element {
background-color: #74992E;
width: 250px;
height: 80px;
}
Some examples will need to reference media, such as images, from the CSS. Make sure that the license terms for any images are acceptable.
Media files should be stored in the /media/examples directory, and can be referenced using a path like "/media/examples/my-file"
:
background-image: url("/media/examples/lizard.png");
Next, you need to tell the page generator about your new page and its dependencies. To do this, open up the meta.json
file in the current folder (i.e. "live-examples/css-examples/backgrounds-and-borders/meta.json").
Under pages
, copy and paste the example then update it to apply to your new example, noting that pages are sorted alphabetically. You entry will look something like this when edited:
"borderRadius": {
"baseTmpl": "tmpl/live-css-tmpl.html",
"cssExampleSrc": "../../live-examples/css-examples/backgrounds-and-borders/border-radius.css",
"exampleCode": "live-examples/css-examples/backgrounds-and-borders/border-radius.html",
"fileName": "border-radius.html",
"title": "CSS Demo: border-radius",
"type": "css"
},
The title
property is displayed above the editor, and should be of the form: "CSS Demo: {item}", where {item} is the name of the item that the example is for. If you're not sure what to use for {item}, use the title of the page.
All that remains is to test that your page generates and displays as intended, then open a pull request for review.
From your command line run:
npm run build
Once this completes run:
npm start
Now point your browser to localhost:8080/pages/css/border-radius.html.
Once satisfied with the example, submit your pull request.
With a JavaScript example you start by creating a new .html
file in a subfolder of live-examples/js-examples
. In this example we are going to contribute an example demonstrating the use of Array.from
so, we'll create a new file called array-from.html
. Since it is part of the Array
object, we're going to put it inside the "array" subfolder.
Next, you need to paste the following code into this new file (this will be the same for all JavaScript examples you add):
<pre>
<code id="static-js" class="language-js">
</code>
</pre>
Inside the code
block is where our example code will go. Change the code to read as follows:
<pre>
<code id="static-js">// call from(), passing a string
let result = Array.from('foo');
// log the result
console.log(result);
</code>
</pre>
Please make sure the example conforms to the JS Example Style Guide.
NOTE: Should your example exceed the ideal of 12 lines of code, you should set the following
data
attribute on thecode
element. This will ensure the editor height is taller, allowing you up to 23 total lines of example code.
<pre>
<code id="static-js" data-height="taller">// call from(), passing a string
...
All that remains is to tell the page generator about our new example. To do this, open up meta.json
in the current folder (i.e. at "live-examples/js-examples/array/meta.json").
Under pages
, copy and paste the example then update it to your new example, noting that pages are sorted alphabetically.
You entry will look something like the following when edited:
"arrayFrom": {
"baseTmpl": "tmpl/live-js-tmpl.html",
"exampleCode": "live-examples/js-examples/array/array-from.html",
"fileName": "array-from.html",
"title": "JavaScript Demo: Array.from()",
"type": "js"
},
The title
property is displayed above the editor, and should be of the form: "JavaScript Demo: {item}", where {item} is the name of the item that the example is for. If you're not sure what to use for {item}, use the title of the page.
From your command line run:
npm run build
Once this completes run:
npm start
Point your browser to:
localhost:8080/pages/js/array-from.html
Once satisfied with the example, submit your pull request.
Thank you for your contribution ~ o/\o