Aspect Ratio Media Elements and intrinsicsize

If you need an aspect-ratio sized <div> (or any element that can have children), you can do it. Perhaps the cleanest way is a custom-property-sized pseudo-element that pushes the correct minimum height through padding-based-on-width.

But media elements like <img> don’t have children. The <video> tag isn’t self-closing, but when it is supported (almost always), the content of it is replaced with a shadow DOM you don’t control. Besides, these are the only two elements that “size to an external resource.” So, how do you enforce aspect ratio on them when using a variable width like 100% or 75vw? Well, once they load, they will have their natural aspect ratio, so that’s nice. But it also means they don’t know the height while they are loading and it may cause performance jank-ening reflow.

One solution is to put them into a container with an aspect ratio, forcing them to the corners with absolute positioning. But, all by themselves, they are incapable of sizing to the aspect ratio correctly until they load.

Hence, the intrinsicsize attribute for “all image element types (including SVG images) and videos” that is now under development.

<img intrinsicsize="400x300" style="width: 100%">

The explainer document is helpful. The reason it is intrinsicsize and not aspectratio is because an aspect ratio doesn’t provide as much useful or usable information. I’d love to see it work on any element and be brought to CSS as well.

The post Aspect Ratio Media Elements and intrinsicsize appeared first on CSS-Tricks.

HTML elements, unite! The Voltron-like powers of combining elements.

Guides, resources and discussions about Semantic HTML are often focused around specific elements, like a heading, or a sectioning element, or a list. It’s not often that we talk specifically about how we can combine HTML elements to increase their effectiveness.

Normally, when we introduce HTML, we talk about how it is used to apply meaning to content in a document, and we do this by using examples like:

  • “Is it a paragraph?”
  • “Is it a heading?”
  • “Is it a numbered list”
  • “Is it a button”

We use these examples because they are easy to understand — it’s a single piece or chunk of the same content that needs to be represented in a particular way. This is useful, but it only scratches the surface of how we can use and combine elements to provide more context and meaning.

You remember Voltron, right? Each member of the Voltron force was powerful in their own right, but it was when they combined together to form a towering figure that their mighty powers became unstoppable.

The same is true of HTML elements. I have a few favorite combinations that I’ll take you through. They may seem obscure, but you’d be surprised at how often they come up when you take the time to think outside of divs and spans.

Abbreviations and Definitions

<abbr> and <dfn> are two of my favorite HTML elements. I particularly like them because they work really well together.

You can combine the abbreviation and definition elements to allow browsers, search bots, and other technologies to recognize that something is being defined and that the acronym is associated to that phrase.

<p> The <dfn><abbr title="International Good Dog Association">IGDA</abbr></dfn> is an international, not-for-profit organization responsible for determining that all dogs are good.
</p>

In the above example, I’m defining that the acronym “IGDA” as “International Good Dogs Association.” I do this by wrapping the acronym in an <abbr> element with a title attribute defining the full name. By adding the <dfn> element around the abbreviation, it indicates that the surrounding paragraph defines the term “International Good Dogs Association.”

The <abbr> element is useful because it can tell screen readers what they should read, while also providing a useful visual representation in the form of a tooltip explaining what the abbreviation is.

Visual representation of <abbr> and <dfn>.

Keyboard, Sample and Variable

If you haven’t heard of these elements, then get ready to have your socks blown off, because they are awesome.

First up, the <kbd> element is used to represent text for a textual user input (e.g. from a keyboard). You can also nest multiple <kbd> elements to represent multiple keystrokes. I love this because, as developers, we find ourselves (hopefully) writing documentation, blog posts, and guides on a regular basis and HTML provides us with native ways to represent this content straight out of the box!

If I wanted to tell someone how you copy and paste with the keyboard, I could mark it up like the code below.

<p>I like to <kbd><kbd>Ctrl</kbd>+<kbd>C</kbd></kbd> and <kbd><kbd>Ctrl</kbd>+<kbd>V</kbd></kbd> a lot.</p>

It looks a bit nuts but the above code, when rendered, looks like the following without any styling applied to it. If you are wondering why kbd is nested inside another kbd element, what this does is specify that the key or input is part of a larger input. Even more combined superpowers!

See the Pen rZpNPy by CSS-Tricks (@css-tricks) on CodePen.

You can further target the <kbd> elements with CSS to make it look more like little keyboard controls. (Note: Browsers tend to render this by default with a monospace font.)

See the Pen gdoOqE by CSS-Tricks (@css-tricks) on CodePen.

If you’re wondering what the difference is between using <kbd> versus a span, I believe it comes down to information. I will repeat this sentiment a lot: we do not know how someone is going to consume our HTML, so give your content it’s best chance by representing it in the most meaningful and contextual way possible. If you are still not on board, then please go read my post about HTML as told by TypeScript.

The <samp> element is really cool because you can nest it inside the <kbd> element and vice versa. WHAT? I know, so versatile! Let’s have a look at some examples from MDN.

The following code is an example of nesting a <samp> element inside a <kbd> element. This is used to mark up content that represents input based on the text displayed by the system (e.g. button names).

<p>To save the image file, select <kbd><kbd><samp>File</samp></kbd> - <kbd><samp>Save as...</samp></kbd></kbd>.
</p>

See the Pen YOYzbJ by CSS-Tricks (@css-tricks) on CodePen.

In the above code, we define our keyboard shortcuts the same as our previous example, but we also determine that the menu and menu item names (contained within both <kbd> and <samp>) are an input selected from something displayed by the system, e.g. a dialog or widget.

In other words, this piece of text is a message from the system which has some user inputs that you need to follow (like File and Save as…).

Whereas, when we nest <kbd> inside <samp>, we determine that the input has been echoed back to the user by the system.

<p><samp>yarn start:theproject does not exist, did you mean:</p>
<blockquote><samp><kbd>yarn start:the-project</kbd></samp></blockquote>

Finally, the <var> element! This is used to mark up the name of a variable in math or programming, for example:

<var>E</var> = <var>m</var><var>c</var><sup>2</sup>.
<samp>Error: <var>console<var> is undefined.</samp>

Here you can start to see how combining <var> with other elements like <pre>, <code>, <kbd> or <samp> starts to make your content’s markup more explicit by adding more context. Anything that interprets your HTML markup can start to derive more meaning from the elements you are using rather than just assuming that it’s all standard text.

If you put this content in a paragraph with some spans, there is no way for technology to distinguish this from any other old text on your page. You don’t have to resort to <span> or a <div> to represent this content because HTML already provides us with more semantically accurate elements we can use. HTML is not just about presentation; it’s about meaning. Various technologies outside of visual rendering engines rely on this meaning to make decisions about how to communicate our content in the most meaningful way (e.g. screen readers, text to voice, reading apps, bots, or the next big thing in the future).

Figures

Figures (<figure>) are a great example of a power combination element. Unfortunately, I think it is widely misused and under appreciated (much like <aside>, which I could talk about for hours). The obvious combination you are probably familiar with is using <figure> and <figcaption> together. We often use this duo to represent graphical content like images, illustrations and diagrams — but it can also be used for things like code, poems and quotes!

