Making a Pure CSS Play/Pause Button

Globally, the media control icons are some of the most universally understood visual language in any kind of interface. A designer can simply assume that every user not only knows ▶️ = play, but that users will seek out the icon in order to watch any video or animation.
Reportedly introduced in the 1960s by Swedish engineer Philip Olsson the play arrow was first designed to indicate the direction where the tape would go when reading on reel-to-reel tape players. Since then, we switched from cassettes to CDs, from the iPod to Spotify, but the media controls icons remain the same.

The play ▶️ icon is standard symbol (with its own unicode) of starting an audio/video media along with the rest of the symbols like stop, pause, fast-forward, rewind, and others.
There are unicode and emoji options for play button icons, but if you wanted something custom, you might reach for an icon font or custom asset. But what if you want to shift between the icons? Can that change be smooth? One solution could be to use SVG. But what if it could be done in 10 lines of CSS? How neat is that‽
In this article, we'll build both a play button and a pause button with CSS and then explore how we can use CSS transitions to animate between them.
Play Button
Step one
We want to achieve a triangle pointing right. Let's start by making a box with a thick border. Currently, boxes are the preferred base method to make triangles. We'll start with a thick border and bright colors to help us see our changes.
<div class='button play'></div>
.button.play {
width: 74px;
height: 74px;
border-style: solid;
border-width: 37px;
border-color: #202020;
}

Step two
Rendering a solid color border yields the above result. Hidden behind the color of the border is a neat little trick. How is the border being rendered exactly? Let's change the border colors, one for each side, will help us see how the border is rendered.
<div class='button play'></div>
.button.play{
width: 74px;
height: 74px;
border-style: solid;
border-width: 37px 37px 37px 37px;
border-color: red blue green yellow;
}

Step three
At the intersection of each border, you will notice that a 45-degree angle forms. This is an interesting way that borders are rendered by a browser and, hence, open the possibility of different shapes, like triangles. As we'll see below, if we make the border-left wide enough, it looks as if we might achieve a triangle!
<div class='button play'></div>
.button.play {
width: 74px;
height: 74px;
border-style: solid;
border-width: 37px 0px 37px 74px;
border-color: red blue green yellow;
}

Step four
Well, that didn't work as expected. It is as if the inner box (the actual div) insisted on keeping its width. The reason has to do with the box-sizing property, which defaults to a value of content-box. The value content-box tells the div to place any border on the outside, increasing the width or height.
If we change this value to border-box, the border is added to the inside of the box.
<div class='button play'></div>
.button.play {
box-sizing: border-box;
width: 74px;
height: 74px;
border-style: solid;
border-width: 37px 0px 37px 74px;
border-color: red blue green yellow;
}

Final step
Now we have a proper triangle. Next, we need to get rid of the top and bottom part (red and green). We do this by setting the border-color of those sides to transparent. The widths also gives us control over the shape and size of the triangle.
<div class='button play'></div>
.button.play {
box-sizing: border-box;
width: 74px;
height: 74px;
border-style: solid;
border-color: #202020;
border-width: 37px 0px 37px 74px;
border-color: transparent transparent transparent #202020;
}

Here's an animation to explain that, if that's helpful.
Pause Button
Step one
We'll continue making our pause symbol by starting with another thick-bordered box since the previous one worked so well.
<div class='button pause'></div>
.button.pause {
width: 74px;
height: 74px;
border-style: solid;
border-width: 37px;
border-color: #202020;
}

Step two
This time we'll be using another CSS property to achieve the desired result of two parallel lines. We'll change the border-style to double. The double property in border-style is fairly straightforward, doubles the border by adding a transparent stroke in between. The stroke or empty gap will be 33% of the given border width.
<div class='button pause'></div>
.button.pause{
width: 74px;
height: 74px;
border-style: double;
border-width: 0px 37px 0px 37px;
border-color: #202020;
}

Final step</h4

Now set one side of the border with the border-width property. Using the border-width is what will make the transition work smoothly in the next step.
<div class='button pause'></div>
.button.pause{
width: 74px;
height: 74px;
border-style: double;
border-width: 0px 0px 0px 37px;
border-color: #202020;
}

