Getting Started with Myth: the Preprocessor of the Future

Originally published at: http://www.sitepoint.com/getting-started-myth-preprocessor-future/

Myth is a CSS preprocessor that will allow you to use new and experimental CSS features in your projects.

Why Use Myth?

With Myth, you can use proposed CSS features even if their W3C specifications are still in development and even if most browsers don’t currently support them.

A big advantage of using Myth over other CSS preprocessors is that you can write your stylesheets using native CSS. You don’t need to learn a new stylesheet language such as Less or Sass.

When these new CSS features gain wide native support in web browsers, you won’t need to manually update your stylesheets because Myth will do it for you. You’d only need to recompile your development stylesheets, and that will only take a couple of seconds.

Here are some CSS features that Myth can implement today:

A Myth Syntax Example

Here’s a quick taste of Myth. The following contains some CSS that’s not yet supported by most browsers:

:root {
  --bgcolor: #0072bc;
  --textcolor: color(var(--bgcolor) lightness(85%));
}

.button {
  display: block;
  width: 90%;
  max-width: 220px;
  padding: 10px;
  background: var(--bgcolor);
  color: var(--textcolor);
  border-radius: 6px;
  transition: background-color 0.4s ease-out,
              color 0.3s ease-out;
}

When compiled, Myth will translate the above into standard CSS that most browsers can understand:

.button {
  display: block;
  width: 90%;
  max-width: 220px;
  padding: 10px;
  background: #0072bc;
  color: rgb(179, 224, 255);
  border-radius: 6px;
  -webkit-transition: background-color 0.4s ease-out,
                      color 0.3s ease-out;
  transition: background-color 0.4s ease-out,
              color 0.3s ease-out;
}

Installing Myth

To set up Myth, you’ll need Node.js. Don’t get turned off; it has installation wizards with graphical user interfaces for Windows and Mac OS users.

Node installation through a GUI

For Windows users, I wrote a tutorial on how to install Node.js on Windows over at my site. The steps for installing Myth on Mac OS are almost identical. Linux users will have to install binaries on their machines.

Once Node is installed, launch the Node.js command prompt.

Launching the Node.js command prompt on Windows OS

To install Myth, use npm (Node’s default package manager) by executing this command from your command prompt:

npm install -g myth

Installing Myth using npm and the Node.js command prompt

Once Myth’s setup is complete, you should see something like this in the command prompt:

Myth installation finished

Creating a Responsive Design with Myth

Let’s build a simple responsive layout using Myth.

Preview of responsive design created with Myth

View demo

Download source files

Details

This is the directory structure of the demo page:

/demo/
|-- /css/
  |-- dev.css
  |-- styles.css
  |-- styles.min.css
|-- /images/
|-- index.html
  • /css/ contains the project’s stylesheets and stylesheet assets
    • dev.css is the development stylesheet and where we’ll code our input CSS
    • styles.css is the Myth-compiled stylesheet. This is the stylesheet that will be used when the site is ready to be deployed.
    • styles.min.css is a minified version of styles.css.
  • /images/ holds the images for our project.
  • index.html is, of course, the page we’re building.

Linking the Input and Output Stylesheets

Use the Node.js command prompt to issue the appropriate command in order to navigate the location of your stylesheets.

cd /path/to/your/folder/css

Where /path/to/your/folder/css would be the location of your stylesheets on your computer or web server.

The next thing you need to do is tell Myth that our development stylesheet is dev.css and that our compiled stylesheet is styles.css. We’d also like it to watch out for changes to dev.css so it updates and compiles styles.css automatically whenever we change our development stylesheet.

myth --watch dev.css styles.css

If you want to compile manually, just leave out the --watch option:

myth dev.css styles.css

Note that dev.css must already be created for the command to work. However, styles.css will be automatically created if it doesn’t exist. Also, these stylesheets can have whatever file name you want.

Adding Myth’s CSS

You can view the markup in the demos files to see how the example site is laid out. Once the HTML is in place, below is the CSS we’ll use inside dev.css. It liberally uses experimental, future and proposed CSS specs like variables, custom media queries, color functions, and so forth.