Because a figure is so flexible in what kind of content it represents, there are a bunch of different HTML elements you can use within a figure to provide more context around the type of content you are putting in your page.

Figcaption

The <figure> element is often seen with an optional <figcaption> which represents a caption or legend for a figure. It should be the first child or last child of the <figure> element. You can also use any flow content (e.g. paragraphs, headings, etc.) in the <figcaption> to provide more context and you can have multiple images inside a <figure> represented by a single <figcaption>.

<figure> <img src="jello.jpg" alt="Golden Retriever Puppy" /> <figcaption>Jello the Golden Retriever enjoying being carried home.</figcaption>
</figure>

Preformatted Text

The <pre> element is used to display preformatted text or code and is usually rendered using a monospace font. While <pre> can be used on its own, it can also be combined with <figure> and <figcaption>. By doing this, the content inside the <pre> element becomes more accessible to assistive technologies, like screen readers, since it allows us to use <figcaption> as a label for the text or code.

We can go even further by combining the <pre> and <code> elements to identify the pre- formatted content as code.

See the Pen QVaWVW by CSS-Tricks (@css-tricks) on CodePen.

Because <code> is considered flow content, it can also be used inside a <figcaption> to mark up inline references to code (i.e. a single phrase or line).

Cite and Blockquote

Quotations are something I use a lot and it honestly didn’t occur to me it could be used as part of a figure. But it still makes sense to use cite or quotation if the content they contain is relevant to the overall content, even if it is not part of the main document flow.

I like the example of using a figure for poems, mainly so I could share the amazing poem I wrote about my dog. Here I use the <cite> element inside the <figcaption>:

<figure> <p> Jello - A little fluffy dog. Hello! Squishy Jello - you little fluffy fellow. BOUNCY yellow Jello. A very mellow fellow. EATING MY MARSHMALLOW. </p> <figcaption><cite>Eating my Marshmallow by Mandy Michael</figcaption>
</figure>

It’s easy to fall into the trap of thinking that the figure element is just for images or image-like content, but you can use it for content like audio, video, charts, poems, quotations or even tables of statistics. Because the element is so versatile you can combine it with so many other elements to provide more and more context about the figure for assistive technology, browsers, and other technologies consuming your website.

Wrapping Up

These are just some of the ways HTML elements can be combined for better context. HTML elements are indeed useful and valuable on their own when used as isolated pieces — and using them this way is a good first step. But, like Voltron, when you combine HTML elements together, the individual pieces form a greater whole and gain much more meaning and power. It’s important that we don’t think of HTML as individual pieces of code, but parts of a whole because HTML is really a mass of totally amazing combinations.

You can combine and use HTML elements in any number of ways to best represent your content. Don’t simply stick to the same old things you know; take the time to explore HTML and learn about all it has to offer. Like any language, we should make the most of it and use it to its full potential.

The more accurate you are in marking up your content, the better that content will be represented across technologies, and the more prepared it will be for any anything else that is used to interpret your HTML in the future.

So, go forth and HTML elements, unite!


Resources

In my opinion, the best resource for learning and understanding how to use HTML (outside of the spec itself) is the MDN Web Docs. It lists all the HTML elements you could ever need.

The following are among the elements covered in this post:

  • <abbr>
  • <cite>
  • <code>
  • <dfn>
  • <figure>
  • <figcaption>
  • <kbd>
  • <samp>
  • <var>

If you are a TypeScript fan and don’t understand why Semantic HTML is important, I wrote this post just for you: Understanding why Semantic HTML is important as told by TypeScript.

The post HTML elements, unite! The Voltron-like powers of combining elements. appeared first on CSS-Tricks.

XOXO 2018

There’s not much talk about frameworks here. There’s no shaming about old techniques, or jokes about JavaScript. There’s just a couple hundred people all around me laughing and smiling and watching talks about making things on the web and it all feels so fresh and new to me. Unlike many other conferences I’ve visited, these talks are somehow inclusive and rather feel, well, there’s no other word for it: inspiring.

I’m sitting in a little room buried underneath the Veterans Memorial Coliseum in Portland and I’m here for my third XOXO. And I can’t stop smiling.

Although the festival is not entirely focused on coding and front-end development, there are a lot of developers here that make art on the web for fun. From Jenn Schiffer’s pixel art to Monica Dinculescu’s emoji projects and Nicole He’s buck-wild enhance.computer, there’s a lot of interesting discussions about coding — but! — it’s from a very different perspective than the one I’m familiar with.

Most conferences tend to focus on being practical. Here’s the newest technique! Here’s how to improve your career! Here’s the coolest new folks that you should be following! But it’s important to remember that the web isn’t only a serious place for serious work. It can be this entirely other thing, too.

The web can be for fun. It can be utterly weird and unexpected. And that’s what we’re all seeing in this little room right now at XOXO; websites that can’t be monetized, websites that can’t be controlled by corporate interests or giant ad networks.

Websites that are just for fun.

The post XOXO 2018 appeared first on CSS-Tricks.

What’s the difference between ./dogs.html and /dogs.html?

They are both URL paths. They have different names, though.

<!-- root-relative -->
<a href="./dogs.html">Dogs</a> <!-- absolute -->
<a href="/dogs.html">Dogs</a>

There are also fully-qualified URLs that would be like:

<!-- fully qualified -->
<a href="https://website.com/dogs.html">Dogs</a>

Fully-qualified URL’s are pretty obvious in what they do — that link takes you to that exact place. So, let’s look those first two examples again.

Say you have a directory structure like this on your site:

public/
├── index.html
└── animals/ ├── cats.html └── dogs.html

If you put a link on cats.html that links to /dogs.html (an “absolute” path), it’s going to 404 — there is no dogs.html at the base/root level of this site! The / at the beginning of the path means “start at the very bottom level and go up from there” (with public/ being the very bottom level).

That link on cats.html would need to be written as either ./dogs.html (start one directory back and work up) or /animals/dogs.html (explicitly state which directory to start at).

Absolute URLs get longer, naturally, the more complex the directory structure.

public/
├── animals/ └── pets/ ├── c/ | └── cats.html └── d/ └── dogs.html

With a structure like this, for dogs.html to link to cats.html, it would have to be either…

<!-- Notice the TWO dots, meaning back up another folder level -->
<a href="../c/cats.html">cats</a> <!-- Or absolute -->
<a href="/animals/pets/c/cats.html">cats</a>

It’s worth noting in this scenario that if animals/ was renamed animal/, then the relative link would still work, but the absolute link would not. That can be a downside to using absolute links. When you’re that specific, making a change to the path will impact your links.

We’ve only looked at HTML linking to HTML, but this idea is universal to the web (and computers, basically). For example, in a CSS file, you might have:

body { /* Back up one level from /images and follow this path */ background-image: url(./images/pattern.png);
}

…which would be correct in this situation:

public/
├── images/
| └── pattern.png
├──index.html
└── style.css

But if you were to move the CSS file…

public/
├── images/
| └── pattern.png
├── css/
| └── style.css
└── index.html

