Where Lines Break is Complicated. Here’s all the Related CSS and HTML.

Say you have a really long word within some text inside an element that isn’t wide enough to hold it. A common cause of that is a long URL finding it’s way into copy. What happens? It depends on the CSS. How that CSS is controlling the layout and what the CSS is telling the text to do.

This is what a break-out text situation might be like:

The text hanging out of the box is a visual problem.

One possibility is overflow: hidden; which is a bit of a blunt force weapon that will stop the text (or anything else) from hanging out. Yet, it renders the text a bit inaccessible. In some desktop browsers with a mouse, you might be able to triple-click the line to select the URL and copy it, but you can’t count on everyone knowing that or that it’s possible in all scenarios.

Overflow is the right word here as well, as that’s exactly what is happening. We have overflow: auto; at our disposal as well, which would trigger a horizontal scrollbar. Maybe suitable sometimes, but I imagine we’ll all agree that’s not generally an acceptable solution.

What we want is the dang long URL (or text of any kind) to break to the next line. There are options! Let’s start with a place to attempt figure this stuff out.

Experimental Playground

My idea here is to have a resizeable panel of content combined with a variety of CSS property/values that you can toggle on and off to see the effects on the content.

This isn’t comprehensive or perfectly executed, I’m sure. It’s just some of the properties I’m aware of.

See the Pen Figuring Out Line Wrapping by Chris Coyier (@chriscoyier) on CodePen.

The Sledgehammer: `word-break: break-all;`

Allows words to be broken anywhere. The word-break property does “solve” the issue:

p { word-break: break-all;
}

In an email exchange with fantasi, she explained that this works because the word-break property redefines what a word is. The break-all value essentially treats non-hyphens property does what you might expect…allows for hyphenation in line breaks. Hyphens can sometimes do the trick in URLs and long words, but it’s not guaranteed. A long number would trip it up, for example. Plus, hyphens affect all the text, breaking words more liberally to help text hug that right edge evenly.

p { hyphens: auto;
}

fantasai told me:

“If a ‘word’ straddles the end of the line, we can hyphenate it.”

I guess “word” helps put a finger on the issue there. Some problematically long strings aren’t “words” so it can’t be counted on to solve all overflow issues.

Future Sledgehammer: `line-break: anywhere;`

There is a property called line-break. It’s mostly for punctuation, apparently, but I can’t seem to see it working in any browser. fantasai tells me there will be a new value called anywhere which is:

“like word-break: break-all; except it actually breaks everything like a dumb terminal client”

.

Other HTML Stuff

  • The <br> element will break a line wherever it renders. Unless it’s display: none;!
  • The <wbr> element is a “word break opportunity” meaning a long word that would normally cause an annoying overflow issue could be told that it’s ok to break at a certain point. Useful! It behaves like a zero-width space.

Other CSS Stuff

  • The &shy; character is just like the <wbr> element.
  • You can inject a line break via psuedo elmement like ::before { content: "\A"; } as long as elment isn’t inline (or if it is, it needs white-space: pre;)

The post Where Lines Break is Complicated. Here’s all the Related CSS and HTML. appeared first on CSS-Tricks.

Overriding Default Button Styles

There are a variety of “buttons” in HTML. You’ve got:

<button>Button</button>
<input type="button" value="Button">

Plus, for better or worse, people like having links that are styled to match the look of other true buttons on the site

<a href="#0" class="button">Button</a>

One challenge is getting all those elements to look and layout exactly the same. We’ll cover that a few ways.

Another challenge is getting people to use them correctly

This is a bit surprising to me — but I hear it often enough to worry about it — is that more and more developers are using <div>s for buttons. As in, they just reach for whatever generic, styling-free HTML is handy and build it up as needed. Andy Bell explains why a real button is better:

So, <button> elements are a pain in the butt to style right? That doesn’t mean you should attach your JavaScript events to a <div> or an <a href="#"> though. You see, when you use a <button>, you get keyboard events for free. You’re also helping screen reader users out because it’ll announce the element correctly.

And here’s Andy again helping you out with a chunk of CSS that’ll get you a cleanly styled button:

See the Pen Button Pal — some basic button styles by Andy Bell (@hankchizljaw) on CodePen.

It’s that styling that just might be the mental roadblock

It’s a bit understandable. Buttons are weird! They have a good amount of default styling (that come from the “User Agent Stylesheet”) that varies from browser to browser and means you have work to do to get them exactly how you want.

See all the weirdness there?

  • Without any styling, the button is kinda little and has that native border/border-radius/box-shadow thing going on.
  • Just by setting the font-size, we lose all those defaults, but it’s got a new default look, one with a border and square corners, a gradient background, and no box-shadow. This is essentially -webkit-appearance: button;.
  • Buttons have their own font-family, so don’t inherit from the cascade unless you tell it to.

Here’s Chrome’s user agent stylesheet for buttons:

Firefox behaves a bit differently. See in the video above how setting border: 0; removed the border in Chrome, but also the background? Not the case in Firefox:

I only point this out to say, I get it, buttons are truly weird things in browsers. Factor in a dozen other browsers, mobile, and the idea that we want to style all those different elements to look exactly the same (see the opening of the article), and I have a modicum of empathy for people wanting to avoid this.

Never hurts to consult Normalize

Normalize does a good amount:

/** * 1. Change the font styles in all browsers. * 2. Remove the margin in Firefox and Safari. */ button,
input,
optgroup,
select,
textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: 1.15; /* 1 */ margin: 0; /* 2 */
} /** * Show the overflow in IE. * 1. Show the overflow in Edge. */ button,
input { /* 1 */ overflow: visible;
} /** * Remove the inheritance of text transform in Edge, Firefox, and IE. * 1. Remove the inheritance of text transform in Firefox. */ button,
select { /* 1 */ text-transform: none;
} /** * Correct the inability to style clickable types in iOS and Safari. */ button,
[type="button"],
[type="reset"],
[type="submit"] { -webkit-appearance: button;
}

I was a tiny bit surprised to see WTF, Forms? not cover buttons, only because of how much weirdness there is. But the form elements that project whips into shape are even more notoriously difficult!

A Style-Testing Kinda Thingy

I feel like the answer to this is basically a big ol’ block of CSS. That’s what Andy provided, and you could very likely come to one on your own by just being a little heavier handed than the usual of setting style rules with your buttons.

Still, I felt compelled to make a little tester machine thingy so you can toggle styles on and off and see how they all go together in whatever browser you happen to be in:

See the Pen Consistent button styles by Chris Coyier (@chriscoyier) on CodePen.

A11y

The biggest point here is to use the correct native elements, as you get a bunch of functionality and accessibility for free. But you might as well get the styling right, too!

While we’re talking buttons, I’m gonna use the same quote I used in our When To Use The Button Element post from MDN:

Warning: Be careful when marking up links with the button role. Buttons are expected to be triggered using the Space key, while links are expected to be triggered through the Enter key. In other words, when links are used to behave like buttons, adding role="button" alone is not sufficient. It will also be necessary to add a key event handler that listens for the Space key in order to be consistent with native buttons.

You don’t need role="button" on <button> because they are already buttons, but if you’re going to make any other element button-like, you have more work to do to mimic the functionality.

Plus, don’t forget about :hover and :focus styles! Once you’ve wrangled in the styles for the default state, this shouldn’t be so hard, but you definitely need them!

button:hover,
button:focus { background: #0053ba;
} button:focus { outline: 1px solid #fff; outline-offset: -4px;
} button:active { transform: scale(0.99);
}

The post Overriding Default Button Styles appeared first on CSS-Tricks.

Decorating lines of text with box-decoration-break

An institution’s motto, an artist’s intro, a company’s tagline, a community’s principle, a service’s greeting… all of them have one thing in common: they’re one brief paragraph displayed on a website’s home page — or at least the about page!

It’s rare that just one word or one line of text welcomes you to a website. So, let’s look at some interesting ways we could style the lines of a paragraph.

To see how things currently are, let’s try giving borders to all the lines of some text in an inline span and see how it looks:

<p><span>Hummingbirds are birds from...</span></p>
span { border: 2px solid;
}

See the Pen Broken inline box. by Preethi (@rpsthecoder) on CodePen.

The edges appear broken, which they technically are, as the inline box has been fragmented into multiple lines. But we can fix those broken edges with box-decoration-break!

The box-decoration-break property in CSS can decorate the edges of fragments of a broken inline box (as well as of a page, column, and region boxes).

Its value, clone, does that with the same design that appears in the box’s unbroken edges, and its default value, slice, does not copy the decorations at the edges, keeping the break very visible like you saw in the demo above.

Let’s try it:

span { border: 2px solid; box-decoration-break: clone;
}

See the Pen Broken inline box w/ box-decoration-break. by Preethi (@rpsthecoder) on CodePen.

The property affects not only the border but also the shadow, spacing, and background of the broken edges.

Let’s play with the background first. While writing the post on knockout text, I was working with the background-clip property and wanted to see if the design held up for multiple lines of text. It didn’t.

The background gradient I applied was not replicated in every line, and after clipping it, only the first one was left with a background. That is, unless box-decoration-break: clone is added:

<p><span>Singapore:<br>Lion City</span></p>
span { background-image: linear-gradient(135deg, yellow, violet); background-clip: text; color: transparent; padding: .5em; box-decoration-break: clone;
}

See the Pen Gradient multi-line text w/box-decoration-break. by Preethi (@rpsthecoder) on CodePen.

The background-clip property with the text value clips a background to the shape of its foreground text. Since we used box-decoration-break, the gradient background is shown and clipped uniformly across all the lines of the text.