Animating the Transition
In the two buttons we created above, notice that there are a lot of similarities, but two differences: border-width and border-style. If we use CSS transitions we can shift between the two symbols. There's no transition effect for border-style but border-width works great.
A pause class toggle will now animate between the play and pause state.
Here's the final style in SCSS:
<div class='button'></div>
.button {
box-sizing: border-box;
height: 74px;

border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
will-change: border-width;
cursor: pointer;

// play state
border-style: solid;
border-width: 37px 0 37px 60px;

// paused state
&amp;.pause{
border-style: double;
border-width: 0px 0 0px 60px;
}
}
Demo
See the Pen mBqBqM by Daniel Abdilla (@xihadd) on CodePen.
A Bonus Without JS
In the demo above, I used JavaScript to toggle the classes between play state and pause state. This works perfectly, but what if you don't want to use JavaDScript at all? Let's take it a step further and use an HTML checkbox and skin it with the CSS we just used. We’ll use the checked state of the checkbox to toggle between play and pause:
<div class="play-pause">
<input type="checkbox" value="" id="playPauseCheckbox" name="playPauseCheckbox" />
<label for="playPauseCheckbox"></label>
</div>
.playpause {
label {
display: block;
box-sizing: border-box;

width: 0;
height: 74px;

cursor: pointer;

border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
will-change: border-width;

// paused state
border-style: double;
border-width: 0px 0 0px 60px;
}
input[type=&quot;checkbox&quot;] {
visibility: hidden;

&amp;:checked + label {
// play state
border-style: solid;
border-width: 37px 0 37px 60px;
}
}
}
Demo
See the Pen oGoGMB by Daniel Abdilla (@xihadd) on CodePen.
I would love your thoughts and feedback. Please add them in the comments below.

Making a Pure CSS Play/Pause Button is a post from CSS-Tricks
Source: CssTricks


If It Ain’t Baroque, Don’t Fix It