…then that becomes wrong because your CSS file is now nested in another directory and is referencing paths from a deeper level. You’d need to back up another folder level again with two dots, like ../images/pattern.png.

One URL format isn’t better than another — it just depends on what you think is more useful and intuitive at the time.

For me, I think about what is the least likely thing to change. For something like an image asset, I find it very unlikely that I’ll ever move it, so linking to it with an absolute URL path (e.g. /images/pattern.png) seems the safest. But for linking documents together that all happen to be in the same directory, it seems safer to link them relatively.

The post What’s the difference between ./dogs.html and /dogs.html? appeared first on CSS-Tricks.

Updating a CSS Variable with JavaScript

Here’s a CSS variable (formally called a “CSS custom property”):

:root { --mouse-x: 0px; --mouse-y: 0px;
}

Perhaps you use them to set a position:

.mover { left: var(--mouse-x); top: var(--mouse-y);
}

To update those values from JavaScript, you’d:

let root = document.documentElement; root.addEventListener("mousemove", e => { root.style.setProperty('--mouse-x', e.clientX + "px"); root.style.setProperty('--mouse-y', e.clientY + "px");
});

That’s all.

See the Pen Set CSS Variable with JavaScript by Chris Coyier (@chriscoyier) on CodePen.

The post Updating a CSS Variable with JavaScript appeared first on CSS-Tricks.

Introducing Trashy.css

It began, as many things do, with a silly conversation. In this case, I was talking with our Front End Technology Competency Director (aka “boss man”) Mundi Morgado.

It went something like this…

Mundi Morgado I want you to build a visual screen reader.

Nathan Smith Who what now?

Mundi Morgado I want a CSS library that allows you to see the structure of a document. It shouldn’t use class so that you’re forced to focus on semantics. Also, make it theme-able.

Nathan Smith Sure, let me see what I can come up with.

Fast-forward a week, and we’ve got what we are now calling:

Trashy.css: The throwaway CSS library with no class

Why throwaway? Well, it’s not really meant to be a fully fledged, production-ready style framework. Rather, it’s like training wheels for document semantics, with some bumper lanes (think: bowling) to keep you on the right track.

It’s part of our ongoing effort at TandemSeven to promote code literacy throughout our organization. As more of our UX designers are beginning to share responsibility for the accessibility and semantics of a project, it makes sense that we would build in such a way that allows UX and development to be more collaborative.

There are four main aspects to Trashy.

Trashy: “Basic”

First is the base trashy.css file, which applies a passably basic look and feel to the majority of common HTML elements. Check out this example of a basic page.

Trashy: “Boxes”

Second, there is trashy.boxes.css. This visually distinguishes otherwise invisible semantic elements, such as: header, main, nav, etc. That way, one can see where those elements are (or aren’t) as a page is being authored. Here’s a page with semantic boxes outlined.

Trashy: “Theme”

Thirdly, theming is possible via trashy.theme.css. This is mostly just an example — inspired by PaperCSS) — of how to make UI look “hand drawn,” to prevent observers from being too fixated on the look and feel, rather than the semantics of a document. Here’s the example theme in action.

Trashy: “Debug”

Lastly, there is a trashy.debug.css file that highlights and calls out invalid and/or problematic markup. Here’s a gnarly example of “everything” going wrong on a single HTML page. This was inspired by a11y.css, though it diverges in what is considered noteworthy.

For instance, we call out “div-itis” when multiple div:only-child have been nested within one another. We’re also opinionated about type="checkbox" being contained inside of a <label>. This is for maximum click-ability within an otherwise dead whitespace gap, between a checkbox (or radio) and its textual label.

Any or all of these CSS files can be applied individually or in conjunction with one another. There is also a bookmarklet (labeled “GET TRASHY!”) on the Trashy home page you can use to get results for any webpage.

The bookmarklet will remotely pull in:

  • sanitize.css
  • trashy.css
  • trashy.boxes.css
  • trashy.debug.css

Our “reset” – Sanitize.css

A quick word on Santitize.css: It was created by my coworker Jonathan Neal (author of Normalize.css), as a way to have a semi-opinionated CSS “reset.” Meaning, it puts in a lot of defaults that we find ourselves writing as developers anyway, so it makes for a good starting point.

Technically speaking

Okay, so now that we’ve covered the “why,” let’s dig into the “how.”

Basically, it all revolves around using (abusing?) the ::before and ::after pseudo elements. For instance, to show the name of a block level tag, we’re using this CSS.

Semantic tags (using ::before)

Here is an abbreviated version of the trashy.boxes.css file, for succinctness. It causes the <section> tag to have a dashed border, and to have its tag named displayed the top left corner.

section { border: 1px dashed #f0f; display: block; margin-bottom: 2rem; /* 20px. */ padding: 2rem; /* 20px. */ position: relative;
} section > :last-child { margin-bottom: 0;
} section::before { background: #fff; color: #f0f; content: "section"; font-family: "Courier", monospace; font-size: 1rem; /* 10px. */ letter-spacing: 0.1rem; /* 1px. */ line-height: 1.3; text-transform: uppercase; position: absolute; top: 0; left: 0.3rem; /* 3px. */
}

Warning messages (using ::after)

Likewise, here’s a snippet of code from the trashy.debug.css file that drives the markup warning messages. This particular example causes <script> tags to be displayed, which may be further optimized or need the developer’s attention: inline JavaScript and/or external src without async.

In the case of inline JS, we set the font-size and line-height to 0 because we’re making the element visible. We yank the text off the page via text-indent: -99999px just to make sure it doesn’t show up. We wouldn’t want that random JS code displayed alongside legit page content.

(Please don’t ever do this for “real” content. It’s just a hack, mkay?)

To get our error message to show up though, we have to set the font-size and line-height back to non-zero values, and remove our text-indent. Then, with a bit more absolute positioning, we ensure the message is visible. This lets us see, amidst the rest of the page content, whereabouts to check (via DOM inspector) for the <script> insertion point.

script:not([src]),
script[src]:not([async]),
script[src^="http:"] { color: transparent; display: block; font-size: 0; height: 2rem; /* 20px. */ line-height: 0; margin-bottom: 2rem; /* 20px. */ position: relative; text-indent: -99999px; width: 100%;
} script:not([src])::after,
script[src]:not([async])::after,
script[src^="http:"]::after { background: #f00; color: #fff; display: inline-block; font-family: Verdana, sans-serif; font-size: 1.1rem; /* 11px. */ font-weight: normal; left: 0; line-height: 1.5; padding-left: 0.5rem; /* 5px. */ padding-right: 0.5rem; /* 5px. */ pointer-events: none; position: absolute; text-decoration: none; text-indent: 0; top: 100%; white-space: nowrap; z-index: 1;
} body script:not([src])::after,
body script[src]:not([async])::after,
body script[src^="http:"]::after { top: 0;
} script:not([src])::after { content: 'Move inline <script> to external *.js file' ;
} script[src]:not([async])::after { content: 'Consider [async] for <script> with [src="…"]' ;
} script[src]:not([src=""]):not([async])::after { content: 'Consider [async] for <script> with [src="' attr(src) '"]' ;
} script[src^="http:"]::after { content: 'Consider "https:" for <script> with [src="' attr(src) '"]' ;
}