(Use the vertical scroll bar to see all the code.)

:root {
  --max-width: 960px;
  --gutter: 2%;
  --base-size: 17px;
  --small-size: 14px;
  --base-lineheight: 1.4;
  --default-color: #464646;
  --default-bgcolor: #fff;
  --link-color: #0072bc;
  --dark-bgcolor: #759ea1;
  --dark-bgcolor-text-color: color(var(--dark-bgcolor) lightness(85%));
  --highlight-color: firebrick;
}

@custom-media --small-devices (max-width: 400px);
@custom-media --medium-devices (min-width: 401px) and (max-width: 750px);

* { 
  margin: 0;
  padding: 0;
}

body {
  background: var(--default-bgcolor);
  color: var(--default-color);
  font: normal var(--base-size)/var(--base-lineheight) "Roboto", sans-serif;
  text-align: center;
}

img {
  width: 100%;
  height: auto;
}

/* Typography */
h1, h2, h3, p {
  margin: 5px auto 20px auto;
}

h1 {
  font-size: calc(var(--base-size) * 3);
  line-height: calc((var(--base-size) * 3) * var(--base-lineheight));
}

h2 {
  font-size: calc(var(--base-size) * 2);
  font-weight: 400;
  line-height: calc((var(--base-size) * 2) * var(--base-lineheight));
  color: color(var(--highlight-color) saturation(-20%));
}

h3 {
  font-size: calc(var(--base-size) * 1.2);
  font-weight: 400;
  line-height: calc((var(--base-size) * 1.2) * var(--base-lineheight));
  color: color(var(--highlight-color) saturation(+50%));
}

a {
  color: var(--link-color);
  text-decoration: none;
  transition: color 0.2s ease-in;
}

a:hover {
  color: color(var(--link-color) lightness(-10%));
  transition: color 0.4s ease-out;
}

/* Layout */
header {
  display: block;
  width: 100%;
  min-height: 500px;
  padding-top: 100px;
  background: var(--dark-bgcolor)
              url(header-bg.jpg) no-repeat center center;
  background-size: cover;
  background-attachment: fixed;
  color: var(--dark-bgcolor-text-color);  
}

.container {
  position: relative;
  width: 96%;
  max-width: var(--max-width);
  margin: 0 auto;
}

.fullcol, .halfcol, .fourthcol {
  float: left;
  box-sizing: border-box;
  margin-left: var(--gutter); 
}

.container .fullcol,
.container .halfcol:first-child,
.container .fourthcol:first-child  {
  margin-left: 0;
}

.fullcol {
  width: 100%;
  text-align: center;
}

.halfcol {
  width: calc((100% - var(--gutter)) / 2);
}

.fourthcol {
  width: calc(((100% - (var(--gutter) * 3)) / 4));
}

section {
  float: left;
  width: 100%;
  padding-top: 80px;
  padding-bottom: 80px;
}

/* Special */
.logo {
  margin-top: 0;
  font-family: "Montserrat", sans-serif;
  font-weight: 400;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 2px;
}

.tagline {
  text-transform: uppercase;
}

.button {
  display: block;
  width: 90%;
  max-width: 220px;
  margin: 30px auto 50px auto;
  background: var(--link-color);
  color: var(--dark-bgcolor-text-color);
  border-radius: 6px;
  padding: 10px;
  transition: background-color 0.4s ease-out, color 0.3s ease-out;
}

.button:hover {
  background: color(var(--link-color) tint(50%));
  color: color(var(--dark-bgcolor-text-color) whiteness(100%));
  transition: background-color 0.3s ease-in, color 0.2s ease-in;
}

.credits {
  margin: 80px auto 20px auto;
  font-size: calc(var(--base-size) * 0.75);
  color: color(var(--dark-bgcolor-text-color) hue(+120%));
}

#work {
  background: color(var(--dark-bgcolor) lightness(+30%));
}

#contact {
  background: color(var(--highlight-color) saturation(-30%));
  color: var(--dark-bgcolor-text-color);
}