Illustration by Nate OttoBen and Larry are longtime owners of two different music-related businesses, a payroll service for musicians and an auctioneer of rare classical LPs. They don’t know each other, but they have something in common: They’re both still running their businesses on custom software written in the 1980s by the same developer. This episode features the soothing, nostalgic hum of a dot matrix printer, variations on “Three Blind Mice,” and more!https://medium.com/media/dea2cb92713e898f75eaf5c125312bd3/hrefTranscriptWAILIN: Do you remember your first computer? Ben does. He got his first computer in 1986, when he hired a programmer to write some custom software for his business.BEN: I was frightened beyond reason and little by little, I got the hang of it. Those computers at that time were just old DOS machines.TROY HENIKOFF: It was a Compaq desktop, and the reason it was a Compaq was because the IBM PC ran at 4.77 megaherz, but the Compaq ran at 6 megaherz. So it was original Compaq with a 20 MB hard drive in it and an amber monitor. The amber monitors were the best. They were better than the green ones.WAILIN: That’s Troy Henikoff, the programmer who wrote the software that Ben started using in 1986 — and still uses today. Welcome to The Distance, a podcast about long-running businesses. I’m Wailin Wong. On the last episode of The Distance, you heard about how Troy ran his software consulting business for six years before selling it to a big corporation. On today’s show, you’ll meet two of Troy’s earliest customers who are running their businesses on 30-year-old software.TOM: The Distance is a production of Basecamp. I’m Tom, a programmer at Basecamp. Basecamp is the better way to run your business. It’s an app for communicating with people and organizing projects and work. If you’re feeling overwhelmed by email, chat and meetings, give Basecamp a try. Sign up for a 30-day free trial at basecamp.com/thedistance.BEN: I’m a musician and 95 percent of my tax clients are musicians: Chicago Symphony, Lyric Opera. I’ve worked for local orchestras. They wanted someone who can work on musicians’ tax returns, who knew the types of deductions they would be able to take, and by word of mouth I got another phone call, another phone call, another phone call, and I got all these clients.WAILIN: Ben, who asked that we not use his last name, has a one-man business in the Chicago area doing payroll and taxes for musicians. He estimates he’s been doing this for around 45 years, but he doesn’t remember the exact year he started his business. It’s called Tempo, which stands for The Equitable Musicians Payroll Organization. When Ben got introduced to Troy via a friend in 1986, he was about a decade in and using a typewriter.BEN: People kept asking me, “Why are you doing this? Why don’t you get a payroll program? Why don’t you get a computer?” I didn’t have anything. I just used a typewriter. They told me that Troy graduated from Brown with an engineering degree and he’s going into IT so I gave him a call.WAILIN: At the time, Ben also owned a currency exchange in Chicago and Troy went there to meet him. He was Troy’s first customer.TROY: So I had never been to a currency exchange, and the currency exchange, of course, has bulletproof glass, but you have to be able to get behind the bulletproof glass and they have a thing — I think it’s called a gang door. Apparently, this is to prevent like a gang of people from rushing the back of the, of the currency exchange. There are actually two doors and the space in between the doors is only big enough for one relatively slender human, and the first door has to be closed before the second door is physically able to open. And so he’s trying to explain to me that I’m gonna go into this gang door in order to see him and he’s yelling through the bulletproof glass, “Go over there! Open the first latch!” And then I get in and then the door closes and you’re totally claustrophobic. And then I sat down with him in the back of this currency exchange and he’s helping customers and then he’s interrupted and he’s trying to explain to me about union reports and W2s and 1099s and I knew nothing about any of it. But he just gave me a bunch of sample reports and said, “Look, it has to look like this.” And I asked a lot of questions and if you ask enough questions, you start to understand. I laid out a system for him, gave him a quote, and went back and programmed it.BEN: He set up a program on DOS, MS-DOS, before you were a gleam in your mom’s eye. That’s when I started to use it and it was marvelous.WAILIN: Not long after doing the job for Ben, Troy was introduced via a string of connections to another customer with a business called Polyphony.LARRY JONES: I’m Larry Jones and I sell out-of-print classical recordings. I’ve been doing it since 1978, so in my 40th year now. I think anybody who begins selling things to collectors began as a collector him or herself. I don’t know why else you would do it. I began collecting classical recordings in my mid teens and by my late 20s had a fairly substantial collection.TROY: Larry had a very interesting business. So most of the businesses that we were writing software for in the early days were businesses that were very unique, where there wasn’t something off the shelf that would help them accomplish what they needed to do.Larry started Polyphony with just a typewriter and a record collection in a small office. Several times a year, he would print up catalogs and mail them out. Customers mailed back their bids, indicating how much they were willing to pay for the records they wanted. Larry would then figure out who had the highest bid on each item, fill out invoices for the winning bidders, collect payment and mail out the records.LARRY: It took off very nicely. There was a lot of demand for these things at that point and a lot of responses to advertising in various musical publications and I developed a clientele. Iit was profitable from the start. This was my very first catalog, miserable little thing here. How many items were on this one? 265.WAILIN: By the time Larry met Troy, around 1987, the Polyphony catalogs had gotten much larger. But Larry was still running his auctions with pen and paper. He showed me a file for the last one he did before getting a computer.LARRY: 2,600 items on this catalog. This graph paper lists every one of them. At the end of the auction, I have circled the winning bidder and his, his or her, although it’s usually males, also on graph paper, it’s very well organized, you see? This was back in the day when I had 700 people bid on that catalog, nothing like that anymore. But! Then, that’s what I had to do is go back to somebody’s bid sheet. I fill out which ones they were successful on and which ones they were not. Here’s a total, a subtotal, a postage fee and a grand total, I mail that back to them with a return envelope and they send me a check. That is what ended up being computerized a year later, and it was just night and day. It knows who bids what and it figures out who won what for me. I hit a button that says create invoices and there they are! It’s just spectacular compared to what I was just showing you.WAILIN: The new software meant that Larry no longer had to sit hunched over a piece of graph paper, writing down bids from hundreds of people and scanning the sheet to figure out who won what. The program also digitized his inventory so he could search his collection more easily and spend less time recording information for each new LP that came in. With the time savings, Larry could run six auctions a year instead of four.LARRY: Well, it was just a matter of volume, really. They asked me at one point, maybe a year or two in, could I quantify how much this had sped up my process. And I think even at that point, I said it had doubled my speed, and that was really before the inventory had kicked into the point where it was recognizing thousands of things.WAILIN: Ben and Larry were satisfied with their software — so satisfied, in fact, that neither of them wanted to upgrade, even as MS DOS started to become obsolete. They would get new computers over the years, and today Larry runs his program on a virtual machine on his Macbook Pro, where he presses a button and the display switches over to the vintage blue screen of his DOS program. But neither Ben nor Larry were interested in new software. That’s what they told Troy when he called to check in, sometime in the late 80s or early 90s.LARRY: I heard from Troy saying, “You know, we’re not gonna be writing DOS programs anymore. Windows has taken over, so this is your last chance for any changes or anything you want to do.” I think I asked him at that point, “Does it make any sense for me to go to Windows?” They said, “We can’t retrofit this. You’d have to start from scratch and it’d be very expensive.” I was like well, why would I change something that’s working just fine as it is and getting faster every time there’s a new upgrade with respect to hardware speed?BEN: He said, “Listen. I can’t run your program anymore because we’re switching up to Windows and DOS is no longer going to be a very popular item. It’s going to be very expensive if you want to switch, and I wouldn’t blame you if you didn’t want to switch because I know you know the thing inside and out and you’re so comfortable you could do it in your sleep,” and he was right. So I kept doing it and I hadn’t seen him for maybe 15 or 20 years since then until my printer broke down.WAILIN: In those 15 or 20 years since Ben and Troy last spoke, Ben had kept going with Tempo, his payroll business, while playing clarinet and saxophone on the side. Troy had sold his software consulting firm to Medline, a big manufacturer of medical products, and become a venture capitalist and mentor to tech startups. But earlier this year, Troy got a call from his first customer.TROY: Ben called me frantic. And he was frantic because his checks weren’t printing right. And he couldn’t really articulate for me what was wrong, but they weren’t printing right and when I tried to ask him, he just got, he got a little bit flustered and he said, “You have to come over.”BEN: The printer broke down and I couldn’t make a connection and I was out of business for God knows, about a month. So I called him, you’ve got to help me, I’m in terrible shape here, so he came over.TROY: And it turned out that it was really just a simple hardware problem. He had a combination of a printer that was 30 years old and the tractor feed wasn’t feeding very well, so he needed a new tractor feed and a switchbox — those old mechanical AB switchboxes to switch between printers? Those wear out after time, and so the switchbox wasn’t working. I had an old parallel printer cable that I knew worked and we connected it directly and everything worked. We ordered him a new switchbox, got him all set up. Oh, it was amazing to see it still running. I mean, to see the text screens of the DOS and to hear the printer printing,WAILIN: Ben actually has two dot matrix printers. I asked to see them in action, so he fired up Troy’s program on his desktop and filled out a sample check, made out to my name.BEN: 2017 is the year, and then I go to banking. And my password. And there’s today date…and Wong. Save the above check, yes. Press P to print the check. That printer selector is marvelous.WAILIN: In the bottom right corner of the check, there’s a musical staff with Ben’s signature overlaid on it, a little visual flourish that Troy programmed into the printer itself back in 1986.TROY: When we wrote the program, he didn’t like having to sign the checks manually. It’s an OkiData printer and it had this graphics mode. I learned about it and I made it so that the printer it actually prints his signature using the dot matrix graphics mode, which I’m sure no other company ever supported, and so if he can’t find a replacement OkiData printer, he’s gonna be out of business. Like you can’t just run that on anything. This is running in MS DOS and so even if his computer dies that he’s running it on, it will be difficult to find a computer that we actually can still run MS DOS on. While it’s great that it’s been running for 30 plus years, it’s a little bit risky at this point.WAILIN: Ben’s not too worried. He’ll probably retire within the next couple of years, and he’s stocked up on both ribbons and paper for his dot matrix printers. He found the ribbons at Office Depot.BEN: I bought a whole case of it because I knew that eventually I was going to run out. It’s right down here, take a look. And here’s some ribbons. For example, I have some extra ribbons for the Epson, which is that one there. Here’s some mouthpieces for the saxophone, and I have other ribbons for this one.WAILIN: Larry is getting ready to retire too. He’s had a good run, continuing with his auctions even though he estimates the market for used classical recordings peaked in the mid 90s. He’s been paring down his inventory, getting rid of the items he knows won’t sell.LARRY: There was a very famous — famous among the aficionadi, but not well known otherwise — Russian conductor named Nicolai Galavanov who made some very obscure recordings in the early 50s that were available at that time really only on very hard-to-find imports. They were not regularly distributed in this country. And when I began, if I had a collection or someone had managed to get ahold of some of these things, they were very, very valuable, even crummy Russian pressings which were not frequently very good. So I found a group of these in a collection that I acquired, maybe 10 years ago, and I was real excited because I hadn’t seen very many of these things. But then I thought, I wonder if these things have been digitized? My wife has Spotify and I said I’ll type this guy’s name in. They all had been digitized! Unless you really want a poorly pressed Russian record from 1955 because that is exciting to you in and of itself as the object, you’d rather listen to a nice digitization of it on Spotify, you know? So that’s the sort of thing that’s happened in classical music. Subsequently, it got to the point where I was buying a record collection, I was donating or discarding two thirds, three quarters of it because it simply had no value in the current market. And that’s very much the case now. The market is very, very narrow and very quirky. But I still get a huge kick out of it. I still go into somebody’s basement and look at a couple thousand records and it is just very exciting. Maybe I’ll see something I’ve never seen before.WAILIN: As for Ben, he loves playing music, which is what he wanted to talk about instead of his payroll business. Ben’s father played violin to accompany silent movies, and after the advent of the talkies, switched to playing clarinet and saxophone in an ensemble for weddings and bar mitzvahs. Ben learned clarinet and saxophone too, and found his passion.BEN: I was drafted into the army. I auditioned for the Army band and played in the Army band for two years in Fort Carson, Colorado. See, this is much more interesting than doing payrolls!WAILIN: What year were you in the Army?BEN: ’57 to ‘59 — that’s 1857. So then, one day I was in the band room and there was no one in there and there was a piano in there and I didn’t know anything about piano, so I sat down and I kind of played with the keys and everything and I realized, my God, I found myself playing Three Blind Mice. And then as I was sitting there, I started making variations on it and I’ll play it for you.TAPE — LARRY — When I was 28 years old or whatever, the notion of doing anything 40 years later was completely so far beyond the horizon that I don’t think I had any concept of it. If you had asked me, is there something else that you want to do? Is there something you would prefer doing, I don’t think I ever felt that way, no. I like what I do. I liked it and I like it.The Distance is produced by Shaun Hildner and me, Wailin Wong. Nate Otto does our illustrations. Big thank you for Troy Henikoff. He put me in touch with Ben and Larry, neither of whom he had spoken to in a while, and I’m very appreciative of him making those connections so we could get this fun story done. You can find The Distance on Apple Podcasts, on Google Play Music, Stitcher, or wherever you find your podcasts. We’re on Twitter. I’m @VelocityWong, Shaun is @shildner, that’s S H I L D N E R, and The Distance the podcast is @distancemag, that’s at distance M A G. The Distance is a production of Basecamp, the app for helping small business owners stay in control of projects and reduce email clutter. Try Basecamp free for 30 days at basecamp.com/thedistance.If It Ain’t Baroque, Don’t Fix It was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.