Note: Some scripts do need to be loaded synchronously. You wouldn’t want your “app” code to load before your “framework” code. Heck, some inline JS is probably fine too, especially if you’re doing some super speed optimization for the critical rendering path. These warnings are “dumb” in the sense that they match only via CSS selectors. Take ‘em with a grain of salt, your mileage may vary, etc.

JS bookmarklet

The aforementioned JS bookmarklet finds all <link rel="stylesheet"> and <style> tags in the page, and causes them to be ineffective. This allows us to add in our own CSS to take over, so that the only styles applied are those provided directly via Trashy.

The magic is accomplished by setting rel="stylesheet" to rel="". If an external stylesheet is not identified as such, even if it’s cached, the browser will not apply its styles to the page. Similarly, we destroy the contents of any inline <style> tags by setting the innerHTML to an empty string.

This leaves us with the tags themselves still intact, because we still want to validate that no <link> or <style> tags are present within <body>.

We also check that there aren’t too many <style> tags being used in the <head>. We allow for one, since it could be used for the critical rendering path. If there’s a build process to generate a page with consolidated inline styles, then it’s likely they’re being emitted through a single tag.

<a href="javascript:( function (d) { var f = Array.prototype.forEach; var linkTags = d.querySelectorAll('[rel=\'stylesheet\']'); var styleTags = d.querySelectorAll('style'); f.call(linkTags, function (x) { x.rel = ''; }); f.call(styleTags, function (x) { x.innerHTML = ''; }); var newLink = d.createElement('link'); newLink.rel = 'stylesheet'; newLink.href = 'https://t7.github.io/trashy.css/css/bookmarklet.css'; d.head.appendChild(newLink); }
)(document);"> GET TRASHY!
</a>

Go forth, get Trashy!

Get Trashy

That pretty much covers it. It’s a simple drop-in to help you visualize your document semantics and debug possibly problematic markup.

I have also found it to be super fun to use. A quick click of the bookmarklet on any given site usually yields lots of things that could be improved upon.

For instance, here’s what CNN’s site looks like with Trashy applied…

P.S. Call security!

If you try this with Twitter’s site, you might wonder why it doesn’t work. We were initially perplexed by this, too. It has to do with the site’s Content Security Policy (CSP). This can be used to disallow CSS and/or JavaScript from being loaded externally, and can whitelist safe domains.

This can be set either at the server level, or by a <meta> tag in the <head>.

<meta http-equiv="Content-Security-Policy" content="…" />

Read more about CSP here.

I know what you’re thinking…

Can’t you just destroy that meta tag with JS?

In the case of Twitter, it’s emitted from the server. Even if it were in the HTML, destroying it has no effect on the actual browser behavior. It’s locked in.

Okay, so…

Can’t you insert your own security meta tag and override it?

You’d think so. But, thankfully, no. Once a CSP been accepted by the browser for that page, it cannot be overridden. That’s probably a good thing, even though it ruins our fun.

I suppose that’d be like wishing for more wishes. It’s against the genie rules!

The post Introducing Trashy.css appeared first on CSS-Tricks.

Working With Events in React

Most of the behavior in an application revolves around events. User enters a value in the registration form? Event. User hits the submit button? Another event. Events are triggered a number of ways and we build applications to listen for them in order to do something else in response.

You may already be super comfortable working with events based on your existing JavaScript experience. However, React has a distinct way of handling them. Rather than directly targeting DOM events, React wraps them in their own event wrapper. But we’ll get into that.

Let’s go over how to create, add and listen for events in React.

Creating Events

We’ll start by creating a form that has an input and a button. An event will be triggered when a value is entered. The button is used to call a function which will reverse that value.

Here’s how it’ll work:

  • An empty input field allows the user to enter text.
  • An onChange event is triggered when values are entered in the input. This calls a function — handleChange() — that is used to set a new state for the input.
  • When the “Reverse Text” button is clicked, another event is triggered. This calls a function — handleReverse() — to set a new state for reversedText.

Here’s that translated into code:

class App extends React.Component { state = { /* Initial State */ input: "", reversedText: "" }; /* handleChange() function to set a new state for input */ handleChange = event => { const value = event.target.value; this.setState({ input: value }); }; /* handleReverse() function to reverse the input and set that as new state for reversedText */ handleReverse = event => { event.preventDefault(); const text = this.state.input; this.setState({ reversedText: text .split("") .reverse() .join("") }); }; render() { return ( <React.Fragment> { /* handleReverse() is called when the form is submitted */ } <form onSubmit={this.handleReverse}> <div> { /* Render input entered */} <label>Text: {this.state.input}</label> </div> <div> { /* handleChange() is triggered when text is entered */ } <input type="text" value={this.state.input} onChange={this.handleChange} placeholder="Enter a text" /> </div> <div> <button>Reverse Text</button> </div> </form> { /* Render reversed text */} <p>Reversed Text: {this.state.reversedText}</p> </React.Fragment> ); }
}}

See the Pen React Event Pen – form by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Listening to component events

Let’s say you have a component like this;

class IncrementButton extends React.Component{ render() { return ( <React.Fragment> <button>+</button> </React.Fragment> ) }
}

Will including it in your App component like this work?

class App extends React.Component{ state = { count: 0 } handleIncrement = (event) => { this.setState({ count: this.state.count + 1}) } render() { return( <React.Fragment> <h1>{this.state.count}</h1> <IncrementButton onClick={this.handleIncrement} /> </React.Fragment> ) }
}

No, it won’t because you can only listen to events on DOM elements. We touched on this at the beginning of the post, but React components are wrappers for DOM elements. That means we essentially have a layer that we need to pass through to listen for the event.

The way around this is to pass the event handler as a prop to the child component. Then the prop is passed down to the click event as an attribute like so:

class IncrementButton extends React.Component{ render() { return ( <React.Fragment> <button onClick={this.props.increaseButton}>+</button> </React.Fragment> ) }
} class App extends React.Component{ state = { count: 0 } handleIncrement = (event) => { this.setState({ count: this.state.count + 1}) } render() { return( <React.Fragment> <h1>{this.state.count}</h1> <IncrementButton increaseButton={this.handleIncrement} /> </React.Fragment> ) }
}

See the Pen React Event Pen – Component Events by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

You could make use of a stateless functional component instead:

const IncrementButton = (props) => { return ( <React.Fragment> <button onClick={props.increaseButton}>+</button> </React.Fragment> )
}

Adding event listeners

There may be times when you want to make use of certain DOM events that are triggered when the component is mounted. Let’s see this using the resize event — we want to see the width of the window whenever it is resized.

class App extends React.Component{ state = { windowWith: window.innerWidth } handleResize = (event) => { this.setState({ windowWith: window.innerWidth }) } render() { return( <React.Fragment> <h1>Window Width</h1> <h1>{this.state.windowWith}</h1> </React.Fragment> ) }
}