Going back to the border, let’s see how its shape and shadow can be copied across the broken edges, along with padding:

<img src="tree.png">
<p><span>Supertrees are tree-like structures...</span></p>
<img src="tree.png">
<p><span>Supertrees are tree-like structures...</span></p>
span { background: rgb(230,157,231); border-radius: 50% 0%; box-shadow: 0 0 6px rgb(41,185,82), 0 0 3px beige inset; padding: .5em 1.3em; box-decoration-break: clone;
} p:nth-of-type(2) span { background-clip: content-box;
}

See the Pen Inline border shape & shadow w/box-decoration-break. by Preethi (@rpsthecoder) on CodePen.

In the second paragraph of the demo, the background is cropped until the content box (background-clip: content-box). As you can see, the crop happens in the broken edges as well, because of box-decoration-break: clone.

Another way we can style borders is with images. You might see a gradient border around the lines of text below, covering the broken edges, if the browser you’re now using supports border-image and the application of box-decoration-break over its result.

<p><span>The Malaysia–Singapore Second Link...</span></p>
span { border: 2px solid; border-image: linear-gradient(45deg, #eeb075, #2d4944) 1; background: #eef6f3; padding: .5em 1.3em; box-decoration-break: clone;
}

See the Pen Inline border image w/ box-decoration-break. by Preethi (@rpsthecoder) on CodePen.

An additional behavior we can tap into for decorating individual lines is of outline’s. In supported browsers, box-decoration-break can add an outline to every line of the text, including the broken edges, which is useful for creating bicolored dashed borders.

<p><span>Cloud Forest replicates...</span></p>
span { outline: 2px dashed rgb(216,255,248); box-shadow: 0 0 0 2px rgb(39,144,198); background: #fffede; padding: .5em 1.3em; animation: 1s animateBorder ease infinite; box-decoration-break: clone;
} @keyframes animateBorder{ to{ outline-color: rgb(39,144,198); box-shadow: 0 0 0 2px rgb(216,255,248); }
}

See the Pen Inline outline w/ box-decoration-break. by Preethi (@rpsthecoder) on CodePen.

As observed in the demo, box-decoration-break withstands animation.

Besides borders and backgrounds, box-decoration-break can also manage shapes applied over elements. There is not much use for it in inline boxes, and is maybe better used in a column or page box, although the application is not yet widely supported in browsers.

But to show an example of what that does, let’s try applying the clip-path property to the span.

The property clip-path itself is only fully supported by Firefox, so only in it you might see an expected outcome. But following are two images: the results of applying a circular clip path over the span, without and with box-decoration-break.

span { clip-path: circle(50% at 202.1165px 69.5px); ...
}
A screenshot of a span of text being highlighted in DevTools showing that text is split up in three lines and with uneven start and end points.
Circular clip-path on a span
span { clip-path: circle(50% at 202.1165px 69.5px); box-decoration-break: clone; ...
}
A screenshot of a span of text being highlighted in DevTools showing that text is split up in three lines and with even start points but uneven end points.
Circular clip-path on a span with box-decoration-break: clone

You’ll notice in the first image that the 50% radius value is derived from the width of the inline box (the longest line) where box-decoration-break is not used.

The second image shows how box-decoration-break: clone redefines the computed value for 50% by basing them on the widths of the individual lines while keeping the center same as before.

And here’s how the inset function of clip-path (an inset rectangle) applied over the span clips it without and with box-decoration-break:

span { clip-path: inset(0); ...
}
A screenshot of a span of text being highlighted in DevTools showing that text is all on one line but the span continues for three lines with even start points but uneven end points.
Inset clip-path on a span
span { clip-path: inset(0); box-decoration-break: clone; ...
}
Inset clip-path on a span with box-decoration-break: clone

Without box-decoration-break, only a portion of the first line that matches the length of the shortest is visible, and with box-decoration-break: clone, the first line is fully visible while the rest of the box is clipped.

So, maybe if you ever want to show only the first line and hide the rest, this can come in handy. But, as I mentioned before, this application is more suitable for other types of boxes than ones that are inline. Either way, I wanted to show you how it works.

Browser Support

As we’ve seen here, box-decoraton-break can be super useful and opens up a lot of possibilities, like creating neat text effects. The property enjoys a lot support with the -webkit prefix, but is still in Working Draft at the time of this writing and lacks any support in Internet Explorer and Edge. Here’s where you can vote for Edge support.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
69* 11 32 No No TP*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
11.3* 11 all 62* 66* 57

Wrapping Up

The box-decoration-break: clone copies any border, spatial, and background designs applied on a fragmented inline box’s unbroken edges to its broken ones. This creates an even design across all the lines of the text, decorating them uniformly and can be super useful for all those blurbs of text that we commonly use on websites.

The post Decorating lines of text with box-decoration-break appeared first on CSS-Tricks.

Microsites for Case Studies

A lot of y’all have personal sites. Personal sites with portfolios. Or you work for or own an agency where showing off the work you do is arguably even more important. Often the portfolio area of a site is the most fretted and hard to pull off. Do you link to the live projects? Screenshots? How many? How much do you say? How much of the process do people care about?

I’m afraid I don’t have all the answers for you. I don’t really do much freelance, work for an agency, or have a need to present work I’ve done in this way.

But! I tweeted this the other day:

I was out to lunch with Rob from Sparkbox recently. A few years back, we worked together on a redesign of CodePen, and a byproduct of that was a microsite about that process.

I remember working on that microsite. It wasn’t a burden, it was kinda fun. We built it as we went, when all that stuff was fresh in our minds. Now that site is kind of a monument to that project. Nobody needs to touch it. It doesn’t load some global stylesheet from a main website. It’s a sub-domained microsite. It’ll be useful as long as it’s useful. When it’s not anymore, stop linking to it.

I’ve also watched loads of people struggle with what to put in that portfolio and how to deal with case studies. I’ve watched it be a burden to people redesigning their site or building one for the first time. I’ve also looked at a lot of personal sites lately, and the default is certainly to work the portfolio into the site itself.

Maybe for some of you, making your case studies into these microsites will be a useful way to go!

The post Microsites for Case Studies appeared first on CSS-Tricks.

CSS Environment Variables

We were all introduced to the env() function in CSS when all that drama about “The Notch” and the iPhone X was going down. The way that Apple landed on helping us move content away from those “unsafe” areas was to provide us essentially hard-coded variables to use:

padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);