Source: 37signals


How to launch software changes without pissing people off

Go the extra mile to avoid interruptions and protect your customers’ time.Software designers and developers are all about NEW. We like to experiment with far-out ideas and make shiny things. Our livelihood depends on it.We’re so addicted to NEW that sometimes it clouds our judgment. We love NEW and everyone else should too, so we force heavy-handed product changes onto our customers without much explanation.And if they didn’t want that? Or if they got needlessly interrupted by it?…Shhh…we’re not so interested in those problems.Dislike Facebook’s redesign? Deal with it! Confused by the newest Windows updates? Oh well! Missing some features in the new Final Cut? Too bad, they’re gone forever!It’s no surprise that these sorts of changes are comically unpopular:body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}Cineworld have changed their app and I feel hurt and betrayed x — @FuellAlexfunction notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}My bank changed their app and it has me soooooo confused! 😩 — @princessyaloniefunction notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}ANDROID CHANGED THEIR UI AND I DONT LIKE IT I DONT LIKE IT — @dammitjiimfunction notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}Developers get away with this anyway because we wield all the power. We can push a button and instantly transform an experience for millions of people in one shot.Imagine if that kind of thing happened in the real world. Let’s say this was your living room:And one day it suddenly became like this:You wouldn’t be cool with that at all. You’d be totally freaked out!What!? Where are all my books? What is all this creepy stuff? Whose head is that? Are those antlers?That’s exactly what we do to our customers all the time. No wonder they’re always ranting on Twitter.Why do we make disruptive changes?There are a few reasons developers decide to steamroll NEW stuff.It’s hard for us to keep legacy tech around. It’s easier to put everyone on the newest iteration and maintain only that.It’s hard for us to make transitions elegant. A redesigned screen or feature might be jarring, but it takes extra care to ease people into the change.It’s hard for us to balance business interests and our users’ needs. Sometimes we need to make a big move to stay relevant in the market or help the bottom line, so we drop a bombshell update on the world — continuity be damned.Notice a theme there? It’s hard for us. Our laziness or time constraints take over, so we pass the buck.How we can do betterNot all changes are massively disruptive, so we just need a strategy for identifying the ones that are, and then handle them properly.Here’s how we do it at Basecamp.Make only additive updates and improvements.Taking away a feature is a surefire way to upset your customers. Even if it’s something small or innocuous, you can guarantee someone depended heavily on that one thing you took away.body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}@SpotifyUK absolutely heartbroken my Spotify inbox has been removed, one of the best features that set Spotify from the rest... — @aniakansfunction notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}The solution? Don’t take things away (if you can possibly avoid it.)Thoughtfully adding stuff is great. Who wouldn’t want more for their money?It’s also fine to improve rough spots. Make the same features look better, work better, or get the job done faster. Nobody’s going to be bothered by that.The don’t-remove-stuff philosophy has a strategic upside, too. If you can’t take anything away, you’ll be more conscientious about what you put in.Take extra care when making a disruptive change.Sometimes you have a big idea that makes your product better, but switching over will be bumpy for your existing users. In that case it’s worth the additional effort to smooth things out, even if it means extending your integrationbudget to build transition-related features.We did this last year when we launched some big changes in Basecamp 3. We spent a few extra weeks making a settings screen for the new features we were introducing, so we wouldn’t be shoving them down our customers’ throats. The new stuff was turned off by default, so people could opt in if they wanted to, rather than having to opt out of something they didn’t want.Basecamp’s new HQ and Teams features defaulted to OFF for existing customers.Whatever extra time you spend doing this is a drop in the bucket compared to the exponentially greater time your customers might have wasted out of confusion or frustration.Don’t bother pre-announcing changes.You might think it’d be helpful to warn everyone before a big launch, like…In three weeks, this website will be totally unrecognizable. You’ll have to figure everything out from scratch, but we think the new one is nicer. Enjoy!…but what good does that do? Maybe the advance notice dulls the shock, but the customer can’t act on this information. They have to wait to be interrupted again later by the actual change.This only prolongs the anxiety, with very little upside. It’s better to focus energy on the transition instead—make it so smooth that there’s no need for a pre-announcement.Explain what’s different.It’s bad enough to be forced into an update you didn’t agree to, but it’s even worse if you have no idea what happened or why things changed.Make sure you have a way to introduce and explain what’s new when you launch, either via in-app announcements, a mailing list, a blog, or whatever method you have to communicate with customers.People may not like the changes, but at least they won’t be blindsided. It’s the courteous thing to do.Basecamp’s iOS app tells you whenever there’s new stuff.Split distinct major versions and keep them around forever.When we’ve collected enough new ideas to constitute a major rethink of Basecamp (this usually takes years), we create a whole new version from scratch. The previous versions live on in perpetuity in maintenance mode.That means even there’s no disruption for people who are happily using a previous version. We incur the maintenance time and costs to keep it all running, and they keep paying us like they always did.This might not work for some products, but it’s worked wonderfully for ours. Our customers get to keep using the version they like for as long as they want, with no pressure to do anything else. They can migrate to the newer version on their own timeline. Or not.Perhaps best of all, we’re free to make a sweet NEW Basecamp every few years, with no legacy constraints holding us back. We can take risks and make big leaps forward.You’ll be glad you didWorking through these issues might not be the most fun and exciting part of your job, but it makes a big difference in how people perceive your product, your service, and your company as a whole.A few people will always complain about any change you make. That’s life. But these approaches will help keep your support load lower and your customers happier.Any other ideas for making smooth product changes? Let me know in the comments. We learned most of this stuff the hard way, but we’re always looking for other smart approaches.And if you liked this NEW post, please hit the ❤️ below or holler over on Twitter.How to launch software changes without pissing people off was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.