If we create a component and try it out like we have below, then the event will not be triggered. We’ll need to add the event listener (handleResize() in this case) and the event type like we have here:

class App extends React.Component{ state = { windowWith: window.innerWidth } handleResize = (event) => { this.setState({ windowWith: window.innerWidth }) } componentDidMount() { window.addEventListener('resize', this.handleResize) } componentDidUnmount() { window.removeEventListener('resize', this.handleResize) } render() { return( <React.Fragment> <h1>Window Width</h1> <h1>{this.state.windowWith}</h1> </React.Fragment> ) }
}

See the Pen React Event Pen – addEventListener by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Now, the event listener will be added when the component mounts. That means our component is actively listening to the browser window and will display its width when it updates.

In summary

OK, so we covered quite a bit of ground in a very small amount of space. We learned that React does not connect directly to a DOM event, but rather Synthetic Events that are wrappers for DOM events. We dug into the process for creating event listeners so that they attach to Synthetic Events and, from there, made sure that a component will update when those events are triggered.

Additional resources

  • Handling Events – React documentation
  • SyntheticEvent – React documentation, including all event types
  • 5 Essential React Concepts to to Know Before Learning Redux – Chris Nwamba provides a nice overview for event handling in React in the second part of this series

The post Working With Events in React appeared first on CSS-Tricks.

Helping a Beginner Understand Getting a Website Live

I got a great email from a fellow named Josh Long the other day. He is, in his words, “relatively new to web design” and was a bit stuck on the concept of getting a site live. I should say that I’m happy to get emails like this an I always read them, but I typically can’t offer tech support over email. If I can respond at all, I normally point people to other community resources.

In this case, it struck me what a perfect moment this is for Josh. He’s a little confused, but he knows enough to be asking a lot of questions and sorting through all this stuff. I figured this was a wonderful opportunity to dig into his questions, hopefully helping him and just maybe helping others in a similar situation.

Here’s one of the original paragraphs Josh sent me, completely unedited:

I’m relatively new to web design, but I’ve taken a few courses on HTML and CSS and I’ve done a Codecademy course on JavaScript. But, (jumping forward probably quite a while here!) after having fully designed and coded a HTML/CSS/JS website or webpage, I don’t fully understand the full process of going from a local site hosted with mamp/wamp to publishing a public site using wordpress(?) or some other host (is WordPress even a host?!) and also finding a server that’s suitable and some way of hosting images/videos or other content. (If that sounded like I didn’t know what half of those meant, it’s because unfortunately I don’t!.. but I’d really like to!)

Can you sense that enthusiasm? I love it.

We worked together a bit to refine many of his questions for this post, but they are still Josh’s words. Here we go!


What is a Domain Registrar? I get they are for registering domain names, but what’s the difference between them? How do you know which one is right for you? A quick search for “best domain hosts” on Google gave me 5 ads for companies who are domain registrars/hosts and 9 “Top 10” style pages that look as though they have some sort of affiliation with at least one company they’re suggesting. Am I just looking for the cheapest one?

You’re exactly right, domain registrants are for registering domain names. If you want joshlongisverycool.com, you’re going to have to buy it, and domain registrants are companies that help you do that.

Searching for a domain name

It’s a bummer that web search results are so saturated by ads and affiliate-link-saturated SEO-jacked pages. You’ll never get total honesty from that because those pages are full of links promoting whoever will pay them the most to send new customers. Heck, even Google themselves will sell you a domain name.

The truth is that you can’t go too wrong here. Domain names are a bit of a commodity and the hundreds of companies that will sell you one largely compete on marketing.

Some things to watch out for:

  • Some companies treat the domain as a loss leader. Like a grocery store selling cheap milk to hope you buy some more stuff while you are there. The check out process at any domain registrant will almost certainly try to sell you a bunch of extra stuff. For example, they might try to sell you additional domain names or email hosting you probably don’t need. Just be careful.
  • Web hosts (which we’re getting to next) will often sell them to you along with hosting. That’s fine I suppose, but I consider it a bit of a conflict of interest. Say you choose to move hosts one day. That hosting company is incentivized in the wrong direction to make that easy for you. If the domain is handled elsewhere, that domain registrant is incentivized the right direction to help you make changes.

I hate to add to the noise for you, but here are some domain registrants that I’ve used personally and aren’t paying for sponsorship here nor are affiliate links:

  • Hover
  • GoDaddy
  • Google Domains
  • Network Solutions
  • Amazon Route 53

Our own Sarah Drasner recommends looking at ZEIT domains, which are super interesting in that you buy and manage them entirely over the command line.

I might suggest, if you can see yourself owning several domain names in your life, keeping them consolidated to a single registrant. Managing domains isn’t something you’ll do very often, so it’s easy to lose track of what domains you registered on what registrant, not to mention how/where to change all the settings across different registrants.

