Skip to content

Latest commit

 

History

History
354 lines (245 loc) · 15.3 KB

CONTRIBUTING.md

File metadata and controls

354 lines (245 loc) · 15.3 KB

Contribution guide

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.

Types of contribution

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.

Setup

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.

Fork and clone

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

Contributing a CSS example

Writing the example

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 more div.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 with id="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.

Styling the example

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;
}

Including media

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");

Updating the metadata

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.

Special rules for CSS functions and types

The guidance above assumes you're documenting a CSS property. But you can also write examples for CSS functions, like linear-gradient(), or types, like angle. If you do this, there are a couple of special considerations.

  • the name of the HTML file you write must be prefixed with function- for functions, or type- for types.
  • in the meta.json file, the name of the output HTML file must be prefixed in the same way.

So the meta.json entry for a function would look like:

"translateX": {
    "baseTmpl": "tmpl/live-css-tmpl.html",
    "cssExampleSrc":
        "../../live-examples/css-examples/transforms/translate.css",
    "exampleCode":
        "live-examples/css-examples/transforms/function-translateX.html",
    "fileName": "function-translateX.html",
    "title": "CSS Demo: translateX()",
    "type": "css"
}

and the meta.json entry for a type would look like:

"angle": {
    "baseTmpl": "tmpl/live-css-tmpl.html",
    "cssExampleSrc": "../../live-examples/css-examples/values-and-units/angle.css",
    "exampleCode": "live-examples/css-examples/values-and-units/type-angle.html",
    "fileName": "type-angle.html",
    "title": "CSS Demo: &lt;angle&gt;",
    "type": "css"
}

Testing

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.

Contributing a JavaScript example

Writing the example

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 the code 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
...

Updating the metadata

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.

Testing

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.

Publishing

After your pull request is reviewed and merged, you can publish your example on MDN Web Docs. On the page that corresponds to the example, add the following to the page source (typically after the introductory paragraph):

<div>{{EmbedInteractiveExample("pages/TYPE/FILENAME")}}</div>

<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>

where TYPE is the kind of example (such as js, css, or html) and FILENAME is the name of the file that contains the example (like margin.html or date-constructor.html).

Thank you!

Thank you for your contribution ~ o/\o