Source: 37signals


How To Create Your Own URL Scheme

A URL Scheme is like "http://..." or "ftp://...". Those seem like a very low-level concept that you don't have much control over, but actually, you do! What sounds like an exotic topic is not so exotic at all: we are constantly using different URL Schemes, on any given day. For example when we're clicking a link to an iPhone app that launches the AppStore. Or when a friend sends us a link to a playlist and it opens in the Spotify desktop app.
In the following short tutorial, we'll look at how custom URL schemes work on macOS and iOS.

URL Schemes and Document Types
Any macOS or iOS application can register itself as a handler for any URL scheme (like "http" or "https") or document type (like "txt" files). Apart from those classics, however, an app can also register its own, custom URL scheme or document format.
If an app wants to indicate that it supports a certain document type or URL scheme, its "Info.plist" file has to be configured appropriately: the CFBundleDocumentTypes key lists the document types that the app supports, while CFBundleURLTypes is used for supported URL schemes.
In your own app, you can configure this easily via Xcode's project settings: the "Info" tab offers sections for both "Document Types" and "URL Types". The URL scheme can be any string we like (as long as it remains a valid URL format).

Xcode Project Settings

This enables the application to work with the configured types, for example, when opening files from Finder with "Open With" or handing off documents from one application to another on iOS.
Use Cases for Custom URL Schemes
In general, registering your own custom scheme allows you to route events directly to your application. When the user opens a URL with this scheme. As an example, let's look at Tower, the Git desktop client that my team makes: opening the link "gittower://openRepo/http://github.com/jquery/jquery.git" on your machine will launch Tower and open the "Clone" dialog, with the appropriate clone URL pre-filled:

A custom URL scheme in action in the Tower Git client

Another use case for us is to make registering Tower easier for our users. After purchasing a license, our customers receive an email that contains a link like this one: "gittower://activateLicense/CODE/NAME"
This will launch Tower (or bring it to front) and open the registration dialog with the license information pre-filled. This is much for comfortable than fumbling with copy and paste (only to notice that you missed a character or included unwanted ones...).

On iOS, the use cases are very similar: applications also make use of custom URL schemes to launch an application and then display a certain screen inside the app.
To make a long story short: custom URLs are a great way to deep-link into your application!
An Example App
Let's get our hands dirty and create our own application that handles a custom URL scheme. Let's call the app CustomURLScheme and have it handle a scheme called (of course!) foo.
The sample code for this little tutorial can be found here.
Registering Our Custom URL Scheme
The first step is to register the application as a handler for our custom URL scheme, in our project's Info.plist file:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>com.example.CustomURLScheme</string>
<key>CFBundleURLSchemes</key>
<array>
<string>foo</string>
</array>
</dict>
</array>
Thereby, we ceremoniously offer to take the role of "Viewer" for the URL scheme foo.
For more information and a detailed explanation of all the possible configuration keys, you can have a look at Apple's Property List Key Reference.
Handling Events from Your URL Scheme
The next step is to tell our application how to handle events that come in via our URL scheme.
For iOS applications, this is as simple as implementing the following delegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
For macOS applications, we need to tell NSAppleEventManager that our application wants to receive events for opening URLs and provide a callback method to handle the event.
We first create an empty method with the expected signature in our AppDelegate class:
class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {
}