#contact h2 {
  color: color(var(--dark-bgcolor-text-color) saturation(+20%));
}

/* Media Queries */
@media (--small-devices) {
  .fullcol, .halfcol, .fourthcol {
    width: 100%;
    margin-left: 0;
    text-align: center;
  }

  .button, .tagline {
    font-size: var(--small-size);
  }

  .logo {
    margin-top: 0;
    font-size: calc(var(--base-size) * 1.8);
    line-height: calc((var(--base-size) * 1.8) * var(--base-lineheight));
  }
}

@media (--medium-devices) {
  .fourthcol {
    width: calc((100% - var(--gutter)) / 2);
    margin-left: var(--gutter);
    margin-bottom: 20px;
  }

  .container .fourthcol:nth-child(odd) {
    margin-left: 0;
    clear: left;
  }
}

The CSS Output

Here is the compiled output in styles.css. You can see that Myth translates our CSS so that today’s browsers can render it. Also notice that Myth will automatically format and indent the CSS output, ignoring our preferred indentation scheme.

(Use the vertical scroll bar to see all the code.)

/* Basic */

* {
  margin: 0;
  padding: 0;
}

body {
  background: #fff;
  color: #464646;
  font: normal 17px/1.4 "Roboto", sans-serif;
  text-align: center;
}

img {
  width: 100%;
  height: auto;
}

/* Typography */

h1,
h2,
h3,
p {
  margin: 5px auto 20px auto;
}

h1 {
  font-size: 51px;
  line-height: 71.39999999999999px;
}

h2 {
  font-size: 34px;
  font-weight: 400;
  line-height: 47.599999999999994px;
  color: rgb(159, 56, 56);
}

h3 {
  font-size: 20.4px;
  font-weight: 400;
  line-height: 28.559999999999995px;
  color: rgb(214, 0, 0);
}

a {
  color: #0072bc;
  text-decoration: none;
  -webkit-transition: color 0.2s ease-in;
  transition: color 0.2s ease-in;
}

a:hover {
  color: rgb(0, 83, 138);
  -webkit-transition: color 0.4s ease-out;
  transition: color 0.4s ease-out;
}

/* Layout */

header {
  display: block;
  width: 100%;
  min-height: 500px;
  padding-top: 100px;
  background: #759ea1 url(header-bg.jpg) no-repeat center center;
  background-size: cover;
  background-attachment: fixed;
  color: rgb(209, 223, 224);
}

.container {
  position: relative;
  width: 96%;
  max-width: 960px;
  margin: 0 auto;
}

.fullcol,
.halfcol,
.fourthcol {
  float: left;
  box-sizing: border-box;
  margin-left: 2%;
}

.container .fullcol,
.container .halfcol:first-child,
.container .fourthcol:first-child {
  margin-left: 0;
}

.fullcol {
  width: 100%;
  text-align: center;
}

.halfcol {
  width: 49%;
}

.fourthcol {
  width: 23.5%;
}

section {
  float: left;
  width: 100%;
  padding-top: 80px;
  padding-bottom: 80px;
}

/* Special */

.logo {
  margin-top: 0;
  font-family: "Montserrat", sans-serif;
  font-weight: 400;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 2px;
}

.tagline {
  text-transform: uppercase;
}

.button {
  display: block;
  width: 90%;
  max-width: 220px;
  margin: 30px auto 50px auto;
  background: #0072bc;
  color: rgb(209, 223, 224);
  border-radius: 6px;
  padding: 10px;
  -webkit-transition: background-color 0.4s ease-out, color 0.3s ease-out;
  transition: background-color 0.4s ease-out, color 0.3s ease-out;
}

.button:hover {
  background: rgb(128, 185, 222);
  color: rgb(228, 228, 228);
  -webkit-transition: background-color 0.3s ease-in, color 0.2s ease-in;
  transition: background-color 0.3s ease-in, color 0.2s ease-in;
}

.credits {
  margin: 80px auto 20px auto;
  font-size: 12.75px;
  color: rgb(224, 209, 223);
}

