<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Tobias Reich on Medium]]></title>
        <description><![CDATA[Stories by Tobias Reich on Medium]]></description>
        <link>https://medium.com/@electerious?source=rss-5f0b44d665e9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*espMLzCZ_T0sw9je2FCiGg@2x.png</url>
            <title>Stories by Tobias Reich on Medium</title>
            <link>https://medium.com/@electerious?source=rss-5f0b44d665e9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 04:30:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@electerious/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[From CommonJS to ES Modules: How to modernize your Node.js app]]></title>
            <link>https://electerious.medium.com/from-commonjs-to-es-modules-how-to-modernize-your-node-js-app-ad8cdd4fb662?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/ad8cdd4fb662</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[modules]]></category>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[commonjs]]></category>
            <category><![CDATA[ecmascript-6]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Mon, 22 Mar 2021 16:03:44 GMT</pubDate>
            <atom:updated>2021-03-22T16:03:44.305Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pz-vT_at9d5FjBNbx19iXA.png" /></figure><p>I recently ported a midsized, vanilla Node.js app from CommonJS to ES Modules. Here’s what I learned and how you can modernize your project step by step.</p><h3>What’s the difference between CommonJS and ES Modules?</h3><p>While CommonJS is de facto everywhere in the Node.js universe, it’s safe to say that ES Modules are the future. They’re now <a href="https://tc39.es/ecma262/#sec-modules">the official standard</a> format to package JavaScript code for reuse. No matter if in the browser or in Node.js, both systems allow you to import and export code from different files, making it possible to split your project into junks of self-contained functionality.</p><pre>// CJS<br>const utils = require(&#39;../utils&#39;)<br>const funcA = () =&gt; {}<br>const funcB = () =&gt; {}<br>module.exports = { funcA, funcB }</pre><pre>// ESM<br>import { utilA } from &#39;../utils/index.js&#39;<br>export const funcA = () =&gt; {}<br>export const funcB = () =&gt; {}</pre><p>You might already use ES Modules in the browser (probably with the help of webpack or a module bundler of your choice). I therefore won’t go into further details. <a href="https://medium.com/u/19c90c54b753">Mahdhi Rezvi</a> has <a href="https://blog.bitsrc.io/understanding-es-modules-in-javascript-a28fec420f73">a great blog post</a> explaining the differences of both systems in depth if you aren’t familiar with them. What matters for this guide is that the current version of Node.js has a solid support for ES Modules. The feature isn’t hidden behind a flag anymore and the official docs are marking ECMAScript modules as “stable”.</p><p>It’s time to bring your app into the future of JS development 🚀</p><h3>Tips along the way</h3><ul><li>Most changes are small, but there’re a lot of them. It will take a while to adjust all exports and imports and your code won’t run in the meantime. You shouldn’t start this task at the end of the day.</li><li>I recommend to use <a href="https://prettier.io/">prettier</a> and <a href="https://eslint.org/">eslint</a>. It’s optional, but it will make your life a lot easier. We need to modify every single file and those tools help us to keep the formatting consistent, while also checking errors we overlooked. Especially the eslint plugin “<a href="https://github.com/benmosher/eslint-plugin-import">eslint-plugin-import</a>” has rules that are relevant for us. Rules that verify our imports. Make sure to configure at least <a href="https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md">import/no-unresolved</a>, <a href="https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md">import/no-commonjs</a> and <a href="https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md">import/extensions</a>.</li></ul><pre>{<br>  ...<br>  &quot;plugins&quot;: [&quot;import&quot;],<br>  &quot;rules&quot;: {<br>    &quot;import/no-unresolved&quot;: 2,<br>    &quot;import/no-commonjs&quot;: 2,<br>    &quot;import/extensions&quot;: [2, &quot;ignorePackages&quot;]<br>  }<br>}</pre><h3>Step by step: From CommonJS to ES Modules</h3><h4>1) Prepare your code</h4><p>Everything is easier when you and your code are prepared.</p><ul><li>Check that your Git working copy is empty, start a new branch, update your dependencies and ensure that your tests are succeeding.</li><li>Install the latest Node.js version (at least <a href="https://nodejs.org/en/download/">the current LTS</a>) and verify that your app is running smoothly after the update.</li></ul><p>Commit all changes, brew yourself a coffee and take a deep breath. It’s showtime🧑‍💻</p><h4>2) Update the package.json</h4><p>Tell Node.js that all files are ES Modules by adding &quot;type&quot;: &quot;module&quot; to the package.json. You can alternatively use the .mjs file extension for all your files, but I prefer the former.</p><pre>{<br>  &quot;name&quot;: example&quot;,<br>  &quot;version&quot;: &quot;1.0.0&quot;,<br>  &quot;type&quot;: &quot;module&quot;,<br>  ...<br>}</pre><h4>3) Convert all imports and exports</h4><p>You can do this by hand when your project only has a few files, but it’s a painful process for any midsized Node.js app.</p><p><a href="https://github.com/nolanlawson/cjs-to-es6">cjs-to-es6</a> is a CLI that converts JavaScript files from CommonJS to ES6 Modules. It’s unmaintained, but still the best tool I could find. It successfully ported around 80% of my files. That’s fine. Both modules systems are different and not everything can be converted 1:1.</p><p>Run the tool with the verbose flag to see which files failed: cjs-to-es6 --verbose src/.</p><h4>4) Fix imports and exports</h4><p>As already mentioned—Both modules systems are different. It’s impossible to convert all files automatically. While cjs-to-es6 is a big help, it’s still necessary to look at each file individually. Here’re a few issues I had and how I fixed them:</p><p><strong>File extensions</strong></p><p>cjs-to-es6 converts const package = require(&#39;package&#39;) to import package from &#39;package&#39; and const localFile = require(&#39;../utils/localFile&#39;) to import localFile from &#39;../utils/localFile&#39;. That’s fine. At least for the external package.</p><p>Local file imports require a file extension. Every import <strong>must</strong> end with .js (or .mjs depending on your choice). You might haven’t seen this before, because it’s not necessary in the browser (when using a module bundler), but this is how ES Modules work. File imports are URLs.</p><p>Do this:</p><pre>import something from &#39;./something.js&#39;</pre><p>Don’t do this:</p><pre>import something from &#39;./something&#39;</pre><p><strong>Directory indexes</strong></p><p>Directory indexes must be fully specified. Importing ../utils won’t magically import the index.js anymore.</p><p>Do this:</p><pre>import * as utils from &#39;../utils/index.js&#39;</pre><p>Don’t do this:</p><pre>import * as utils from &#39;../utils&#39;</pre><p><strong>Object exports</strong></p><p>It was common to export an object of functions when a file had multiple functions to expose. You can still export objects, but this isn’t the correct way anymore. Instead, add export in front of every function or variable you want to export. This has the advantage that you can now import them individually via import { funcA, funcB } from &#39;../utils/index.js&#39; or all at once via import * as utils from &#39;../utils/index.js&#39;.</p><p>Do this:</p><pre>export const funcA = () =&gt; {}<br>export const funcB = () =&gt; {}</pre><p>Don’t do this:</p><pre>const funcA = () =&gt; {}<br>const funcB = () =&gt; {}</pre><pre>export default {<br>  funcA,<br>  funcB<br>}</pre><p><strong>Broken imports of external modules</strong></p><p>You might need to adjust the import of some external npm packages depending on how they export their code. Checking the GitHub repo for existing issues usually does the job. Sometimes it can also help to try a few common ESM imports to see where the code you’re looking for is hidden behind.</p><p>In my case it only got confusing when the module exported an object (see “Object exports”). In this case you can’t import a property or function directly via import { funcA } from &#39;package&#39;. You instead need to import the object and access the function you’re looking for later on.</p><p>This works when the export is an object:</p><pre>import signale from &#39;signale&#39;</pre><pre>const instance = new signale.Signale()</pre><p>This won’t:</p><pre>import { Signale } from &#39;signale&#39;<br>import * as signale from &#39;signale&#39;</pre><p><strong>JSON imports</strong></p><p>This made me a bit sad. It’s currently not possible to import JSON files, but there’re three ways to get around this problem:</p><ul><li>Use fs to read the content of a JSON file and parse it using JSON.parse</li><li>Use JS modules instead of JSON and export an object</li><li>Use the experimental --experimental-json-modules Node.js flag</li></ul><p><strong>ESLint</strong></p><p>I had to rename my eslintrc.js to eslintrc.cjs, because ESLint <a href="https://github.com/eslint/eslint/issues/12593">doesn’t support ES Modules</a>, yet. Using a JSON instead of a JS configuration also does the job.</p><blockquote>Note that we can’t support .mjs configuration files yet due to ESLint currently being synchronous in nature. — <a href="https://github.com/kaicataldo">kaicataldo</a></blockquote><p><strong>NYC Code Coverage</strong></p><p>Are you using nyc (the Istanbul command line interface that reports the code covered by your tests)? It’s not ready for the future, yet. The good thing is that <a href="https://v8.dev/">V8</a> (the JavaScript engine behind Node.js) has code coverage built-in. You can take advantage of it using <a href="https://github.com/bcoe/c8">c8</a>. A CLI similar to nyc. And because it relies on the build-in V8 code coverage it always works with the newest syntax supported by Node.js.</p><p><strong>Miscellaneous</strong></p><p>I’m sure that you will run into specific issues not covered by this guide. Every code is different. Make sure to take a look <a href="https://nodejs.org/api/esm.html">at the Node.js documentation</a> before searching the web. It’s up-to-date and contains everything you need to know on one page.</p><h4>5) Verify your changes</h4><p>It’s time to check if everything went well. Use prettier to clean up your code and let eslint check your imports (this is where <a href="https://github.com/benmosher/eslint-plugin-import">eslint-plugin-import</a> is a big help). Run your app to see if there’re obvious errors. I’m sure that your app won’t launch on the first try. There’s always a file that has been overlooked 🙄</p><h3>Congratulation</h3><p>You successfully ported your Node.js app to ES Modules 👏 I hope this article made the process a bit easier. Let me know what you think and what issues bothered you during the conversion!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ad8cdd4fb662" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Directional link effects with CSS variables]]></title>
            <link>https://blog.prototypr.io/directional-link-effects-with-css-variables-37468bed4c3d?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/37468bed4c3d</guid>
            <category><![CDATA[design]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[interaction-design]]></category>
            <category><![CDATA[js]]></category>
            <category><![CDATA[animation]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Mon, 18 Nov 2019 12:27:46 GMT</pubDate>
            <atom:updated>2019-11-18T12:27:46.115Z</atom:updated>
            <content:encoded><![CDATA[<p>You might know that I <a href="https://blog.prototypr.io/stunning-hover-effects-with-css-variables-f855e7b95330">really</a>, <a href="https://medium.com/@electerious/the-power-of-css-variables-6c4e4ebaf279">really</a> like CSS variables and <a href="https://medium.com/@electerious/parallax-scrolling-with-js-controlled-css-variables-63cfe96820c7">what you can do with them</a>. Changing them in JS is like using useState in React: The browser automatically re-renders the necessary parts. This allows you to build powerful effects in a few lines of code. My favourite is to track the position of the mouse to build directional cursor effects. Believe me: It’s a small detail, but you can’t stop hovering once you’ve seen it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*1DiRqDmxbXppvomn70sBFg.gif" /></figure><p>This guide explains the little magic behind the hover effect I’ve made for the <a href="https://ackee.electerious.com/">menu of the Ackee site</a>. Let’s start! 🚀</p><h3>Track the position</h3><p>We need to know the position of the cursor to build a directional effect. This can be done in JS.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e451dcb3a6526ce387eff7925c8a01bf/href">https://medium.com/media/e451dcb3a6526ce387eff7925c8a01bf/href</a></iframe><p>The CSS variable --x now contains the position of the mouse relative to the element. It will update whenever the mouse enters and leaves the element.</p><p>Reality however showed me that it looks a little bit weird when x is near, but not exactly left (0) or right (elem.clientWidth). Let’s fix this by adding a tolerance.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/588b69caa00d724f4c4ed1345334c718/href">https://medium.com/media/588b69caa00d724f4c4ed1345334c718/href</a></iframe><h3>The styling</h3><p>text-decoration: underline can’t be animated. We’re therefore adding a line below the element using an ::after pseudo element.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0910d00d9516651ab303da41f17a4d43/href">https://medium.com/media/0910d00d9516651ab303da41f17a4d43/href</a></iframe><ol><li>Remove the default styling of the link</li><li>Add a custom underline</li><li>Use --scale to show and hide the underline (starting with 0 = hidden)</li><li>Use --x to define the origin of the scale transform (the position of the mouse)</li><li>Show the underline by changing the --scale variable</li></ol><h3>The result</h3><p>That’s it already. A few lines of code and hovering links makes fun, again. Add the missing HTML and enjoy:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Felecterious%2Fembed%2Fpreview%2FxeJPbB%3Fheight%3D600%26slug-hash%3DxeJPbB%26default-tabs%3Dcss%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2Felecterious%2Fpen%2FxeJPbB&amp;image=https%3A%2F%2Fscreenshot.codepen.io%2F136245.xeJPbB.small.17f442fd-1308-4bee-8111-c6e26c9b4ddc.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/edd235ac94f515a34355a5ba407d6a2a/href">https://medium.com/media/edd235ac94f515a34355a5ba407d6a2a/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37468bed4c3d" width="1" height="1" alt=""><hr><p><a href="https://blog.prototypr.io/directional-link-effects-with-css-variables-37468bed4c3d">Directional link effects with CSS variables</a> was originally published in <a href="https://blog.prototypr.io/">Prototypr</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rocking Swift and iOS development in 3 months]]></title>
            <link>https://electerious.medium.com/rocking-swift-and-ios-development-in-3-months-85405f1dff10?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/85405f1dff10</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[iphone]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Tue, 12 Feb 2019 08:35:35 GMT</pubDate>
            <atom:updated>2019-02-12T08:44:58.711Z</atom:updated>
            <content:encoded><![CDATA[<p>Swift and iOS development was on my bucket list for quite some time. I always had some ideas on my mind and couldn’t wait to bring them to a device I use daily. But building an app with a language you don’t know, on a system you haven’t developed on before, isn’t something you can do in a few days. It requires time.</p><p>November last year I finally had the opportunity to go part time and to spend three days a week on my goal. For three months ⏱</p><p>My personal ambition was to learn Swift and iOS development in the given time and to test and approve my new knowledge by publishing an app to the App Store 📲</p><h3>Prior knowledge</h3><p>Swift isn’t my first language. I’m a Front-End developer specialised in JavaScript development. I’ve worked with other object-oriented languages before and I also know how to design user-interfaces.</p><p>I guess it’s important to say that ~36 days aren’t enough when you don’t have any background in programming. And it’s by far not enough time to become a Swift expert. But don’t be scared. Swift is a language that’s good to read and learn. The amount of tutorials is fantastic for such a young language.</p><h3>Rocking Swift and iOS</h3><h4>Step 1</h4><p>For the beginning I recommend to <strong>start with a tutorial series or book that takes you by hand and guides you through all the basics</strong>. Something you can follow step by step. It helps you to get familiar, without getting lost in all the topics.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CyOQS6lEFhTSDeLi4HFGyA.png" /><figcaption><a href="https://designcode.io/">Design+Code</a> is great to get started</figcaption></figure><p>I’ve used <a href="https://designcode.io/">Design+Code</a> to get started. It covers everything from design and basics to advanced Swift features. And with $9 per month it’s also a very cheap way to bring yourself to the next level. Design+Code was a great help for me, but the course isn’t completely up-to-date. You might run into issues when using the latest version of Xcode and Swift.</p><p>Whatever you choose to get started, choose something you can follow and rely on. This gives you a feeling of progress as you’re doing one step at a time. Don’t pick videos or articles from different sources. They may vary in their quality and make it harder in the beginning.</p><h4>Step 2</h4><p>One of the best resources for Swift comes straight from the source: <strong>The official </strong><a href="https://itunes.apple.com/de/book/the-swift-programming-language-swift-4-2/id881256329?mt=11"><strong>Swift Book</strong> from Apple</a> is by far one of the best programming language books. It contains everything you need to know about Swift. And it won’t cost you anything.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ujVsZ1-6Q8pOePOPwMK8wQ.png" /><figcaption>The Swift Programming Language</figcaption></figure><p>You can start reading it from day one or you can continue with it after you’re done with the first step. This way you will get that “Ahhh” feeling as everything you’ve learned before becomes clearer 🤓</p><p>Understanding a language makes your life easier. So why don’t start with the book? Be honest: You’re learning a language because you want to do cool stuff. Not because you want to read a documentation. That’s why it’s good to start practical first.</p><h4>Step 3</h4><p>Design plays an imported role in iOS development. Take a look at the apps featured by Apple. They are all very well designed. To succeed on the App Store you need to keep up with them or at least try to.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*14sdKM0JMcavsbS-tGthyw.png" /><figcaption>Apple Design Resources</figcaption></figure><p>The <a href="https://developer.apple.com/design/human-interface-guidelines/">Human Interface Guidelines</a> provided by Apple are a must-read before you start with the design of your app.</p><p>Apple also provides a lot of helpful resources and insights <a href="https://developer.apple.com/design/resources/">on their website</a>.</p><h4>Step 4</h4><p>There is no better way to learn something than to build and ship. That’s why this step was the one I was most excited about: It was time to start with my app. Two months were left ⏱</p><p>At this point you should already be familiar with the basics of Swift and iOS development, but keep in mind that this is your first app. It should be basic and possible to build in short time. Search the internet whenever you’re running into a problem or question. I’ve done this million times during this stage. The “Resources” section includes a few links to help you.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*glVfeXOYqgpGdY3qPUKOFw.png" /><figcaption>“The Last Time”, now <a href="https://itunes.apple.com/us/app/the-last-time-days-tracker/id1448605380?mt=8">available on the App Store</a></figcaption></figure><p>I decided to build a days tracker. An app that counts the passed days since an event occurred. How else should you know when you’ve visited the dentist the last time? Or when you’ve called you parents?</p><p>The app is called “The Last Time”. And yes, it’s <a href="https://itunes.apple.com/us/app/the-last-time-days-tracker/id1448605380?mt=8">available on the App Store</a> 🎉</p><h3>Resources</h3><p>Here’s a list of resources I’ve used to learn Swift and iOS. My favourites are marked with a star.</p><ul><li><a href="https://designcode.io/">Design+Code</a> is good to get started</li><li><a href="https://geo.itunes.apple.com/us/book/the-swift-programming-language-swift-4-2/id881256329?mt=11">The Swift Programming Language</a> book contains everything you need to know about Swift 🌟</li><li><a href="https://cocoacasts.com/">Cocoacasts</a> offer a clear roadmap to anyone interested in learning Swift development</li><li>The <a href="https://developer.apple.com/design/human-interface-guidelines/">Human Interface Guidelines</a> provided by Apple are must read before you start with your design</li><li><a href="https://ivomynttinen.com/blog/ios-design-guidelines">iOS Design Guidelines</a> is a short version of the HIG from Apple, written by <a href="https://medium.com/u/32df654b788f">Ivo Mynttinen</a></li><li><a href="https://medium.com/@kamushken/designing-for-iphone-ios-12-native-components-styles-6a03ece069ea">Designing for iPhone (iOS 12 native components UI styles)</a> shows you what’s possible to build without writing tons of custom UI</li><li><a href="https://www.youtube.com/channel/UCbTw29mcP12YlTt1EpUaVJw">Sean Allen’s YouTube channel</a> contains fantastic, short tutorials and a great Swift News series 🌟</li><li><a href="https://www.youtube.com/channel/UCuP2vJ6kRutQBfRmdcI92mA">Lets Build That App</a> has practical videos that teach you how to build real features 🌟</li><li><a href="https://www.youtube.com/channel/UCqndzS37vNHVrqLVAKEP2HQ">iOS Compressed</a> is perfect when you want to learn something in short time</li><li><a href="https://theswiftdev.com/">The.Swift.Dev.</a> is a blog with tutorials and more</li><li><a href="https://medium.freecodecamp.org/ux-best-practices-how-to-design-scannable-app-screenshots-89e370bf433e">How to Design Scannable App Screenshots</a> is helpful to read before you publish your app</li></ul><h3>Conclusion</h3><p>I’m happy that I took the opportunity. I’ve learned so many things in three months that I can’t wait to build more. It’s way easier to continue once you know the basics. Give Swift a try!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=85405f1dff10" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The ultimate guide for the perfect <form>]]></title>
            <link>https://electerious.medium.com/the-ultimate-guide-for-the-perfect-form-f52b7ee0fd29?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/f52b7ee0fd29</guid>
            <category><![CDATA[user-experience]]></category>
            <category><![CDATA[input-field]]></category>
            <category><![CDATA[forms]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[html]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Tue, 22 May 2018 12:41:08 GMT</pubDate>
            <atom:updated>2018-05-22T12:41:08.571Z</atom:updated>
            <content:encoded><![CDATA[<p>We all know those forms where using the autocompletion ends up in a complete mess. Some fields stay empty, some are filled with incorrect values and others rely on placeholders to tell us what they should be filled with. Is this value correct? Perhaps, but the only way to be sure is to remove the autocompleted value to see the placeholder again. It’s frustrating and it doesn’t have to be like this!</p><h3>Getting the markup right</h3><p>A good form starts with the right markup.</p><h4>1. Turn off autocorrect</h4><p>Turn off autocorrect when you don’t need it: It’s annoying when the system tries to correct something it can’t know. This includes names of persons, streets, companies and cities. Whenever you write an &lt;input&gt; ask yourself: Is the potential value of the input part of a dictionary? When the answer is “No” turn off the autocorrection.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00ee803ae90ee83c3eba90a3a78c1def/href">https://medium.com/media/00ee803ae90ee83c3eba90a3a78c1def/href</a></iframe><h4>2. Turn off autocapitalize</h4><p>Turn off autocapitalize when you don’t need it. This might apply to e-mail fields only, but it’s helpful to avoid that the first character of an email is written capitalized.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/98d9aacbbab8c5705bbae31e042a8e31/href">https://medium.com/media/98d9aacbbab8c5705bbae31e042a8e31/href</a></iframe><h4>3. Use autocomplete</h4><p>The autocomplete attribute lets you control how the browser should populate a given form field. It’s the key for a correctly working autocompletion. Common values for the attribute are name, email, username, new-password and current-password, but the<a href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete-name"> list of values you can use is almost endless</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/838013e0d60c66c2ac28dbcc427e1fa8/href">https://medium.com/media/838013e0d60c66c2ac28dbcc427e1fa8/href</a></iframe><h4>4. Use required</h4><p>The required attribute specifies that an input field has to be filled out before submitting the form. Try to use it instead of a JavaScript validation (when possible). It’s better to let the browser do its job instead of reinventing the wheel with a custom validation. Browsers are doing a lot out of the box: A tooltip appears and the input scrolls into view when a user tries to submit an empty required field.</p><p>It’s also recommended to indicate that a value is required by adding a hint for the user near the input or its label. Yes, <a href="https://baymard.com/blog/required-optional-form-fields">even when all fields are required</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/20e976bd9e251f4d9c5c0cd3a946ec32/href">https://medium.com/media/20e976bd9e251f4d9c5c0cd3a946ec32/href</a></iframe><h4>4. Use type and pattern</h4><p>Touch devices can show a different, optimized keyboard layout for each form field once you told them to do so. For example: They numeric keyboard of the iPhone 6S has <a href="https://baymard.com/blog/mobile-touch-keyboards">a hit-area that is 521% larger</a> than the default touch keyboard. It’s perfect for inputs that accept numeric values only.</p><p>Optimized keyboard layouts can be triggered using the type and pattern attributes. There’s also a new inputmode attribute, <a href="https://caniuse.com/#feat=input-inputmode">but it can’t be used in many browsers, yet.</a></p><ul><li>Use pattern=”[0–9]*” or inputmode=”numeric” to trigger the numeric keyboard</li><li>Use type=&quot;email&quot; to trigger the email keyboard</li><li>Use type=&quot;url&quot; to trigger the URL keyboard</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5e1bc745eb1292dd66d1fdb5dda90f87/href">https://medium.com/media/5e1bc745eb1292dd66d1fdb5dda90f87/href</a></iframe><h4>5. Use labels</h4><p>Designers and developers like to omit the &lt;label&gt; as it makes the form cleaner and the code and styling simpler, but <a href="https://baymard.com/blog/mobile-forms-avoid-inline-labels">it plays an important role</a> for users. A form control that solely relies on a placeholder is unidentifiable once it’s filled. This is especially a problem when the form has been filled using autocompletion: Users can’t tell if an input is filled correctly until they remove the value.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d505ab7f0378017ab9a348c0762c0125/href">https://medium.com/media/d505ab7f0378017ab9a348c0762c0125/href</a></iframe><h4>6. Use placeholders</h4><p>Placeholders are hints for users. They should always show a potential value in the expected format. Placeholders like +49 or https:// are perfect to tell your users that they should start phone numbers with the country calling code and links with a protocol.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/411ff61a17a7d8e1705ea93662df87cd/href">https://medium.com/media/411ff61a17a7d8e1705ea93662df87cd/href</a></iframe><h4>7. Use disabled</h4><p>Use the disabled attribute to deactivate inputs. Not a class. I repeat: Not a class. disabled can be applied to all kind of form controls and tells the browser to keep a user from using an element. Adding an additional class to do the styling is fine, but remember that you can also select the element using input[disabled] in CSS.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1a3b960c16f73857d8a0e38050ad299b/href">https://medium.com/media/1a3b960c16f73857d8a0e38050ad299b/href</a></iframe><h3>Getting the usability right</h3><p>The correct markup already sets the base for a good usability.autocorrect, autocapitalize and autocomplete make it easy to fill the form, using type and pattern ensures that touch devices show an optimized keyboard layout and a placeholder lets the user know what we should insert. But that’s not enough. There’s still a lot you can do wrong when it comes to the styling and overall structure. Here’re three great resources to improve the UX of your forms:</p><h4>Design Better Forms</h4><p>Common mistakes designers make and how to fix them. <a href="https://uxdesign.cc/design-better-forms-96fadca0f49c">More 👉</a></p><h4>UX Movement</h4><p>User experience blog that helps you improve your interface by demonstrating how good and bad design practices affect user behavior. <a href="http://uxmovement.com/category/forms/">More 👉</a></p><h4>Baymard Institute</h4><p>E-commerce UX research — uncovering what designs cause usability issues and how to create “State of the Art” e-commerce experiences. The free articles also contain some great posts related to forms and inputs. <a href="https://baymard.com/blog">More 👉</a></p><h3>Getting the styling right</h3><p>Styling a form is a nightmare. Elements ship with their own styling which variates from system to system and from browser to browser. There’s even a multi-page guide on MDN explaining <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms">“Why is it so hard to style form widgets with CSS?”</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c1-VGXl3HY1a12VR-VxBQg.png" /><figcaption>Better default styles for common input elements with <a href="https://github.com/electerious/formbase">formbase</a></figcaption></figure><p>I’ve spend so much time styling forms that I decided to build a base of default styles for common input elements: <a href="https://github.com/electerious/formbase">formbase</a> eliminates cross browser bugs, inconsistencies across systems and applies a beautiful default styling to several input elements. Zero dependencies, no JavaScript, just CSS.</p><p>An alternative to formbase is <a href="https://boilerform.design/">Boilerform</a>: A little HTML and CSS boilerplate that has been started by an idea from <a href="https://medium.com/u/a789923b5cad">Chris Coyier</a> (<a href="https://css-tricks.com/boilerform/">A Boilerform Idea</a>). It turned into a project that tries to take the pain away from working with forms.</p><h3>Markup examples</h3><p>I would like to end this post with a few examples showing common input fields and their correct attributes. Go back to this section whenever you’re writing a form to ensure that your markup follows the best practices.</p><h4>Name</h4><p>Tip: Always use a single name field instead of <a href="https://baymard.com/blog/mobile-form-usability-single-input-fields">splitting single input entities</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb9ff560d7eca5252ffe7899e50bbfd8/href">https://medium.com/media/eb9ff560d7eca5252ffe7899e50bbfd8/href</a></iframe><h4>Company</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/806b2bfdb46600e52fc85d03d4747e09/href">https://medium.com/media/806b2bfdb46600e52fc85d03d4747e09/href</a></iframe><h4>Postal code</h4><p>Note: Some countries use letters in their postal code<em>. </em>Make sure to remove the pattern when the user should be able to enter a postal code of one of those countries.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b0634350231ecdbd0f5a418a9c8c41d/href">https://medium.com/media/5b0634350231ecdbd0f5a418a9c8c41d/href</a></iframe><h4>City</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/29e0d137f32bd6c1433659d659a9a45a/href">https://medium.com/media/29e0d137f32bd6c1433659d659a9a45a/href</a></iframe><h4>Street</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3023feb963e5520aa961d62ed917afd2/href">https://medium.com/media/3023feb963e5520aa961d62ed917afd2/href</a></iframe><h4>Country</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c7e38f847e725a3c928c2aec5d1c519/href">https://medium.com/media/1c7e38f847e725a3c928c2aec5d1c519/href</a></iframe><h4>Phone</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/92fc617a96bcd32de00cb7e315f61722/href">https://medium.com/media/92fc617a96bcd32de00cb7e315f61722/href</a></iframe><h4>E-Mail</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2f667695eddee5a0d2ea5a55a92499b7/href">https://medium.com/media/2f667695eddee5a0d2ea5a55a92499b7/href</a></iframe><h4>Birthday</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cdfd430267814b73d87cfa1984b4f306/href">https://medium.com/media/cdfd430267814b73d87cfa1984b4f306/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f52b7ee0fd29" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stunning hover effects with CSS variables]]></title>
            <link>https://blog.prototypr.io/stunning-hover-effects-with-css-variables-f855e7b95330?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/f855e7b95330</guid>
            <category><![CDATA[js]]></category>
            <category><![CDATA[animation]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Mon, 19 Feb 2018 13:42:56 GMT</pubDate>
            <atom:updated>2018-08-17T21:53:42.883Z</atom:updated>
            <content:encoded><![CDATA[<p>I recently got inspired by the playful hover animation on the <a href="https://getgrover.com/de-en/products/iphone-x-64gb">Grover website</a>. Moving your mouse over the subscribe-button reveals a colorful gradient that follows your cursor as it moves. The idea is simple, but the result is a button that stands out from the rest and waits to be clicked.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/696/1*5DUxSK_vvV-Igqgb6O_CFw.gif" /></figure><p>How can we achieve a similar effect to make our website stand out, too? Well, it’s not as hard as you might think!</p><h3>Track the position</h3><p>The first thing we need is the position of the mouse.</p><pre>document.querySelector(&#39;.button&#39;).onmousemove = (e) =&gt; {</pre><pre>  const x = e.pageX - e.target.offsetLeft<br>  const y = e.pageY - e.target.offsetTop</pre><pre>  e.target.style.setProperty(&#39;--x&#39;, `${ x }px`)<br>  e.target.style.setProperty(&#39;--y&#39;, `${ y }px`)<br> <br>}</pre><ol><li>Select the element and wait till the user moves his mouse across it</li><li>Calculate the position relative to the element</li><li>Save the coordinates in CSS variables</li></ol><p>Yes, only 9 lines of code to let your CSS know where the user positions his mouse. The amount of effects you can achieve with this information is enormous. But let us finish the CSS first…</p><h3>Animate the gradient</h3><p>We now have the coordinates stored in CSS variables and we can use them everywhere in our CSS.</p><pre>.button {<br>  position: relative;<br>  appearance: none;<br>  background: #f72359;<br>  padding: 1em 2em;<br>  border: none;<br>  color: white;<br>  font-size: 1.2em;<br>  cursor: pointer;<br>  outline: none;<br>  overflow: hidden;<br>  border-radius: 100px;</pre><pre>  span {<br>    position: relative;<br>  }</pre><pre>  &amp;::before {<br>    --size: 0;</pre><pre>    content: &#39;&#39;;<br>    position: absolute;<br>    left: var(--x);<br>    top: var(--y);<br>    width: var(--size);<br>    height: var(--size);<br>    background: radial-gradient(circle closest-side, #4405f7, transparent);<br>    transform: translate(-50%, -50%);<br>    transition: width .2s ease, height .2s ease;<br>  }</pre><pre>  &amp;:hover::before {<br>    --size: 400px;<br>  }<br>}</pre><ol><li>Wrap the text inside a span to avoid that the gradient appears above it</li><li>Start with a width and height of 0px and bring it up to 400px when the user hovers the button. And don’t forget to set a transition to make it appear with a swoosh 💨</li><li>Use the coordinates to follow the mouse</li><li>Apply a radial-gradient to the background and use a closest-side circle. Closest-side fills the whole before without getting beyond it.</li></ol><h3>The result</h3><p>That’s it! Add the missing HTML and enjoy your button:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Felecterious%2Fembed%2Fpreview%2FMQrRxX%3Fheight%3D600%26slug-hash%3DMQrRxX%26default-tabs%3Dcss%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;display_name=CodePen&amp;url=https%3A%2F%2Fcodepen.io%2Felecterious%2Fpen%2FMQrRxX&amp;image=https%3A%2F%2Fassets.codepen.io%2F136245%2Finternal%2Fscreenshots%2Fpens%2FMQrRxX.default.png%3Fformat%3Dauto%26amp%3Bha%3Dfalse%26amp%3Bheight%3D360%26amp%3Bquality%3D75%26amp%3Bv%3D1%26amp%3Bversion%3D1519031077%26amp%3Bwidth%3D640&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/c3769e6eac7475b602678750928ff4a7/href">https://medium.com/media/c3769e6eac7475b602678750928ff4a7/href</a></iframe><h3>Enormous possibilities</h3><p>You can build so many effects just by reacting to the position of the mouse. It’s gorgeous and makes so much fun to play with 👌</p><p>Here’s a similar animation I’ve used on the website of <a href="https://basicscroll.electerious.com/">basicScroll</a>:</p><h3>Tobias Reich on Twitter</h3><p>May the hover be with you https://t.co/2jrmVorLRW</p><p>Or go fancy and build a 3D parallax button:</p><h3>Tobias Reich on Twitter</h3><p>3D parallax button with JS controlled CSS variables @CodePen 🎉 https://t.co/qE0woiNip8 https://t.co/Wyi0xjRzPq</p><p>The possibilities are endless. Let us know what you did with it in the comments below 👇</p><h3>Questions and answers</h3><p><em>Why animating </em><em>width and </em><em>height instead of using </em><em>transform: scale()?</em></p><p>The performance when animating width and height is bad and you should always try to use transform where possible. So why am I not doing it like I should? The problem is that browsers are rendering elements (that are transforming) in an accelerated layer. This layer can cause problems when the button has non-rectangular edges.</p><p><strong>Edit:</strong> There’re ways to use transform, but some browsers don’t like it. Not applying a transition to transform is one potential solution. There’s also a <a href="https://gist.github.com/ayamflow/b602ab436ac9f05660d9c15190f4fd7b">workaround for Safari</a> that might fix those clipping issues.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/701/1*YLEO1IfeE7T8Y5m5-hzHkA.png" /><figcaption>Issue with accelerated layers and border-radius</figcaption></figure><p><em>Why changing </em><em>top and </em><em>left instead of using </em><em>transform: translate()?</em></p><p>See explanation above 👆</p><p><em>Can I follow you on Twitter?</em></p><p><a href="https://twitter.com/electerious">Sure.</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Ff51076%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Ff51076%2F&amp;image=http%3A%2F%2Fapi.screenshotlayer.com%2Fapi%2Fcapture%3Faccess_key%3Dfe59908dad3baab69ffab249a2224b03%26viewport%3D1024x612%26width%3D1000%26url%3Dhttps%253A%252F%252Fupscri.be%252Ff51076%253Fscreenshot&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/b85dfbb5286d8a25cf2e754b9462cf45/href">https://medium.com/media/b85dfbb5286d8a25cf2e754b9462cf45/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f855e7b95330" width="1" height="1" alt=""><hr><p><a href="https://blog.prototypr.io/stunning-hover-effects-with-css-variables-f855e7b95330">Stunning hover effects with CSS variables</a> was originally published in <a href="https://blog.prototypr.io/">Prototypr</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sharing components between front-end and back-end]]></title>
            <link>https://electerious.medium.com/sharing-components-between-front-end-and-back-end-1e9a624bceae?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/1e9a624bceae</guid>
            <category><![CDATA[nunjucks]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[atomic-design]]></category>
            <category><![CDATA[twig]]></category>
            <category><![CDATA[components]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Mon, 11 Dec 2017 13:35:55 GMT</pubDate>
            <atom:updated>2017-12-11T13:35:55.397Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sEfY12RxqjHJI7j7-n06xg.png" /><figcaption>Atomic Design explained by <a href="http://atomicdesign.bradfrost.com/">Brad Frost</a> (© Brad Frost)</figcaption></figure><p>As a front-end developer there is nothing more annoying than losing the control of your HTML after your code has been implemented in the back-end. This typically happens when the HTML isn’t shared between front-end and back-end. But it‘s not the fault of a back-end developer. It‘s the fault of the front-end which failed to provide a good integration into the targeted CMS. Our mission at <a href="https://www.comwrap.com/">comwrap</a> was to solve this problem.</p><h3>The problem</h3><p>Our existing workflow followed a pattern that allowed us to develop the front-end without caring too much about its later use. HTML, CSS and JS wasn’t tied to a specify CMS. Want to use a different templating engine? No problem, as long as the output (HTML) is the same as before.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_4HPEqHVvboZyinHYguFLQ.png" /><figcaption>Static UI page for the <a href="https://www.comwrap.com/">comwrap website</a></figcaption></figure><p>The issue with this workflow was that both projects were disconnected. Changing HTML always required to update the implementation in the back-end, too. And that gets out of control as soon as you have to touch more than one line of HTML. You need to communicate every adjustment you’ve made and you need to check if everything has been changed accordingly. And no matter how good you are, spotting a different tag, class or attribute inside the reimplementation is almost impossible. All those little deficiencies quickly sum up to issues that are hard to debug. “It works fine in the front-end” or “I can’t reproduce it” are the resulting answers after a bug has been reported.</p><blockquote>“It works fine in the front-end” — Every Front-End developer, always</blockquote><h3>The challenge</h3><p>Each team had different preferences and we were looking for a solution that works great for both. In the front-end we preferred to stay with our existing front-end build process that is powered by <a href="https://rosid.electerious.com/">Rosid</a>. The back-end on the other hand already worked with a component system called <a href="https://fractal.build/">Fractal</a> and expected a similar interface and integration. Indeed, Fractal already had what we were looking for. It’s a UI that helps you to build and document components. We tried hard to integrate the system into our build-process, but we had to accept that Rosid and Fractal aren’t playing well together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qJv0eInIsf37PK7BND6ZIw.png" /><figcaption>UI of Fractal</figcaption></figure><h3>The concept of components</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*taiBGV_MrG4zsCcSbvrN_A.png" /><figcaption>Atomic Design by <a href="http://bradfrost.com/">Brad Frost</a></figcaption></figure><p>Fractal showed us what a solution could look like. It forces the developer of the front-end to write small, reusable components. The back-end then uses the same components and renders them with real data, instead of the dummy data used in the front-end. The components can later be assembled in a variety of ways to build anything from larger components right up to whole pages. This concept isn’t tied to Fractal or a UI in general, but the interface helps you assemble, preview and document those components in a visual way. <a href="http://bradfrost.com/">Brad Frost</a> calls this “atomic design”. I highly recommend <a href="http://atomicdesign.bradfrost.com/">the book</a> he wrote to learn more about robust design systems.</p><h3>The solution</h3><p>Our research and the concept of Fractal showed us that we were actually looking for two things:</p><ol><li><strong>Components</strong>: A way to share the same HTML between front-end and back-end. This requires a templating engine that works on both sides.</li><li><strong>UI</strong>: A way to visualize components. Great for the whole team as it makes communication easier when you can show what you are talking about.</li></ol><p>We decided to use <a href="https://twig.symfony.com/">Twig</a> as our templating engine as most developers were already familiar with it.</p><p>Finding a UI was way harder than finding a templating engine. In the end we made the step and developed our own system. After two projects we can say with certainty that this was the right move.</p><h3>Malvid</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_NdryRqYddUmLrTINUNwHQ.png" /><figcaption>The UI of Malvid</figcaption></figure><p>Let me introduce you to <a href="https://github.com/comwrap/Malvid">Malvid</a>, our own UI solution. A Node.js module powered by modern technologies, focused on components and rendered blazingly fast with React. We took everything that made Fractal great for us and tried to do it even better. A static site compiler that generates a web-app from a given folder structure of components.</p><p>Malvid shows all relevant information at a glance: Your components on the left and a preview, the template, data and notes of the selected component on the right.</p><h3>Conclusion</h3><p>Changing a workflow isn’t something that happens over night. It requires a lot of input from your teams, research and brainstorming. But don’t lose yourself in details! You will never know if it works before trying it and you can’t solve everything at once. Your new workflow might crack existing problems, but it also introduces new ones.</p><p>Sharing components between front-end and back-end was the right move for us. No matter if <a href="https://fractal.build/">Fractal</a>, <a href="http://patternlab.io/">Pattern Lab</a> or <a href="https://github.com/comwrap/Malvid">Malvid</a>—try to find a way that works for your company. The switch might be worth it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1e9a624bceae" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a static site with Rosid]]></title>
            <link>https://electerious.medium.com/building-a-static-site-with-rosid-99f51a8154bb?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/99f51a8154bb</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[static-site-generator]]></category>
            <category><![CDATA[sass]]></category>
            <category><![CDATA[static-site]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Wed, 03 May 2017 16:12:20 GMT</pubDate>
            <atom:updated>2017-05-03T16:12:20.364Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://rosid.electerious.com/">Rosid</a> is a just-in-time server and static site generator written in Node.js. It’s inspired by <a href="https://www.google.de/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0ahUKEwiy45GMuMzTAhWGBBoKHV2IDTsQFggnMAA&amp;url=http%3A%2F%2Fharpjs.com%2F&amp;usg=AFQjCNH4mAy9u6xOcqG7vNrjd_oN1Ixs5w&amp;sig2=hoL1svPydW1O5f-IktqS0g">Harp.js</a>, but solves two of it’s biggest problems:</p><ol><li>Hard-coded pre-processing</li><li>Missing live-reloading</li></ol><p>Rosid can be integrated into your project in two ways: Using the CLI <em>or</em> using the API of Rosid. This guide covers the first way and shows you how create and serve a simple project.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0Ll5tQ0YfW5dzClmrq5w6w.png" /><figcaption>Rosid runs in your Terminal and transforms your code on-the-fly.</figcaption></figure><h3>1. Install Rosid</h3><p>First, install or update to the newest version of <a href="https://nodejs.org/">Node.js</a>. Rosid is written in Node.js, but you only need to know the basics of Node.js and JavaScript to use Rosid. Once it has finished installing, create a new folder, open it in the terminal and run the following npm commands. If you wonder what npm is: It’s a package manager that ships with Node.js. You should already have it installed now 🤘</p><pre># Create a package.json file<br>npm init --yes</pre><pre># Install Rosid and save it as a dependency in the newly created package.json<br>npm install rosid --save</pre><h3>2. Setup your project</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9QnFovhiOScghg_UiERQnw.png" /><figcaption>A very simple project setup with Rosid.</figcaption></figure><p>Rosid is now installed in your project, but needs a few files to do anything useful. Create a new folder called src and add a index.html and main.scss to it. Fill the HTML file with …</p><pre>&lt;!doctype html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>	&lt;head&gt;</pre><pre>		&lt;meta charset=&quot;utf-8&quot;&gt;<br>		&lt;title&gt;Rosid&lt;/title&gt;</pre><pre>		&lt;link rel=&quot;stylesheet&quot; href=&quot;main.css&quot;&gt;</pre><pre>	&lt;/head&gt;<br>	&lt;body&gt;</pre><pre>		&lt;h1&gt;Hello Rosid!&lt;/h1&gt;</pre><pre>	&lt;/body&gt;<br>&lt;/html&gt;</pre><p>… and your SCSS file with …</p><pre>$background: #55c185;<br>$color: #fff;</pre><pre>body {<br>	background: $background;<br>}</pre><pre>h1 {<br>	color: $color;<br>}</pre><h3>3. Install a handler</h3><p>Rosid is now installed and two files have been added to your project in a folder called src. The HTML needs no processing. It works out of the box and Rosid will send it straight to the browser. The SASS file on the other side needs to be transformed to CSS, because browser don&#39;t know anything about SASS.</p><p>Let’s use npm again to install an existing handler that handles the transformation of SASS files.</p><pre># Install the SASS handler<br>npm install rosid-handler-sass --save</pre><h3>4. Create a configuration</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YSJf_MugM3j5RCxT47piig.png" /><figcaption>Everything Rosid needs to work.</figcaption></figure><p>The handler is now installed, but Rosid has no clue how to use it. It’s up to you to tell Rosid about your newbie. You do so by creating a rosidfile.json in the root of the project. It should contain anything Rosid needs to know.</p><pre>[<br>	{<br>		&quot;name&quot;: &quot;SASS&quot;,<br>		&quot;path&quot;: &quot;*.{css,scss,sass}&quot;,<br>		&quot;handler&quot;: &quot;rosid-handler-sass&quot;,<br>		&quot;opts&quot;: {<br>			&quot;in&quot;: &quot;.scss&quot;<br>		}<br>	}<br>]</pre><ul><li>name is just a help for you. Rosid logs the activity of the handler with the name you&#39;ve chosen.</li><li>path uses the same patterns the shell uses. It matches all files with a css, scss or sass extension. Your main.scssis a match and Rosid will transform it with the handler specified in the handler property.</li><li>opts are options. They&#39;re different form handler to handler. rosid-handler-sass loads .sass files by default. The in option changes this behaviour to .scss as this is the extension of your file.</li></ul><h3>5. Start Rosid</h3><p>It’s time to fire up Rosid. Rosid has been installed into the node_modules directory and you can run the Rosid CLI it contains.</p><pre># Start Rosid<br>./node_modules/.bin/rosid serve src/</pre><p>Rosid starts and opens your default browser. You should see “Hello Rosid!” in it with a white font on a green background.</p><h3>6. Compile your project</h3><p>You don’t need to use the server of Rosid. Export static files using your existing transform-functions and host your site anywhere!</p><pre># Compile your project<br>./node_modules/.bin/rosid compile src/ dist/</pre><h3>What’s next</h3><p>This was just a taste of what <a href="https://rosid.electerious.com/">Rosid</a> can do for you. Try the official <a href="https://github.com/electerious/Skeleton">Skeleton</a> project for more practical examples. Skeleton is a HTML5 Boilerplate built upon Rosid. JS (with Babel, UglifyJS), SASS (with cssnano, Autoprefixer) and EJS can be used right out of the box.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=99f51a8154bb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to write tests for file-based Node.js modules]]></title>
            <link>https://electerious.medium.com/how-to-write-tests-for-file-based-node-js-modules-6e73eb070ed9?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/6e73eb070ed9</guid>
            <category><![CDATA[chai]]></category>
            <category><![CDATA[mocha]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[unit-testing]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Thu, 30 Mar 2017 10:11:24 GMT</pubDate>
            <atom:updated>2017-03-30T10:11:24.460Z</atom:updated>
            <content:encoded><![CDATA[<p>Writing tests for modules that require a predefined file-structure isn’t fun. Each test needs it’s own combination of files and folders. Setting up those structures takes time and makes your tests complicated.</p><p>I had the same problem with my modules: The quality of the tests suffered, because it was annoying to write them. This really shouldn’t be the case. I’ve looked at solutions and started to use <a href="https://www.npmjs.com/package/temp">temp</a>. You might know it if you have ever written tests for file-based modules. temp generates a unique path under the system temporary directory and supports automatic removal 🎉</p><p>I liked this solution, but I realized that it’s only half of what I needed. Generated files had to be filled manually and creating complex structures required multiple API calls. Why does it have to be so complicated? Why not using an object to describe a whole structure at once?</p><h3>The solution</h3><p><a href="https://github.com/electerious/fsify">fsify</a> is my attempt to make file-based testing easy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QxbtIyQrWS0c09EOD8XOmg.png" /><figcaption>Testing with different structures</figcaption></figure><ul><li>Files and folders can be persistent or temporary</li><li>Nested structures can be described in an array of objects</li><li>Files can be filled with content</li><li>Files and directories can have custom or random names</li><li>It works with the output of the Linux and Unix <a href="https://www.npmjs.com/package/tree-cli">tree</a> command</li></ul><h3>Creating a structure</h3><pre>.<br>├── dirname<br>│   └── filename<br>└── filename</pre><p>The given tree can be created with fsify in a few lines of code.</p><pre>const fsify = require(&#39;fsify&#39;)()</pre><pre>const structure = [<br>    {<br>        type: fsify.DIRECTORY,<br>        name: &#39;dirname&#39;,<br>        contents: [<br>            {<br>                type: fsify.FILE,<br>                name: &#39;filename&#39;,<br>                contents: &#39;data&#39;<br>            }<br>        ]<br>    },<br>    {<br>        type: fsify.FILE,<br>        name: &#39;filename&#39;,<br>        contents: &#39;data&#39;<br>    }<br>]</pre><pre>fsify(structure)<br>    .then((structure) =&gt; console.log(structure))<br>    .catch((err) =&gt; console.error(err))</pre><ol><li>Create a new instance of fsify</li><li>Describe the structure in an array of objects</li><li>Run fsify with the defined structure</li></ol><h3>Writing a test</h3><p>Let’s use <a href="https://mochajs.org/">Mocha</a>, <a href="http://chaijs.com/">Chai</a> and <a href="https://github.com/electerious/fsify">fsify</a> together. The imaginary module we want test requires a HTML file and a JSON file with the name of the HTML file + “.data.json”.</p><pre>.<br>├── &lt;filename&gt;.html<br>└── &lt;filename&gt;.data.json</pre><p>Both files need to be filled with content appropriate to their file type. The main function of the module gets called with the path to the HTML. It should return the original markup filled with data.</p><pre>const os     = require(&#39;os&#39;)<br>const assert = require(&#39;chai&#39;).assert<br>const index  = require(&#39;./../src/index&#39;)</pre><pre>const fsify = require(&#39;fsify&#39;)({<br>    cwd        : os.tmpdir(),<br>    persistent : false,<br>    force      : true<br>})</pre><pre>describe(&#39;index()&#39;, function() {<br>    <br>    it(&#39;should load HTML and fill it with data from associated data file&#39;, function() {<br>    <br>        const data = {<br>            key: &#39;value&#39;<br>        }<br>        <br>        const structure = [<br>            {<br>                type: fsify.FILE,<br>                name: &#39;index.html&#39;,<br>                contents: &#39;&lt;p&gt;{{ key }}&lt;/p&gt;&#39;<br>            },<br>            {<br>                type: fsify.FILE,<br>                name: &#39;index.data.json&#39;,<br>                contents: JSON.stringify(data)<br>            }<br>        ]<br>        <br>        return fsify(structure).then((structure) =&gt; {<br>            <br>            return index(structure[0].name)<br>            <br>        }).then((output) =&gt; {<br>            <br>            assert.strictEqual(output, `&lt;p&gt;${ data.key }&lt;/p&gt;`)<br>            <br>        })<br>        <br>    })<br>    <br>})</pre><p>At first we create an instance of fsify with several options.</p><ul><li>cwd: os.tmpdir() All files should be created in the operating system’s default directory for temporary files</li><li>persistent: false Files shouldn’t be persistent. They will be deleted when the process exits.</li><li>force: true Force the deletion of files outside the current working directory</li></ul><p>Setup done<strong> </strong>✅</p><p>Our test starts with data and structure. This part isn’t much different to the first example and should explain itself.</p><p>Structure defined ✅</p><p>In the last part of the test we call fsify with the structure. The function resolves an array of objects equal to the input, but with an absolute path as the name.</p><p>Structure created ✅</p><p>We use the absolute path (structure[0].name) and call our imaginary module with it. It resolves the HTML filled with data.</p><p>Module tested ✅</p><h3>Going further</h3><p>fsify is not only for tests. It can actually create any structure you need and also works perfect in production 🤘</p><h4>What about random filenames?</h4><p>The <a href="https://www.npmjs.com/package/uuid">uuid module</a> can be used to create random filenames.</p><h4>Can I use the output of tree?</h4><p><a href="https://github.com/electerious/fsify#structure-from-tree--j">Yes</a>. tree has -J flag which prints out an JSON representation of the tree.</p><h4>Can I set a custom encoding, mode or flag?</h4><p>encoding, mode and flag are supported. You can specify those options for <a href="https://github.com/electerious/fsify#directory">directories</a> and <a href="https://github.com/electerious/fsify#file">files</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6e73eb070ed9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The power of CSS variables]]></title>
            <link>https://electerious.medium.com/the-power-of-css-variables-6c4e4ebaf279?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/6c4e4ebaf279</guid>
            <category><![CDATA[css]]></category>
            <category><![CDATA[sass]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[variables]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Thu, 16 Mar 2017 08:44:50 GMT</pubDate>
            <atom:updated>2017-03-16T08:44:50.275Z</atom:updated>
            <content:encoded><![CDATA[<p>CSS variables are the next big thing and their power is often underestimated. People call them “CSS variables”, which doesn’t describe their actual behavior properly. CSS Custom Properties — as <a href="https://www.w3.org/TR/css-variables/">the specification</a> names them — can do much more for you than SASS variables. They’re properties and they cascade like normal properties.</p><p>I’ve made <a href="https://coffee.electerious.com/">a test project</a> to learn more about them and tried not to use any SASS variables at all. Here’re some of the benefits I discovered:</p><h3>Eliminate redundant styling</h3><p>The principle you know from functions in programming languages applies to CSS Custom Properties: Define once, reuse often. No need to write the same code over and over again 😌</p><h4>Before</h4><pre>.button {<br>    display: inline-block;<br>    padding: .5em 1em;<br>    color: white;<br>}</pre><pre>.button--red {<br>    background: red;<br>    box-shadow: inset 0 0 2px red;<br>}</pre><pre>.button--blue {<br>    background: blue;<br>    box-shadow: inset 0 0 2px blue;<br>}</pre><h4>After</h4><pre>.button {<br>    display: inline-block;<br>    padding: .5em 1em;<br>    color: white;<br>    background: var(--color);<br>    box-shadow: 0 0 2px var(--color);<br>}</pre><pre>.color-red { --color: red; }<br>.color-blue { --color: blue; }</pre><p>The new approach brings several advantages:</p><ul><li>All button styles are now in one place</li><li>Redundant styling has been removed</li><li>Color classes can be used for all elements with dynamic colors</li></ul><p>You can even define a fallback value for all your buttons 🤘</p><pre>background: var(--color, black);<br>box-shadow: 0 0 2px var(--color, black);</pre><h3>Conditional values</h3><p>Custom properties can be made conditional with @media and @supports. Changing a variable in a conditional rule affects the properties in which you’ve used the variable. It’s the same behavior as in the previous example. Just with conditional rules.</p><pre>.warning {<br>    display: var(--display, none);<br>    background: red;<br>}</pre><pre>.warning::before {<br>    content: &#39;Your browser does not support &#39; var(--feature) &#39;.&#39;;<br>}</pre><pre><a href="http://twitter.com/supports">@supports</a> not (display: flex) {<br>    .warning {<br>        --display: block;<br>        --feature: &#39;CSS Flexbox&#39;;<br>    }<br>}</pre><pre><a href="http://twitter.com/supports">@supports</a> not (display: grid) {<br>    .warning {<br>        --display: block;<br>        --feature: &#39;CSS Grid Layout&#39;;<br>    }<br>}</pre><h3>A bridge between HTML and CSS</h3><p>It’s possible to define CSS Custom Properties in the HTML style attribute to use them in your CSS. Think about an element with a gradient, where the first color is always different. You could apply a gradient using JS or inline styles, but this would either cause a flash of unstyled content or HTML that contains styling.</p><h4>Before</h4><pre>&lt;!-- HTML --&gt;<br>&lt;div class=&quot;gradient&quot; style=&quot;background: linear-gradient(to bottom, red, blue)&quot;&gt;&lt;/div&gt;<br>&lt;div class=&quot;gradient&quot; style=&quot;background: linear-gradient(to bottom, yellow, blue)&quot;&gt;&lt;/div&gt;</pre><pre>/* CSS */<br>.gradient {<br>    width: 100%;<br>    height: 100px;<br>}</pre><h4>After</h4><pre>&lt;!-- HTML --&gt;<br>&lt;div class=&quot;gradient&quot; style=&quot;--color: red&quot;&gt;&lt;/div&gt;<br>&lt;div class=&quot;gradient&quot; style=&quot;--color: yellow&quot;&gt;&lt;/div&gt;</pre><pre>/* CSS */<br>.gradient {<br>    width: 100%;<br>    height: 100px;<br>    background: linear-gradient(to bottom, var(--color), blue);<br>}</pre><p>It’s not only easier to read, it also improves the code quality and clarity:</p><ul><li>The gradient definition is back in the CSS file where it belongs to</li><li>Redundant styling has been removed from the HTML</li></ul><h3>JS controlled variables</h3><p>CSS Custom Properties can be used in calc() functions to perform a calculation with them. That’s cool, but what if you want more power? JavaScript to the rescue! 💪</p><p>JS allows to read and write CSS variables. This gives you all the capabilities of a programming language to generate the content of your variables. It’s so powerful, you can even build a <a href="https://medium.com/@electerious/parallax-scrolling-with-js-controlled-css-variables-63cfe96820c7">parallax scrolling library</a> with it.</p><p>Here’s a demo combing CSS Custom Properties with JavaScript to generate a random gradient on the client-side:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2Felecterious%2Fembed%2Fpreview%2FyMbQvY%3Fheight%3D600%26amp%3Bslug-hash%3DyMbQvY%26amp%3Bdefault-tabs%3Djs%2Cresult%26amp%3Bhost%3Dhttp%253A%252F%252Fcodepen.io%26amp%3Bembed-version%3D2&amp;url=https%3A%2F%2Fcodepen.io%2Felecterious%2Fdetails%2FyMbQvY%2F&amp;image=https%3A%2F%2Fgravatar.com%2Favatar%2F7ff9e93ff25e002bc49f4d69c0c3eac7%3Fs%3D80%26d%3Dhttps%3A%2F%2Fcodepen.io%2Fassets%2Favatars%2Fuser-avatar-80x80-bdcd44a3bfb9a5fd01eb8b86f9e033fa1a9897c3a15b33adfc2649a002dab1b6.png&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/31c9daef8991b86893095f71cf167c90/href">https://medium.com/media/31c9daef8991b86893095f71cf167c90/href</a></iframe><h3>Conclusion</h3><p>Custom properties are way more than SASS variables. I highly recommend to play around with them in a project. Developing a complete page with them gives you a much better feeling than a simple CodePen experiment. Try to avoid SASS variables to see what you can and can’t do with CSS variables.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6c4e4ebaf279" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Behind the Scenes: Rebuilding LaudableApps]]></title>
            <link>https://electerious.medium.com/behind-the-scenes-rebuilding-laudableapps-88248166562a?source=rss-5f0b44d665e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/88248166562a</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[static-site-generator]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[server-side-rendering]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Tobias Reich]]></dc:creator>
            <pubDate>Mon, 30 Jan 2017 09:11:41 GMT</pubDate>
            <atom:updated>2017-01-30T09:11:41.551Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://laudableapps.com/">LaudableApps</a> is a site originally started by <a href="https://dribbble.com/benedikt">Benedikt</a> as a Tumblr blog. I took over the project in 2012 and started to maintain it as a free time project. My goal was to build an independent showcase for beautiful iOS apps without distraction. No ratings, no reviews, no comments. Just apps, screenshots and App Store links.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/908/1*eMcKzj5-JjznFJhnn5seqA.png" /><figcaption>The new look of LaudableApps</figcaption></figure><h3>A new design</h3><p>The first big redesign was back in 2012. Another refresh happened late 2013. Now, 4 years later, it was time to move away from the initial branding. It has done its job, but started to look outdated.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/908/1*TbGytk5cYLioaKg9MK9DkQ.png" /><figcaption>The original design from 2014</figcaption></figure><p>I tried to redesign the site several times, but was never satisfied with the result. You sometimes need to put a project aside to collect new inspiration and fresh ideas. It thankfully worked out: The main part of the final design happened in only few hours. I was super happy with it and took it directly into development 🦊 Bright and light colors, whitespace and abstract forms dominate the new design. Concept and layout stayed.</p><h3>No CMS</h3><p><a href="https://getkirby.com/">Kirby</a> was my CMS of choice for a long time. It still is, but as a developer I’m able to maintain code without any UI or level of abstraction. Especially as I’m the only one working on LaudableApps. There was no reason for me to use a CMS, again.</p><p>Static website generators are a big thing and they make hosting simple. You can upload your sites anywhere and don’t need to worry much about security and performance.</p><p><a href="https://harpjs.com/">Harp.js</a> is a fantastic solution, but limited to its build-in preprocessors. I’ve developed a similar generator called <a href="https://rosid.electerious.com/">Rosid</a> to solve the issues I had with it. Rosid invokes functions before serving files to the browser. This allows you to transform anything, without saving. And the best: You decide what the function does.</p><h3>React and SSR</h3><p>React is my framework of choice when it comes to user interfaces on the web. There’s not much interactivity on LaudableApps. Using a JS library to render HTML for it is unnecessary… but fun 😎</p><p>I’ve ensured that all the code I’ve written was isomorphic. This makes it possible to run the JavaScript on both server-side and client-side. Or with other words: The back-end and front-end share the same code. Why? Because I don’t want to send an empty site to the user that then gets filled with HTML when the JS has loaded. When both sides already share the same code, why not pre-executing it on the server? The magic keyword is SSR 💫 Server-side rendering means that we send a filled site to the user that then gets re-rendered when the client JS kicks in. When the used library is smart enough (and React is), it only re-renders what’s necessary.</p><p>I previously mentioned that I’m using a static website generator, which means that there’s no server-side. I instead execute the server-side once and <a href="https://github.com/electerious/rosid-handler-node">save the output</a> to static HTML files. Lets call it pre-executed SSR and pretend it’s a thing…</p><h3>CSS in JS</h3><p>It’s crazy. Now that everyone has started to write HTML in JS, people got over-motivated and try to squeeze as much as possible into one language. To be honest: I was skeptical about this, but I thought I should give it a try.</p><p><a href="https://github.com/threepointone/glamor">Glamor</a> looked like a good library to get started with. I can’t tell if it’s the best in its class, but it worked fine and I got no trouble with it. And yes, writing CSS in JS has its advantages:</p><ul><li>JS is all you need. You can throw away your SASS workflow.</li><li>Generating CSS based on props you pass to components is delightful.</li><li>All the power of JavaScript is usable, including everything from npm. <a href="https://github.com/adriantoine/kewler">kowler</a> is one great example of modules you can use. The possibilities are endless.</li></ul><p>But it’s not all fun and games 😒</p><p>There’re <a href="https://github.com/MicheleBertoli/css-in-js">many libraries</a>. Finding the right one takes a while. Some of them don’t even support pseudo classes and media queries. Others don’t allow to extract CSS files. You will run into problems which haven’t existed before. I claim that you never thought: “How can I save the damn CSS into a file?”. Now you will.</p><p>Another disadvantage was that glamor uses objects to define styles. Objects are powerful in JS, but it can get pretty ugly when you start to use :hover or @media in them.</p><pre>css({<br>  display: &#39;flex&#39;,<br>  justifyContent: &#39;space-between&#39;,<br>  alignItems: &#39;center&#39;,<br>  background: &#39;rgba(0, 0, 0, .04)&#39;,<br>  &#39;:hover&#39;: {<br>    background: &#39;rgba(0, 0, 0, .08)&#39;,<br>  },<br>  [`<a href="http://twitter.com/media">@media</a> (max-width: 800px)`]: {<br>    flexDirection: &#39;column&#39;,<br>    textAlign: &#39;center&#39;<br>  }<br>})</pre><p>Template strings are an alternative. They are easier to read and some libraries support them, too. It depends on the library and you should take this into mind when choosing one. There’s also a way to use them in glamor, but it’s <a href="https://github.com/threepointone/glamor/blob/master/docs/css.md">considered as buggy</a>.</p><pre>css`<br>  display: flex;<br>  justify-content: space-between;<br>  align-items: center;<br>  background: rgba(0, 0, 0, .04);<br>  :hover {<br>    background: rgba(0, 0, 0, .08);<br>  }<br>  <a href="http://twitter.com/media">@media</a> (max-width: 800px) {<br>    flex-direction: column;<br>    text-align: center;<br>  }<br>`</pre><h3>Conclusion</h3><p>I’m happy that I finished the project without getting lost in new libraries. I tried a bunch of new stuff and had some trouble getting SSR and CSS in JS right. The hardest part was the rethinking. How to write JS that works on server and client? How to style elements without a real CSS file?</p><p>Let me know what you think and feel free to ask me further questions <a href="https://twitter.com/electerious">on Twitter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=88248166562a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>