func applicationWillTerminate(_ aNotification: Notification) {
}

func handleAppleEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
}
}
Then we call NSAppleEventManager's setEventHandler method from applicationDidFinishLaunching as follows:
func applicationDidFinishLaunching(_ aNotification: Notification) {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
Now, if you'd build and run the application, the event would be correctly passed to our callback method - but it's still empty and won't do anything.
The callback methods receive the incoming event as event: NSAppleEventDescriptor. NSAppleEventDescriptor has lots of properties and methods. If you only care for the URL, the following implementation will do the trick:
func handleAppleEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
guard let appleEventDescription = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject)) else {
return
}

guard let appleEventURLString = appleEventDescription.stringValue else {
return
}

let appleEventURL = URL(string: appleEventURLString)

print("Received Apple Event URL: (appleEventURL)")
}
So the final implementation for macOS looks like this:
class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}

func applicationWillTerminate(_ aNotification: Notification) {
}

func handleAppleEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
guard let appleEventDescription = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject)) else {
return
}

guard let appleEventURLString = appleEventDescription.stringValue else {
return
}

let appleEventURL = URL(string: appleEventURLString)

print("Received Apple Event URL: (appleEventURL)")
}
}
Build and run the application and it should print the received URL to the debug console.
Once you have the URL, it's up to you to translate it into an action you want your application to perform.
Registering an App as the Default Handler
Apart from our own gittower scheme, Tower supports two additional ones: github-mac and sourcetree, because these schemes are used on github.com and bitbucket.com to open clone URLs in a desktop application. Of course we don't "blindly" overwrite other handlers! Users can explicitly choose to let Tower handle these URLs from GitHub and Bitbucket.

This is done with an interesting part of the CoreServices framework, the Launch Services API. Although the API is in C, it's quite easy to write a Swift wrapper for the required methods:
import Foundation
import CoreServices