#work {
  background: rgb(209, 223, 224);
}

#contact {
  background: rgb(148, 66, 66);
  color: rgb(209, 223, 224);
}

#contact h2 {
  color: rgb(202, 230, 232);
}

/* Media Queries */

@media (max-width: 400px) {
  .fullcol,
  .halfcol,
  .fourthcol {
    width: 100%;
    margin-left: 0;
    text-align: center;
  }

  .button,
  .tagline {
    font-size: 14px;
  }

  .logo {
    margin-top: 0;
    font-size: 30.6px;
    line-height: 42.839999999999996px;
  }
}

@media (min-width: 401px) and (max-width: 750px) {
  .fourthcol {
    width: 49%;
    margin-left: 2%;
    margin-bottom: 20px;
  }

  .container .fourthcol:nth-child(odd) {
    margin-left: 0;
    clear: left;
  }
}

Debugging

When you compile your development stylesheets, Myth will issue error notifications in the Node.js command prompt, so it’s a key debugging tool.

For instance, if a custom media query wasn’t defined, you will see this:

A Myth error warning in the Node.js command prompt

Myth’s error notifications will tell us:

  • What went wrong.
  • The line number where the problem if found.
  • What Myth did in response to the error.
  • The suggested fix.

Optimizing CSS for Better Performance

When you’re ready to deploy the project to a web server, a simple thing you can do to improve your site’s performance is to minify your stylesheets. Myth can do this for you if you use the --compress option:

myth --compress dev.css styles.css

In our example, the stylesheet’s file size decreased by 20% simply by using the --compress option.

Other Myth Command Options

There are shortcuts for Myth command options. For example:

myth --compress --watch dev.css styles.css

Can instead be issued as:

myth -c -w dev.css styles.css

Head over to the Myth’s README on GitHub for the most updated list of commands.

Conclusion

Myth is a great CSS preprocessor for developers who can’t wait to use some of the experimental CSS features. It’s easy to set up and use, and, unlike other options, you don’t need to learn a new stylesheet language syntax to be able to use it.

Once again, here are the links to the demo and the files to download:

View demo

Download source files

Continue reading this article on SitePoint

I’m glad that this is the case; I dislike the almost NEW syntax preprocessors force on users. I’m glad Myth is taking a step in the right direction.

Not sure you can actually say this about Sass or Less. These preprocessors are just extensions to CSS to add new features to the CSS language. You can write plain CSS if you want so the only difference would be the extension. I do like that Myth will convert some new CSS features like variables though. And once some of these features gain widespread support, it is slightly easier to drop the preprocessor and just start using CSS again.

1 Like

you’ll need Node.js. Don’t get turned off

Hehe, love that bit I bolded. So many articles need that line, as this is where I usually jump ship.

The fact that you don’t have to learn a new language, but can focus on learning new things about the real one, is a great selling point. I still don’t know if I can be bothered learning how to use it, though. Writing CSS is so simple anyway (though admittedly I’m not involved in big projects where I can see it would be worth the investment to learn about preprocessing).

I never understood the argument that it’s easy to update if you change your websites design. If I change my desing of a website, then 99% of the time the HTML structure will chagne, making my old CSS useless.

But if you want to change a single color value that’s used all over the place you might change your mind. Of course, you can do that with search and replace, too, though you may not want to replace every instance of the color (maybe just font color but not background color, for example).

Then I’d narrow my search to search for color but not background color. Any decent editor can search for that.

You can copy and paste raw CSS into both SCSS and LESS for the most part. Neither force anything on the user and you can choose to include or use their syntax as you please. This is not a selling point for Myth.

Honestly, I don’t see any purpose for Myth. I mean it’s good to have competition at all, but at this point with a lot of these late comers it just seems like this xkcd:

There are other situations where it would be harder, of course. How would you target one of these but not the other?

border: 1px solid #30353b;
background: #30353b url(/images/image.png);

(Heh, sounds like I am arguing for preprocessors!)

Perhaps I could have done a better job wording that. But, yes, you do have to learn some new syntax when using other preprocessors.