Uh ok! Weird! Now, nine months later, an “Unofficial Proposal Draft” for env() has landed. This is how specs work, as I understand it. Sometimes browser vendors push forward with stuff they need, and then it’s standardized. It’s not always waiting around for standards bodies to invent things and then browser vendors implementing those things.

Are environment variables something to get excited about? Heck yeah! In a sense, they are like a more-limited version of CSS Custom Properties, but that means they can be potentially used for more things.

Eric also points out some very awesome early thinking:

ISSUE 4 – Define the full set of places env() can be used.

  • Should be able to replace any subset of MQ syntax, for example.
  • Should be able to replace selectors, maybe?
  • Should it work on a rule level, so you can insert arbitrary stuff into a rule, like reusing a block of declarations?

Probably still changeable-with-JavaScript as well. I would think the main reason CSS Custom Properties don’t work with media queries and selectors and such is because they do work with the cascade, which opens up some very strange infinite loop logic where it makes sense CSS doesn’t want to tread.

If you’re into the PostCSS thing, there is a plugin! But I’d warn… the same issues that befall preprocessing CSS Custom Properties applies here (except the first one in that article).

The post CSS Environment Variables appeared first on CSS-Tricks.

Inspecting Animations in DevTools

I stumbled upon the Animation panel in Chrome’s DevTools the other day and almost jumped out of my seat with pure joy. Not only was I completely unaware that such a thing exists, but it was better than what I could’ve hoped: it lets you control and manipulate CSS animations and visualize how everything works under the hood.

To access the panel, head to More Tools → Animations in the top right-hand menu when DevTools is open:

Many of the tutorials I found about this were pretty complicated, so let’s take a step back and look at a smaller example to begin with: here’s a demo where the background-color of the html element will transition from black to orange on hover:

html { cursor: pointer; background-color: #333; transition: background-color 4s ease;
} html:hover { background-color: #e38810;
}

Let’s imagine that we want to nudge that transition time down from 4s. It can get pretty annoying just bumping that number up and down in the element inspector. I typically would’ve opened up DevTools, found the element in the DOM and then ever-so-slowly manipulate it by typing in a value or using the keyboard directional keys. Instead, we can fire up that demo, open DevTools, and switch to the Animation tab which ought to look something like this:

By default, Chrome will be “listening” for animations to take place. Once they do, they’ll be added to the list. See how those animation blocks are displayed sort of like an audio wave? That’s one frame, or act, of an animation and you can see on the timeline above it each frame that follows it. On an animation itself, the inspector will even show us which property is being changed, like background-color or transform. How neat is that?

We can then modify that animation by grabbing that bar and moving it about:

…and it updates the animation right away — no more clicking and editing an animation the old way! Also, you might’ve noticed that hovering over an animation frame will highlight the element that’s being animated in blue. This is handy if you’re editing a complex animation and forget what that crazy weird pseudo element does. If you have multiple animations on a page, then you can see them all listed in that section just like in this demo:

What we’re doing here is animating both the .square and the .circle when hovering on the html element, so there’s effectively two separate divs being animated in the same time frame — that’s why you can see them in the same section just like that.

I can see that inspecting animations in this way could be super useful for tiny icon design, too. Take this pen of Hamburger menu animations by Jesse Couch where you might want to slow everything down to get things just right. Well, with the animation inspector tool you can do exactly that:

Those buttons in the top left-hand corner will control the playback speed of the animation. So hitting 10% will slow things to a crawl — giving you enough time to really futz with things until they’re perfect.

I’ve focused on Chrome here but it’s not the only browser with an animation inspector — Firefox’s tool is in every way just as useful. The only immediate difference I found was that Chrome will listen for any animations on a page and will display them once their captured. But, with Firefox, you have to inspect the element and only then will it show you the animations attached to that element. So, if you’re doing super complex animations, then Chrome’s tool might be a smidge more helpful.

Animation Inspector Documentation

  • Walkthrough on Google Developers
  • Animation inspector in Firefox – MDN

The post Inspecting Animations in DevTools appeared first on CSS-Tricks.

Finger-friendly numerical inputs with `inputmode`

Forms are often a nightmare on mobile. We can make the process as pain-free as possible by reacting to context. Input fields that expect numerical values should have a numerical most) larger screens, number inputs come with an incrementer/decrementer button. It’s a useful piece of UI we get for free by default. It does, however, make this kind of input totally inappropriate for a credit card number, for example.

A default number input that displays the up and down arrows that allow users to increase and decrease numbers in the field.
The default UI for number inputs looks something like this in all desktop browsers

The spec itself makes this clear.

The type=number state is not appropriate for input that happens to only consist of numbers but isn’t strictly speaking a number. For example, it would be inappropriate for credit card numbers or US postal codes. A simple way of determining whether to use type=number is to consider whether it would make sense for the input control to have a spinbox interface (e.g., with “up” and “down” arrows). Getting a credit card number wrong by 1 in the last digit isn’t a minor mistake, it’s as wrong as getting every digit incorrect. So it would not make sense for the user to select a credit card number using “up” and “down” buttons. When a spinbox interface is not appropriate, type=text is probably the right choice (possibly with a pattern attribute).

It’s easy to hide the up and down buttons with CSS:

input[type="number"] { -moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

It’s important to note that this isn’t the only difference between a number and text input. You should definitely follow the spec on this point! Some older browsers will strip out leading zeros for number inputs which would be a big problem for US ZIP codes. The often-useful maxlength attribute is ignored on number inputs.

Why would anybody dislike such a useful input?

The answer comes down to validation and using the input for the wrong thing. The number input performs input sanitization by default. If a user enters anything that isn’t a valid number, the value will be equal to an empty string — regardless of what the user can see on the screen.

This input sanitization can trip developers up, and there’s no way to turn it off. If you want to allow input that isn’t a valid number, don’t use type="number".

A screenshot showing a number input that is filled with numbers and includes dashes between some of the numbers.
Number input in Chrome. This might be valid input for your use case, but it’s illegitimate in the eyes of the number input.
var numberinput = document.querySelector('input[type="number"]')
numberinput.value // will be ""

This might not be what you would intuitively expect. However, if you follow the spec and only use the number input for what its designed for — actual numbers — this behavior is unproblematic.

Number Input Alternatives

iOS Solution: Use the `pattern` Attribute on a Text Input

On iOS devices, using the pattern attribute with a value of [0-9]* will bring up the numeric keypad. This only works with this exact pattern — you can’t allow any extra characters.

<label for="creditcard">credit card number:</label> <input pattern="[0-9]*" type="text" name="creditcard">
The iOS number keyboard that displays only numbers one through ten and no other special characters.
iOS with pattern attribute

Bear in mind that an iPhone won’t let the user switch keyboard type when this keyboard is displayed. Make sure these are the only keys they need to fill in the input correctly.

If you want to bring up a keypad of large numeric keys on iOS, you need to use the pattern attribute even on number inputs. Otherwise, you’ll get small and finger-friendly buttons:

A screenshot of the iOS keyboard displaying both numbers and letters.
iOS keypad for <input type="number">

A Better Solution: `inputmode`

inputmode has been a WHATWG spec for a couple of years, and has finally been implemented by Chrome as of version 66:

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
66 No 20 No No No

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
No No No No No No

For the widest support possible, it can be combined with the pattern attribute for iOS:

<label for="creditcard">credit card number:</label> <input inputmode="numeric" pattern="[0-9]*" type="text" name="creditcard">

This gives developers full control of the mobile UI without any extra baggage. It makes the UI finger-friendly while being more versatile than the pattern attribute as we can allow any characters we like. It controls one thing — and one thing only. inputmode is a great solution for those cases when it’s inappropriate to use type="number".

Some people would go further and ditch type="number" altogether once inputmode has better support. I’m not convinced that’s wise, but type="number" can be problematic.

if (numberInput.validity.valueMissing) {
errorMessage.textContent = "field must not be empty"
}
A screenshot of a number input filled with numbers and special characters with an error message below it that informs the user the field is empty.
Contrary to the human eye, the field is empty…

If you want to explicitly warn of empty number inputs, you’ll need to use:

if (numberInput.validity.valueMissing && !numberInput.validity.badInput) {
errorMessage.textContent = "field must not be empty"
}

According to Google, users abandon purchases twice as often on mobile as compared to desktop. Sales on phones account for only one third of all completed online purchases. Clearly people don’t tolerate fumbling through badly designed forms and jabbing at tiny inputs. Data entry needs to be effortless. While browser support is currently low, we’re only really waiting on mobile browsers. Desktop support is largely irrelevant. The input elements introduced by HTML5 are great, but they miss some edge cases. This can fill in some gaps.

The post Finger-friendly numerical inputs with `inputmode` appeared first on CSS-Tricks.

Radial Gradient Recipes

Radial gradients are pretty dang cool. It’s amazing we can paint the background of an element with them so easily. Easily is a relative term though. It’s certainly easier than needing to create a graphic in third-party software to use as the background, and the syntax is highly learnable. But it’s also not that easy to remember if you don’t use it often, and it’s more complicated than linear-gradient().

I figured I’d put together a page of reference examples, so if you know what you need but forget the syntax, it’s easy to find that starter code example here.

Centered Bursts

The simplest possible syntax places the first color in the center of the element and the second color on the outside and that’s that:

See the Pen Radial Gradient – Centered by Chris Coyier (@chriscoyier) on CodePen.

That will stretch the gradient into an ellipse on a non-square element though. If you don’t like that, you can force the shape into a circle, like the second example here demonstrates:

See the Pen Radial Gradient – Circle vs. Ellipse by Chris Coyier (@chriscoyier) on CodePen.

You can also control the size by literally saying how large the circle/ellipse should be (the final color will still stretch to cover the element) by:

  • Using a keyword closest-side, farthest-side, closest-corner, farthest-corner
  • Explicitly saying like radial-gradient(circle 100px, ...)
  • Using color stops like radial-gradient(#56ab2f, #a8e063 150px)

See the Pen Radial Gradient – Sizing by Chris Coyier (@chriscoyier) on CodePen.

Here’s some of that stuff in use:

See the Pen Usage of Radial Gradients by Chris Coyier (@chriscoyier) on CodePen.

See the Pen Lit text by Chris Coyier (@chriscoyier) on CodePen.

Positioned

Besides controlling the size and shape of the gradient, the other big trick to know with radial gradients is that you can position the center of them.

This is one of the shortcomings, I find, with gradient generators. They help you pick colors and color stops and stuff, but they usually punt on the positioning stuff.

This is a beautiful gradient tool, but doesn’t help with positioning or sizing. Some of them do help a little with positioning (see “Expert” settings), but don’t expose all the possibilities.

The center of a radial gradient doesn’t have to be in the center! For example, you can position the center in the top left like this:

.element { background: radial-gradient( at top left, var(--light), var(--dark) /* using variables just for fun! */ )
}

Here’s all the four corners:

See the Pen Positioned Radial Gradients by Chris Coyier (@chriscoyier) on CodePen.

You can also be very specifically positioned. Here’s an example of a gradient positioned exactly 195px from the left along the bottom of the element. It also has a specific size, but otherwise does the default ellipse shape:

.element { background: radial-gradient( 150px 40px at 195px bottom, #666, #222 );
}

See the Pen Specifically positioned gradient by Chris Coyier (@chriscoyier) on CodePen.

Another little thing to know is that you can use transparent in the gradients to expose the color behind if that’s needed, or partially transparent colors like rgba(255, 255, 255, 0.5) to do the same at a colorized color stop.

Also, radial gradients can be used with multiple backgrounds, applying multiple of them to a single element, even overlapping!

.element { background: radial-gradient( circle at top left, rgba(255, 255, 255, 0.5), transparent 100px ), radial-gradient( circle at top right, rgba(255, 255, 255, 0.5), transparent 100px ), radial-gradient( at bottom left, rgba(255, 0, 255, 0.5), transparent 400px ), radial-gradient( at bottom right, rgba(255, 100, 100, 0.5), transparent 400px );
}

See the Pen Multiple Gradients by Chris Coyier (@chriscoyier) on CodePen.

To highlight the idea that the center of the gradient can be anywhere, here’s a gradient that follows the mouse:

See the Pen Radial Gradient Move With Mouse by Leo Sammarco (@lsammarco) on CodePen.

Resources

People tend to think about browser support, and rightfully so, but don’t think too hard about it in this case. We’re at pretty much across the board support even without any prefixes.

  • There is also repeating-linear-gradient() and here Ana Tudor gets into some detail and use cases.
  • Need some colors that go nicely togehter in a gradient? uiGradients is nice.
  • MDN on radial-gradient
  • See our complete guide to all gradients here!

OK bye!

See the Pen CSS Sunset Sunrise by Marty Saetre (@msaetre) on CodePen.

The post Radial Gradient Recipes appeared first on CSS-Tricks.

Understanding React `setState`

React components can, and often do, have state. State can be anything, but think of things like whether a user is logged in or not and displaying the correct username based on which account is active. Or an array of blog posts. Or if a modal is open or not and which tab within it is active.

React components with state render reconciliation. The reconciliation process is the way React updates the DOM, by making changes to the component based on the change in state. When the request to setState() is triggered, React creates a new tree containing the reactive elements in the component (along with the updated state). This tree is used to figure out how the Search component’s setState Pen by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Let’s register the component and define the markup for the Understanding React `setState` appeared first on CSS-Tricks.

Server-Side Visualization With Nightmare

This is an extract from chapter 11 of Ashley Davis’s book Data Wrangling with JavaScript now available on the Manning Early Access Program. I absolutely love this idea as there is so much data visualization stuff on the web that relies on fully functioning client side JavaScript and potentially more API calls. It’s not nearly as robust, accessible, or syndicatable as it could be. If you bring that data visualization back to the server, you can bring progressive enhancement to the party. All example code and data can be found on GitHub.

When doing exploratory coding or data analysis in Node.js it is very useful to be able to render a visualization from our data. If we were working in browser-based JavaScript we could choose any one of the many charting, graphics, and visualization libraries. Unfortunately, under Node.js, we don’t have any viable options, so how otherwise can we achieve this?

We could try something like faking the DOM under Node.js, but I found a better way. We can make our browser-based visualization libraries work for us under Node.js using a headless browser. This is a browser that has no user interface. You can think of it as a browser that is invisible.

I use Nightmare under Node.js to capture visualizations to PNG and PDF files and it works really well!

The headless browser

When we think of a web-browser we usually think of the graphical software that we interact with on a day to day basis when browsing the web. Normally we interact with such a browser directly, viewing it with our eyes and controlling it with our mouse and keyboard as shown in Figure 1.

Figure 1: The normal state of affairs: our visualization renders in a browser and the user interacts directly with the browser

A headless browser on the other hand is a web-browser that has no graphical user interface and no direct means for us to control it. You might ask what is the use of a browser that we can’t directly see or interact with.

Well, as developers we would typically use a headless browser for automating and testing web sites. Let’s say that you have created a web page and you want to run a suite of automated tests against it to prove that it works as expected. The test suite is automated, which means it is controlled from code and this means that we need to drive the browser from code.

We use a headless browser for automated testing because we don’t need to directly see or interact with the web page that is being tested. Viewing such an automated test in progress is unnecessary, all we need to know is if the test passed or failed — and if it failed we would like to know why. Indeed, having a GUI for the browser under test would actually be a hindrance for a continuous-integration or continuous-deployment server, where many such tests can run in parallel.

So headless browsers are often used for automated testing of our web pages, but they are also incredibly useful for capturing browser-based visualizations and outputting them to PNG images or PDF files. To make this work we need a web server and a visualization, we must then write code to instance a headless browser and point it at our web server. Our code then instructs the headless browser to take a screenshot of the web page and save it to our file system as a PNG or PDF file.

Figure 2: We can use a headless browser under Node.js to capture our visualization to a static image file

Nightmare is my headless browser of choice. It is a Node.js library (installed via npm) that is built on Electron. Electron is a framework normally used for building cross-platform desktop apps that are based on web-technologies.

Why Nightmare?

It’s called Nightmare, but it’s definitely not a Nightmare to use. In fact, it’s the simplest and most convenient headless browser that I’ve used. It automatically includes Electron, so to get started we simply install Nightmare into our Node.js project as follows:

npm install --save nightmare

That’s all we need to install Nightmare and we can start using it immediately from JavaScript!

Nightmare comes with almost everything we need: A scripting library with an embedded headless browser. It also includes the communication mechanism to control the headless browser from Node.js. For the most part it’s seamless and well-integrated to Node.js.

Electron is built on Node.js and Chromium and maintained by GitHub and is the basis for a number of popular desktop applications.

Here are the reasons that I choose to use Nightmare over any other headless browser:

  • Electron is very stable.
  • Electron has good performance.
  • The API is simple and easy to learn.
  • There is no complicated configuration (just start using it).
  • It is very well integrated with Node.js.

Nightmare and Electron

When you install Nightmare via npm it automatically comes with an embedded version of Electron. So, we can say that Nightmare is not just a library for controlling a headless browser, it effectively is the headless browser. This is another reason I like Nightmare. With some of the other headless browsers, the control library is separate, or it’s worse than that and they don’t have a Node.js control library at all. In the worst case, you have to roll your own communication mechanism to control the headless browser.

Nightmare creates an instance of the Electron process using the Node.js child_process module. It then uses inter-process communication and a custom protocol to control the Electron instance. The relationship is shown in Figure 3.

Figure 3: Nightmare allows us to control Electron running as a headless browser

Our process: Capturing visualizations with Nightmare

So what is the process of capturing a visualization to an image file? This is what we are aiming at:

  1. Acquire data.
  2. Start a local web server to host our visualization
  3. Inject our data into the web server
  4. Instance a headless browser and point it at our local web server
  5. Wait for the visualization to be displayed
  6. Capture a screenshot of the visualization to an image file
  7. Shutdown the headless browser
  8. Shutdown the local web server

Prepare a visualization to render

The first thing we need is to have a visualization. Figure 4 shows the chart we’ll work with. This a chart of New York City yearly average temperature for the past 200 years.

Figure 4: Average yearly temperature in New York City for the past 200 years

To run this code you need Node.js installed. For this first example we’ll also use live-server (any web server will do) to test the visualization (because we haven’t created our Node.js web server yet), install live server as follows:

npm install -g live-server

Then you can clone the example code repo for this blog post:

git clone https://github.com/Data-Wrangling-with-JavaScript/nodejs-visualization-example

Now go into the repo, install dependencies and run the example using live-server

cd nodejs-visualization-example/basic-visualization
bower install
live-server

When you run live-server your browser should automatically open and you should see the chart from Figure 4.

It’s a good idea to check that your visualization works directly in a browser before you try and capture it in a headless browser; there could easily be something wrong with it and problems are much easier to troubleshoot in a real browser than in the headless browser. live-server has live reload built-in, so now you have a nice little setup here when you can edit and improve the chart interactively before you try to capture it under Node.js.

This simple line chart was constructed with C3. Please take a look over the example code and maybe look at some of the examples in the C3 gallery to learn more about C3.

Starting the web server

To host our visualization, we need a web server. It’s not quite enough that we have a web server, we also need to be able to dynamically start and stop it. Listing 1 shows the code for our web server.

Listing 1 – Code for a simple web server that can be started and stopped

const express = require('express');
const path = require('path'); module.exports = { start: () => { // Export a start function so we can start the web server on demand. return new Promise((resolve, reject) => { const app = express(); const staticFilesPath = path.join(__dirname, "public"); // Make our 'public' sub-directory accessible via HTTP. const staticFilesMiddleWare = express.static(staticFilesPath); app.use('/', staticFilesMiddleWare); const server = app.listen(3000, err => { // Start the web server! if (err) { reject(err); // Error occurred while starting web server. } else { resolve(server); // Web server started ok. } }); }); }
}

The code module in listing 1 exports a start function that we can call to kickstart our web server. This technique, being able to start and stop our web server, is also very useful for doing automated integration testing on a web site. Imagine that you want to start your web server, run some tests against it and then stop it at the end.

So now we have our browser-based visualization and we have a web server that can be started and stopped on demand. These are the raw ingredients we need for capturing server-side visualizations. Let’s mix it up with Nightmare!

Rendering the web page to an image

Now let’s flesh out the code to capture a screenshot of the visualization with Nightmare. Listing 2 shows the code that instances Nightmare, points it at our web server and then takes the screenshot.

Listing 2 – Capturing our chart to an image file using Nightmare

const webServer = require('./web-server.js');
const Nightmare = require('nightmare'); webServer.start() // Start the web server.
.then(server => { const outputImagePath = "./output/nyc-temperatures.png"; const nightmare = new Nightmare(); // Create the Nightmare instance. return nightmare.goto("http://localhost:3000") // Point the browser at the web server we just started. .wait("svg") // Wait until the chart appears on screen. .screenshot(outputImagePath) // Capture a screenshot to an image file. .end() // End the Nightmare session. Any queued operations are completed and the headless browser is terminated. .then(() => server.close()); // Stop the web server when we are done.
})
.then(() => { console.log("All done :)");
})
.catch(err => { console.error("Something went wrong :("); console.error(err);
});

Note the use of the goto function, this is what actually directs the browser to load our visualization.

Web pages usually take some time to load. That’s probably not going to be very long, especially as we are running a local web server, but still we face the danger of taking a screenshot of the headless browser before or during its initial paint. That’s why we must call the wait function to wait until the chart’s <svg> element appears in the browser’s DOM before we call the screenshot function.

Eventually, the end function is called. Up until now we have effectively built a list of commands to send to the headless browser. The end function actually sends the commands to the browser, which takes the screenshot and outputs the file nyc-temperatures.png. After the image file has been captured we finish up by shutting down the web server.

You can find the completed code under the capture-visualization sub-directory in the repo. Go into the sub-directory and install dependencies:

cd nodejs-visualization-example/capture-visualization
cd public bower install
cd ..
npm install
live-server

Now you can try the code for yourself:

node index.js

This has been an extract from chapter 11 of Data Wrangling with JavaScript now available on the Manning Early Access Program. Please use this discount code fccdavis3 for a 37% discount. Please check The Data Wrangler for new updates on the book.

The post Server-Side Visualization With Nightmare appeared first on CSS-Tricks.