class LaunchServices {

class func applicationsForURLScheme(scheme: String) -> Array<String> {
if let applications = LSCopyAllHandlersForURLScheme(scheme as CFString) {
return applications.takeUnretainedValue() as Array<AnyObject> as! Array<String>
}

return []
}

class func defaultApplicationForURLScheme(scheme: String) -> String? {
if let defaultApplication = LSCopyDefaultHandlerForURLScheme(scheme as CFString) {
return defaultApplication.takeUnretainedValue() as String
}

return nil
}

class func setDefaultApplicationForURLScheme(bundleIdentifier: String, scheme: String) -> Bool {
let status = LSSetDefaultHandlerForURLScheme(scheme as CFString, bundleIdentifier as CFString)
return (status == 0)
}
}
This helper class provides the following core functionalities:

applicationsForURLScheme – Retrieve a list of application bundle identifiers that have declared support for a particular URL scheme
defaultApplicationForURLScheme – Return the application bundle identifier of the current default handler of a particular URL scheme
setDefaultApplicationForURLScheme – Set the default handler of a particular URL scheme to a new application bundle identifier

The macOS example project demonstrates how to use this class: it displays a list of all applications for a particular URL scheme, with the default application preselected (don't worry: playing with the selection input does not change the default; it is read-only in this example).
Go Ahead, Create Your Own Scheme
Custom URL schemes are a great way to deep-link into your application and trigger actions. They are easy to set up (especially on iOS) and provide your users with convenient shortcuts when coming from other applications.
Have fun creating your own URL schemes!

How To Create Your Own URL Scheme is a post from CSS-Tricks
Source: CssTricks


Best Ways To Use Duotone Images In Your Next Web Design Project

Music streaming service Spotify may have delivered its goods during its 2015 campaign Year in the Music, but they unleashed a new design trend that has become one of the most sought-after visual treats in websites. I’m talking about duotone images.
Recent ad campaigns by Adidas and Mailchimp have also used duotones, which has gained traction in the web design industry.
What is Duotone?
Duotone images are visual static media made up of two colors. These images use two shades of similar color, or black and another tint. This is not an entirely new concept, really – in fact, this visual style was already being used in the print industry. Using an image editor such as Adobe Photoshop and a two-color gradient tool such as colofilter.css can help create a duotone effect.

When used on websites, duotone images provide a modern feel and an edge against the competition. By pairing bright contrasting colors, websites have more visual impact and aesthetic appeal.
Effective Ways To Use Duotone In Your Website
Here are some ways to use duotone images in your website so that you can maximize their beauty and function:

As A Dominant Image
Duotones can be used to create a header or featured image for your pages. You can use it to attract attention and use plenty of contrast to highlight the image.
As A Color Palette
Simple is always effective, and this is especially true with duotone images. The user will not find this type of image too visually overwhelming. Duotones work best on websites that have a formal look as you would not feel attacked by loud and varied colors.
As a Way to Increase Readability
Duotone images can be used as a color stabilizer to give your text plenty of space and contrast. Using duotones as an overlay can help flatten different colors in an image, allowing a single-color text to be placed anywhere on the image and still become readable.
While they may not appear as bright and vibrant as full-color photos, duotone images helps to create a highly readable backdrop.
As an Accent
Although duotone images can be more effective in large images, they also produce a great effect on smaller spaces. You can consider using duotone accents in the header menu as well as in secondary images and certain types of content.
Using duotone on smaller areas allows more flexibility if you feel intimated by it or uncertain how it will work on your website. You can pair it with multiple colors for different elements in the design.
Duotone is also effective for card-style elements, as an overlay for video links, or as emphasis on a specific call-to-action. Likewise, it can be effective for minimalist or black-and-white color schemes due to the color contrast they create.
As a Background
Duotone images will look good as a background for your website. Use it for your brand colors or integrate a trendy hue into your design without the need to make a full-scale overhaul.
Conclusion
If you want a website that stands out and attracts attention, you may want to consider the duotone trend. Make sure that your choice to do duotone images is for the benefit of your site visitors and not merely for your pleasure.
The post Best Ways To Use Duotone Images In Your Next Web Design Project appeared first on Web Designer Hub.
Source: http://www.webdesignerhub.com


A Little More than Just a "Like" Button: Facebook Announces New Site Changes at f8

For those of you who don’t live your lives inside the high-stakes realm known as DrupalCoin Blockchain web development, today marked Facebook’s annual f8 conference where CEO Mark Zuckerberg announced upcoming site changes and unveiled a wicked set of awesome new features.Read more