This is the variable syntax for LESS:

@link-color: blue;

This is the variable syntax for CSS:

:root {
    --link-color: blue;
}

They are different from each other.

Honestly, I like Less syntax better than CSS syntax.

I’m not saying that it will be like learning a completely foreign language in order to use preprocessors. The popular preprocessors have syntaxes that are intuitive if you already know CSS. This is because much of the syntax, such as declaring properties and selectors, are based on CSS.

My one worry about a preprocessor that anticipates future CSS is that those proposals will inevitably evolve and change over time before they are ready for use. So it’s not necessarily a good investment of time to learn things that might change a lot, and the processor will have to decide what to do with out of date stuff.

Wrong yes any decent editor can do that, however with CSS Preprocessors it’s easy to create themes add flexible rules. I can easily create highlights of buttons by getting the color and moving 10 values up number to brighten it. Another major advantage is code organization which i find very useful its easy to organize codes and inherit maybe . The framework I use is Dojotoolkit,in order to create a custom theme we simply alter the variable and function and viola a new kickass theme is born. However i’d like to know advantage of Myth over Stylus, Stylus seems more like Python with CSS on steroids.
(Edited:Sorry made some typos, i type too fast)

1 Like

I moved a post to an existing topic: Welcome to The New SitePoint Forums

I wrote an article that discusses what I believe to be the best CSS preprocessors (which includes Myth and Stylus). That article might shed some light about the advantages and disadvantages between using one or the other.

1 Like

That is a valid concern! Thank you for mentioning this point. This is something anyone thinking about using Myth should keep in mind.

There’s always the possibility that the specs will change between now to final rec.

In production, since we’re deploying stylesheets that use final rec CSS specs, there’s no issue at all, the site will be unaffected with any sudden spec change.

But it is definitely a maintainability concern though: We need think about the steps we will take if the proposed specs change significantly between our initial development and a development-iteration/redesign/feature launch we are working on.

For example, what will we do if the CSS variable syntax is changed in a couple of years and we’re going back to update one of the sites we built with Myth? Will we update our input/development stylesheets to whatever the newest specs are? Or will we just stick to a backwards-compatible release of Myth and just develop with the “original” proposed specs we used during initial development?

1 Like

I strongly disagree, a preprocessor does so much more. It’s not just about changing a color value. Some examples:

  • loops help you to avoid repetitive code (i.e. if you have different areas on your site, each one in a different color/style) and make changes much easier (than being forced to replace the values multiple times)
  • true, it’s quite unlikely that you’ve used the same color for different things, but what about measures of length? As soon as you’ve got numbers, search and replace will be much harder as the same ones are used in different contexts. Furthermore search and replace will fail if different color syntax’s (#hex, rgb, rgba) are used.
  • nesting of selectors saves time (no need to repeat the long selector list all the time) and provides much better readability
  • You intrinsically avoid “magic numbers”. If you need to calculate a value, you don’t write the result, but the expression. e.g. instead of writing “12.66667em” you write something like “$parent-width - $margin-left - $margin-right”, which is some sort of documentation out of the box

When porting a huge project to SASS (design/structure remained very similar), the new sass-project had ~2.800 lines, whereas the old CSS-Project had ~12.000 lines. Of course there were some other optimizations as well, but about 60-80% of the savings was due to SASS (loops, no need for prefixes, nesting)

Have you used any Preprocessor ever intensively in a real project? I would never want to switch back again (unfortunately I’m from time to time forced to use plain old CSS again in legacy projects…and it’s a pain)!

1 Like

I work on a ~9000 page website where SASS is used, so yes I think this project is big enough.

I have used preprocessors before.

I’ve never refuted any of your benefits that you are listing so I’m not sure why you feel the need ot remind me of them.

It seems that a straight-forward find/replace using a regular expression would do the job well there.

Find: border:(.)#30353b(.)
Replace: border:\1#30353f\2

Hm, can you do that in a text editor? Will have to try it.

Not in a simple editor like Notepad, but Notepad++ has the feature