I’d also suggest it’s OK to experiment here. That’s how all of us have learned. Pick one with a WP Engine is a web host that focuses specifically on WordPress.

  • Media Temple has WordPress-specific hosting, but has a wider range of services from very small and budget friendly to huge and white-glove.
  • BlueHost is has very inexpensive hosting choices, but has essentially the same capabilities as those others.
  • Now here some other web hosts that are a little less traditional. Forgive the techy terms here — if they don’t mean anything to you, just ignore them.

    • Netlify does static site hosting, which is great for things like static site generators and JAMstack sites.
    • Zeit is a host where you interact with it only through the command line.
    • Digital Ocean has their own way of talking about hosting. They call their servers Droplets, which are kind of like virtual machines with extra features.
    • Heroku is great for hosting apps with a ready-to-use backend for things like Node, Ruby, Java, and Python.
    • Amazon Web Services (AWS) is a whole suite of products with specialized hosting focuses, which are for pretty advanced users. Microsoft Azure and Google Cloud are similar.

    Again, I’d say it’s OK to, in a sense, make some mistakes here. If you aren’t hosting something particularly mission-critical, like your personal website, pick a host that seems to fit the bill and give it a go. Hopefully, it works out great — if not, you can move. Moving isn’t always super fun, but everybody ends up doing it, and you’ll learn as you go.

    When you buy web hosting, that host is going to tell you how to use it. One common way is that the host will give you WordPress and CraftCMS. They don’t really have anything directly to do with that connection between working locally on a site and getting that site live. But they do rather complicate it.

    The reason that you’d use a CMS at all is to make working on your site easier. Consider this site you’re looking at right now. There are tens of thousands of pages on this site. It would be untenable for each of them to be a hand-authored file.html file.

    Instead, a CMS allows us to craft all those pages by combining data and templates.

    Let’s consider the technology behind WordPress, a CMS that works pretty good for CSS-Tricks. In order for WordPress to run, it needs:

    1. PHP (the back-end language)
    2. MySQL (the database)
    3. Apache (the web server)

    You can do all that locally!

    I use Local by Flywheel for that (Mac and Windows), but there are a number of ways to get those technologies running: MAMP, Docker, Vagrant, etc.

    That’ll get you up and running locally with your CMS. That’s a beautiful thing. Having a good local development environment for your site is crucial. But it doesn’t help you get that site live.

    We’ll go over getting all this to a live site a bit later, but you should know this: the web server that you run will need to run these same technologies. Looking at the WordPress example from above, your web server will also need to run PHP, MySQL, and Apache. Then you’ll need to set up a system for getting all your files from your local computer to your web server like you would for any other site, but also probably have a system for dealing with the database. The database is a bit tricky as it’s not a “flat file” like most of the rest of your site.

    A CMS could be built from any set of technologies, not just the ones listed above. For example, see KeystoneJS. Instead of PHP, Keystone is Node.js. Instead of MySQL for the database, it uses MongoDB. Instead of Apache, it uses Express. Just a different set of technologies. Both of which you can get running locally and on a live web server.

    A CMS could even have no database at all! Static site generators are like this. You get the site running locally, and they produce a set of flat files which you move to your live server. A different way to do things, but absolutely still a CMS. What I always say is that the best CMS is one that is customized to your needs.


    What is “Asset Hosting”? Are assets not content? What is the difference between a CMS and an asset hosting service? What does an asset host do?

    Let’s define an asset: any “flat” file. As in, not dynamically generated like how a CMS might generate an HTML file. Images are a prime example of an “asset.” But it’s also things like CSS and JavaScript files, as well as videos and PDFs.

    And before we get any further: you probably don’t need to worry about this right away. Your web host can host assets and that’s plenty fine for your early days on small sites.

    One major reason people go with an asset host (probably more commonly referred to as a CDN or Content Delivery Network) is for a speed boost. Asset hosts are also servers, just like your web host’s web server, but they are designed for hosting those flat file assets super fast. So, not only do those assets get delivered to people looking at your site super fast, but your web server is relieved of that burden.

    You could even think of something like YouTube as an asset host. That 100 MB video of a butterfly in your garden is a heavy load for your little web server, and potentially a problem if your outgoing bandwidth is capped like it often is. Uploading that video to YouTube puts your video into that whole social universe, but a big reason to do it other than the social stuff is that it’s hosting that video asset for you.


    I’ve heard of “repositories”, but don’t really get what they are. I hear stuff like “just upload it to my Git Repository.” What the heck does that mean? I feel like a moron for asking this. What is Git? What is it for? Do I need to use it? Is it involved in the “local to live” process at all?

    Sorry you got hit with a “just” there. There is an epidemic in technology conversations where people slip that in to make it seem like what they are about to say is easy and obvious when it could be neither depending on who is reading.

    But let’s get into talking about Git repositories.

    Git is a specific form of version control. There are others, but Git is so dominant in the web industry that it’s hardly worth mentioning any others.

    Let’s say you and me are working on a website together. We’ve purchased a domain and hosting and gotten the site live. We’ve shared the SFTP credentials so we both have access to change the files on the live site. This could be quite dangerous!

    Coda is a code editor that let’s you edit files directly on a sever you’ve connected to over SFTP. Cool, but dangerous!

    Say we both edit a file and upload it over SFTP… which change wins? It’s whoever uploaded their file last. We have no idea who has done what. We’re over-writing each other and have no way of staying in sync with each other’s changes, changes immediately affect the live site which could break things and we have no way of undoing changes in case we break things. That’s a situation so unacceptable that it’s really never done.

    Instead, we work with version control, like Git. With Git, when we make changes, we commit them to a repository. A repository can be hosted anywhere, even on your local machine. But to make them really useful, they are hosted on the internet somewhere everyone has access to. You’ve surely seen GitHub, which hosts these repositories and adds a bunch of other features like issue tracking. Similar are GitLab and Bitbucket.

    Now let’s say you and me are working on that same site, but we’ve set up a Git repository for it. When I make a change, I commit it to the repository. If you want to make a change as well, you have to pull my changes down which merges them into your own copy of the code. Then you can push your changes up to the repository. Like anything, it gets more complicated, but that’s the gist of it.

    But a Git repository isn’t the live website. You’re on your own for getting the files from a Git repository to a live site. Fortunately, that’s a situation that everyone faces, so there are lots of options. Good thing your last question is about this!


    OK. So now with all that straight… where do you start with going from local to live? Where do you “upload” your HTML, CSS and JavaScript files? How do you link your shiny new domain name to those files and see it out in the wild? Which service is in charge of adding new content to your site, or updating it? Does it get really confusing if you have different companies for each service?

    Let’s start with a very simple website on what I’d consider typical web hosting. Say you have just index.html, style.css, and script.js files on your local computer which is your entire website. You’ve purchased a domain name and pointed the DNS settings at a web host. That host has given you SFTP credentials. You’ll use those credentials in an app that allows SFTP connections to log in:

    Your host will also tell you which folder is the “public root” of your website. The files there will be out on the public internet for the world to see!

    You might hear people refer to the “live” website as a “production” site. When someone asks something like, Did that bug make it to production?” they mean whether the bug is on the live website. “Development” is your local computer. You might also have a “Staging” site, which is a clone of the live website on the same hardware/software of the live site for testing.

    Remember earlier when we talked about Git repositories? While the repositories themselves don’t directly help you get the files in them to your web server, most systems that help you with the local-to-live process work with your repositories.

    The phrase “local-to-live” refers to deployment. When you have changes that you want to go out to your production website, you deploy them. That’s the process of moving your work from “development” to “production.”

    One service that helps with this idea of deployment is Beanstalk. Beanstalk hosts your Git repository, plus you give it the SFTP credentials for your server — that way it can move the files to your web server when you make commits. Cool right? Say you wanted to host that Git repo elsewhere though, like GitHub, Bitbucket, or Gitlab. Check out DeployBoy, which does the same thing, only it can connect to those sites as well. It probably comes as no surprise by now that there are lots of options here, ranging in price and complexity.

    Let’s go back to our WordPress example.

    1. You’ve got it running locally (on your computer) just perfectly and now want to go live with it.
    2. You’ve bought a domain name from a registrar.
    3. You’ve purchased hosting that meets WordPress requirements.
    4. You’ve pointed the DNS of the domain name at the web host.
    5. You’ve verified it’s all working (easy way: upload an index.html file in the public root via SFTP and verify that it loads when you type you type the domain name into a browser.)

    Now, you’ve still got some work to do:

    1. Set up a Git repository for the site.
    2. Set up a deployment service to move the files from the repository to the live site.
    3. Configure/Set up the live site as needed. For example, you’ll need a database on the live site. You’ll have to create that (your host will have instructions) and do things like run the WordPress installer and update configuration files.
    4. If you have things in your local database that you want to move to the live site, you might be exporting/importing things. That can happen at the raw MySQL level using WordPress’ native import/export features, or a fancy plugin like WP DB Migrate Pro.

    It’s a non-trivial amount of work! Sorry. This process is pretty similar for any site though. It’s a matter of configuring and setting up your production web server exactly how it should be, then deploying files to it. Every site is a bit different, but you’ll get the hang of this whole dance.

    It really is a big dance. I’ve only painted one picture for you here. I tried to pick one that was generic and broad enough that it shows the landscape of what needs to be done. But, at every step in this dance, there are different ways you can do things, different services you can pick, companies trying to help you at different pain points… it’s an ever-changing world.

    Right now, Netlify is enjoying a lot of popularity because they are one of the only web hosts that actually helps you with deployment. They’ll watch your Git repositories and do deployment for you! Netlify is for static sites only, but that can be a whole world onto itself. ZEIT also is massively innovative in how it helps with deploying and hosting web projects, including directly connecting with GitHub.


    Good luck!

    I hope this was helpful. Remember, you aren’t alone in all this. Zillions of other developers have done this before you and there is help to be found on the internet.

    Oh, and remember: the best way to learn anything at all is to…


    https://css-tricks.com/wp-content/uploads/2018/08/jbw.mp3

    The post Helping a Beginner Understand Getting a Website Live appeared first on CSS-Tricks.

    What do we call browser’s native development tools?

    You know, that panel of tools that allows you to do stuff like inspect the DOM and see network requests. How do the companies that make them refer to them?

    • Chrome calls them DevTools.
    • Edge calls them DevTools.
    • Firefox calls them Developer Tools.
    • Safari calls it the Web Inspector.

    I think it’s somewhat safe to generically refer to them as DevTools. Safari is the only browser that doesn’t use that term, but I imagine even die-hard Safari users will know what you mean.



    The post What do we call browser’s native development tools? appeared first on CSS-Tricks.

    Flutter: Google’s take on cross platform

    Flutter is a mobile You can see more examples of who’s using Flutter (including the app I’ve worked on) on Flutter’s website on the showcase page.

    Right now, there’s a lot of buzz about Flutter. The question I see most often is, “Flutter or React Native…which one should I use?” Like all things in programming, its all about the tradeoffs you’re willing to make.

    I’m going to try to convince you that Flutter is the best option for mobile app development. I believe it’s better than any other cross platform framework, and it’s possibly better than native development — but more on that in a bit.

    Before that though, let me walk (quickly) through what Flutter is, and what it is not, starting with the Dart programming language.

    What’s Dart?

    Dart is a programming language created by Google and was used to write Flutter. Dart was created, more or less, because Google wanted a language that was “better” than JavaScript to write server side and front-end code. From what I understand, the main issue they had with JavaScript is how slowly it updates with new features since it relies on a huge committee for approvals and several browser vendors to implement it.

    After a series of decisions about whether to take on JavaScript directly or not, Google decided to make a language that semantically fit inside of JavaScript. In other words, every single thing you write in Dart can compile to JavaScript. This is why they didn’t just use Java — it’s semantically huge.

    Here’s a leaked email chain from Google from 2010. It’s the “coming to Jesus” moment that they decided they needed to do something about JavaScript.

    The fundamentals of Dart are similar to all high-level languages. That said, programming languages are, as it turns out, hard to learn.

    There’s good news, though. Dart excels at being a “safe” language to learn. Google didn’t set out to create anything innovative with Dart. They were seeking to make a language that was simple, productive and could be compiled into JavaScript.

    There is nothing particularly exciting about its syntax, and no special operators that will throw you through a loop. In Dart (unlike JavaScript), there is one way to say true: True. There is one way to say false: False.

    In JavaScript, this coerces to True:

    if (3) { ... }

    In Dart, that would blow up your program. Dart is, at its core, a productive, predictable, and simple language.

    This is important, because writing an app in Flutter is simply writing Dart. Flutter is, underneath it all, a library of Dart classes. There is no markup language involved or JSX-style hybrid language. Every bit of front-end code is written in Dart. No HTML. No CSS.

    Why does Flutter use Dart?

    If you’re coming from literally any other background (and you’re like me), you’ve probably complained about the fact that Flutter uses Dart, and not JavaScript. (Developers are, believe it or not, opinionated.)

    And there are reasons to be skeptical of this choice. It’s not one of the hot languages of today. It’s not even one of the top 25 most used languages. What gives? Is Google just using it because it’s their language? I’d imagine that played a role, but there are practical reasons, too.

    • Dart supports both Just In Time (JIT) compiling and Ahead of Time (AOT) compiling.
      • The AOT compiler changes Dart into efficient native code. This makes Flutter fast (a win for the user and the developer), but it also means that almost all of the framework is written in Dart. For you, the developer, that means you customize everything.
      • Dart’s optional JIT compiling allows hot-reloading to exist. Fast development and iteration is a key to the joy of using Flutter. When you save code in your text editor, your app is updated in your simulator in less than a second.
    • Dart is Object Oriented. This makes it easy to write visual user-experiences exclusively with Dart, with no need for a markup language.

    • Dart is a productive and predictable language. It’s easy to learn and it feels familiar. Whether you come from a dynamic language or a static language, you can get up and running with ease.
    • And yes, I’d image that it is extremely appealing to use a language made by the same company, because the Flutter team could work closely with the Dart team to implement new needed features.

    Flutter vs. React Native (and other options)

    Before I offer up my unsolicited opinions on your other options, I want to make this crystal clear: Flutter is not the answer 100% of the time. It’s a tool and we should choose the right tool for the job at hand. That said, I’d only argue that it’s something you should strongly consider in the future.

    Native development (iOS and Android)

    Your first choice is to write native apps for iOS and Android. This gives you maximum control, debugging tools, and (potentially) a very performant app. At a company, this likely means you have to write everything twice; once for each platform. You likely need different developers on different teams with different skillsets that can’t easily help each other.

    React Native, WebViews, and other cross-platform JavaScript options

    Your second option: cross-platform, JavaScript-based tools such as WebViews and React Native. These aren’t bad options. The problems you experience with native development disappear. Every front-end web developer on your team can chip in and help — all they need are some modern JavaScript skills. This is precisely why large companies such as AirBnb, Facebook, and Twitter have used React Native on core products. (AirBnb recently announced that it would stop using React Native, because of some of the issues I’ll describe below.)

    The first “mobile apps” to be built cross platform are simply WebViews that run on WebKit (a browser rendering engine). These are literally just embedded web pages. The problem with this is basically that manipulating the DOM is very expensive and doesn’t perform well enough to make a great mobile experience.

    Some platforms have solved this problem by building the “JavaScript bridge.” This bridge lets JavaScript talk directly to native widgets.

    This is much more performant than WebViews, because you eliminate the DOM from the equation, but it’s still not ideal. Every time your app needs to talk directly to the rendering engine, it has to be compiled to native code to “cross the bridge.” On a single interaction, the bridge must be crossed twice: once from platform to app, and then back from app to platform.

    Flutter differs because it uses its own rendering engine, Skia, which is the same rendering engine used in Chrome. Skia can communicate with Flutter apps. As a result, Flutter accepts local events directly, rather than having to first compile them into JavaScript. This is essentially possible because Flutter compiles to native ARM code. This is the secret to its success. When your app is fired up on a user’s device, it’s entirely running in the language that the device’s operating system expects.

    The JavaScript bridge is a marvel of modern programming, to be sure, but it presents three big problems.

    The first problem is that debugging is hard. When there’s an error in the runtime compiler, that error has to be traced back across the JavaScript bridge and found in the JavaScript code. It may be in markup or CSS-like syntax as well. The debugger itself may not work as well as we’d like it to.

    A second bigger issue, though, is performance. The JavaScript bridge is very expensive. Every time something in the app is tapped, that event must be sent across the bridge to your JavaScript app. The result, for lack of better term, is jank.

    The third big problem, according to AirBnb, is that they found themselves having to dip down into the native code more often than they wanted to, which was a problem for their teams comprised mostly of JavaScript developers. (The jury is still out on this issue with Flutter, but I can say that I’ve never once had to try and write native code at my job. Some members of my team have created plugins in Objective-C and Java.)

    The immediate benefits of Flutter

    It’s likely, since you’re reading this article, that you’re interested in Flutter… but you might be skeptical. I admire how thorough you are in vetting technology.

    Your reasons for being skeptical are fair. It’s a new technology. That means breaking changes in the API. It means missing support for important features (such as Google Maps). It seems possible that Google could abandon it altogether one day.

    And, despite the fact that you believe Dart is great language, that doesn’t change the fact that Dart isn’t widely used, and many third-party libraries that you want may not exist.

    I would argue against all those points, though. The API unlikely to change, as the Google uses Flutter internally on major revenue-generating apps, including Google AdWords. Dart has recently moved into version 2, which means it will likely be a while until it changes much. It will likely be years until breaking changes are introduced which, in a computer world, is practically forever.

    Yes, there are indeed missing features, but Flutter gives you the complete control to add your own native plugins. In fact, many of the most important operating system plugins already exist, such as a map plugin, camera, location services, and device storage. The Dart and Flutter ecosystem and community already exists. It’s much smaller than the JavaScript community, of course, but I would argue that it’s concise. I see people every day contributing to existing packages, rather than creating new ones.

    Now, let’s talk about Flutter’s specific benefits.

    No JavaScript bridge

    This is a major bottleneck in development and in your application’s performance. Again, it leads to jank. Scrolling isn’t smooth, it’s not always performant, and it’s hard to debug.

    Flutter compiles to actual native code and is rendered using Skia. The app itself is running in native, so there’s no reason to convert Dart to native. This means that it doesn’t lose any of the performance or productivity when it’s running on a user’s device.

    Compile time

    If you’re coming from native development, one of your major pains is the development cycle. iOS is infamous for its insane compile times. In Flutter, a full compile generally takes less than 30 seconds, and incremental compiles are sub-seconds, thanks to hot-reload. At my day job, we develop features for our mobile client first because Flutter’s development cycle allows us to move so quickly. Only when we’re sure of our implementation do we go write those features in the web client.

    Write once, test once, deploy everywhere

    Not only do you get to write your app one time and deploy to iOS and Android, you also only have to write your tests once. Dart unit testing is quite easy, and Flutter includes a library for testing Widgets.

    Code sharing

    I’m going to be fair here: I suppose this is technically possible in JavaScript as well. But, it’s certainly not possible in native development. With Flutter and Dart, your web and mobile apps can share all the code, except each client’s views. (Of course, only if you’re using Dart for your web apps.) You can quite easily use dependency injection to run an AngularDart app and Flutter app with the same models and controllers.

    And of course, even if you don’t want to share code between your web app and your mobile app, you’re sharing all your code between the iOS and Android apps.

    In practical terms, this means that you are super productive. I mentioned that we develop our mobile features first at my day job. Because we share business logic between web and mobile, once the mobile feature is implemented, we only have to write views that expect that same controller data.

    Productivity and collaboration

    Gone are the days of separate teams for iOS and Android. In fact, whether your use Dart or JavaScript in your web apps, Flutter development is familiar enough that all your teams will be unified. It’s not a stretch by any means to expect a JavaScript web developer to also effectively develop in Flutter and Dart. If you believe me here, then it follows that your new unified team will be three times more productive.

    Code maintenance

    Nothing is more satisfying then fixing a bug once and having it corrected on all your clients. Only in very specific cases is there a bug in a iOS app produced with Flutter that is not also in the Android version (and vice versa). In 100% of these cases, these bugs aren’t bugs, but cosmetic issues because Flutter follows the device OS design systems in it’s built-in widgets. Because these are issues like text sizing or alignment, they are trivial in the context of using engineering time to fix.

    Flutter for JavaScript developers

    Since you’re reading CSS-Tricks, I’d be willing to bet you’re a web developer. If you’ve used any of today’s hottest frameworks (e.g. React, Angular, Vue, etc.), then you’ll be happy to know that picking up Flutter is easy.

    Flutter is completely reactive, so the same mindset and paradigm that you’re used to with React carries over to Flutter. You’re essentially building a ton of small, reusable components (called Widgets in Flutter) just like React. These widgets are complete with lifecycle methods, and they’re written in classes. If you’ve used this syntax in React:

    const MyComponent extends React.Component { //... render(){}
    }

    …then you’ll pick up Flutter with no problem. This is how you do the same in Flutter:

    class MyWidget extends StatelessWidget { //... build(){}
    }

    And, just like React, Flutter favors composition over inheritance. For example, if you want to make a special AddToCartButton in React, you’d build a button with special functions and styles in JSX. That’s exactly how you do it in Flutter (minus the JSX).

    Finally, the layout system in Flutter is similar to CSS rules we’re familiar with, like flexbox and absolute positioning.

    This is also where a big difference in making views in Flutter comes in, though. In Flutter, literally everything is a Widget. There are some obvious, concrete Widgets, like Text, Button, and AppBar. But Animations and Layout declarations are also Widgets. To center text, you wrap a Text Widget in a Center Widget. To add padding, there’s a Padding Widget.

    Imagine breaking down a React app to the smallest possible reusable components you could make. For example, what if you made a higher-order React component that simply took a prop “padding” and all it did was add that amount of padding to whatever was nested within it. That’s how Flutter works, because there is no CSS or markup.

    In this sample picture, here are a few layout widgets that you might use, but you can’t ‘see’ as the user:

    That may seem like a ton of monotonous work, but Flutter comes with many, many Widgets built right in (such as Padding and Center) so you don’t have to waste time doing that yourself.

    These are some of the most common widgets:

    • Layout – Row, Column, Scaffold, Stack
    • Structures – Button, Toast, MenuDrawer
    • Text – TextStyle, Color
    • Animations – FadeInPhoto, transformations
    • Styling – Center, Padding

    Final note

    TL;DR: should you try Flutter?

    If you want to make buttery smooth mobile apps in a familiar style, then yes! The performance and developer experience are both completely held in tact in Flutter. Its animations tick at 60fps, and it has a bundle of built-in Cupertino-style and Material Design-style Widgets. Or, long story short: it’s incredible how quick you can be productive in Flutter, without sacrificing native performance.

    If you want to try Flutter today, here are a couple great places to start:

    • Flutter Docs – Getting Started
    • Flutter for Web Developers (HTML/CSS equivalents)
    • Flutter by Example

    The Flutter docs are truly some of the best I’ve ever seen, and they’ll teach you everything you need to know.

    The post Flutter: Google’s take on cross platform appeared first on CSS-Tricks.