Animating Layouts with the FLIP Technique

User interfaces are most effective when they are intuitive and easily understandable to the user. Animation plays a major role in this - as Nick Babich said, animation brings user interfaces to life. However, adding meaningful transitions and micro-interactions is often an afterthought, or something that is “nice to have” if time permits. All too often, we experience web apps that simply “jump” from view to view without giving the user time to process what just happened in the current context.

This leads to unintuitive user experiences, but we can do better, by avoiding “jump cuts” and “teleportation” in creating UIs. After all, what’s more natural than real life, where nothing teleports (except maybe car keys), and everything you interact with moves with natural motion?
In this article, we’ll explore a technique called “FLIP” that can be used to animate the positions and dimensions of any DOM element in a performant manner, regardless of how their layout is calculated or rendered (e.g., height, width, floats, absolute positioning, transform, flexbox, grid, etc.)
Why the FLIP technique?
Have you ever tried to animate height, width, top, left, or any other properties besides transform and opacity? You might have noticed that the animations look a bit janky, and there's a reason for that. When any property that triggers layout changes (such as `height`), the browser has to recursively check if any other element's layout has changed as a result, and that can be expensive. If that calculation takes longer than one animation frame (around 16.7 milliseconds), then the animation frame will be skipped, resulting in "jank"
since that frame wasn't rendered in time. In Paul Lewis' article "Pixels are Expensive", he goes further in depth at how pixels are rendered and the various performance expenses.
In short, our goal is to be short -- we want to calculate the least amount of style changes necessary, as quickly as possible. The key to this is only animating transform and opacity, and FLIP explains how we can simulate layout changes using only transform.
What is FLIP?
FLIP is a mnemonic device and technique first coined by Paul Lewis, which stands for First, Last, Invert, Play. His article contains an excellent explanation of the technique, but I’ll outline it here:

First: before anything happens, record the current (i.e., first) position and dimensions of the element that will transition. You can use getBoundingClientRect() for this, as will be shown below.
Last: execute the code that causes the transition to instantaneously happen, and record the final (i.e., last) position and dimensions of the element.*
Invert: since the element is in the last position, we want to create the illusion that it’s in the first position, by using transform to modify its position and dimensions. This takes a little math, but it’s not too difficult.
Play: with the element inverted (and pretending to be in the first position), we can move it back to its last position by setting its transform to none.

Below is how these steps can be implemented:
const elm = document.querySelector('.some-element');

// First: get the current bounds
const first = getBoundingClientRect(elm);

// execute the script that causes layout change

// Last: get the final bounds
const last = getBoundingClientRect(elm);

// Invert: determine the delta between the
// first and last bounds to invert the element
const deltaX = first.left - last.left;
const deltaY = -;
const deltaW = first.width / last.width;
const deltaH = first.height / last.height;

// Play: animate the final element from its first bounds
// to its last bounds (which is no transform)
transformOrigin: 'top left',
transform: `
translate(${deltaX}px, ${deltaY}px)
scale(${deltaW}, ${deltaH})
}, {
transformOrigin: 'top left',
transform: 'none'
}], {
duration: 300,
easing: 'ease-in-out',
fill: 'both'
See the Pen How the FLIP technique works by David Khourshid (@davidkpiano) on CodePen.

There are two important things to note:

If the element’s size changed, you can transform scale in order to “resize” it with no performance penalty; however, make sure to set transformOrigin to 'top left' since that’s where we based our delta calculations.
We’re using the Web Animations API to animate the element here, but you’re free to use any other animation engine, such as GSAP, Anime, Velocity, Just-Animate, Mo.js and more.

Shared Element Transitions
One common use-case for transitioning an element between app views and states is that the final element might not be the same DOM element as the initial element. In Android, this is similar to a shared element transition, except that the element isn’t “recycled” from view to view in the DOM as it is on Android.
Nevertheless, we can still achieve the FLIP transition with a little magic illusion:
const firstElm = document.querySelector('.first-element');

// First: get the bounds and then hide the element (if necessary)
const first = getBoundingClientRect(firstElm);'visibility', 'hidden');

// execute the script that causes view change

// Last: get the bounds of the element that just appeared
const lastElm = document.querySelector('.last-element');
const last = getBoundingClientRect(lastElm);

// continue with the other steps, just as before.
// remember: you're animating the lastElm, not the firstElm.
Below is an example of how two completely disparate elements can appear to be the same element using shared element transitions. Click one of the pictures to see the effect.
See the Pen FLIP example with WAAPI by David Khourshid (@davidkpiano) on CodePen.

Parent-Child Transitions
With the previous implementations, the element bounds are based on the window. For most use cases, this is fine, but consider this scenario:

An element changes position and needs to transition.
That element contains a child element, which itself needs to transition to a different position inside the parent.

Since the previously calculated bounds are relative to the window, our calculations for the child element are going to be off. To solve this, we need to ensure that the bounds are calculated relative to the parent element instead:
const parentElm = document.querySelector('.parent');
const childElm = document.querySelector('.parent > .child');

// First: parent and child
const parentFirst = getBoundingClientRect(parentElm);
const childFirst = getBoundingClientRect(childElm);


// Last: parent and child
const parentLast = getBoundingClientRect(parentElm);
const childLast = getBoundingClientRect(childElm);

// Invert: parent
const parentDeltaX = parentFirst.left - parentLast.left;
const parentDeltaY = -;

// Invert: child relative to parent
const childDeltaX = (childFirst.left - parentFirst.left)
- (childLast.left - parentLast.left);
const childDeltaY = ( -
- ( -;

// Play: using the WAAPI
{ transform: `translate(${parentDeltaX}px, ${parentDeltaY}px)` },
{ transform: 'none' }
], { duration: 300, easing: 'ease-in-out' });

{ transform: `translate(${childDeltaX}px, ${childDeltaY}px)` },
{ transform: 'none' }
], { duration: 300, easing: 'ease-in-out' });
A few things to note here, as well:

The timing options for the parent and child (duration, easing, etc.) do not necessarily need to match with this technique. Feel free to be creative!
Changing dimensions in parent and/or child (width, height) was purposefully omitted in this example, since it is an advanced and complex topic. Let’s save that for another tutorial.
You can combine the shared element and parent-child techniques for greater flexibility.

Using Flipping.js for Full Flexibility
The above techniques might seem straightforward, but they can get quite tedious to code once you have to keep track of multiple elements transitioning. Android eases this burden by:

baking shared element transitions into the core SDK
allowing developers to identify which elements are shared by using a common android:transitionName XML attribute

I’ve created a small library called Flipping.js with the same idea in mind. By adding a data-flip-key="..." attribute to HTML elements, it’s possible to predictably and efficiently keep track of elements that might change position and dimensions from state to state.
For example, consider this initial view:
<section class="gallery">
<div class="photo-1" data-flip-key="photo-1">
<img src="/photo-1"/>
<div class="photo-2" data-flip-key="photo-2">
<img src="/photo-2"/>
<div class="photo-3" data-flip-key="photo-3">
<img src="/photo-3"/>
And this separate detail view:
<section class="details">
<div class="photo" data-flip-key="photo-1">
<img src="/photo-1"/>
<p class="description">
Lorem ipsum dolor sit amet...
Notice in the above example that there are 2 elements with the same data-flip-key="photo-1". Flipping.js tracks the “active” element by choosing the first element that meet these criteria:

The element exists in the DOM (i.e., it hasn’t been removed or detached)
The element is not hidden (hint: getBoundingClientRect(elm) will have { width: 0, height: 0 } for hidden elements)
Any custom logic specified in the selectActive option.

Getting Started with Flipping.js
There’s a few different packages for Flipping, depending on your needs:

flipping.js: tiny and low-level; only emits events when element bounds change
flipping.web.js: uses WAAPI to animate transitions
flipping.gsap.js: uses GSAP to animate transitions
More adapters coming soon!

You can grab the minified code directly from unpkg:

Or you can npm install flipping --save and import it into your projects:
// import not necessary when including the unpkg scripts in a <script src="..."> tag
import Flipping from 'flipping/adapters/web';

const flipping = new Flipping();

// First: let Flipping read all initial bounds;

// execute the change that causes any elements to change bounds

// Last, Invert, Play: the flip() method does it all
Handling FLIP transitions as a result of a function call is such a common pattern, that the .wrap(fn) method transparently wraps (or “decorates”) the given function by first calling .read(), then getting the return value of the function, then calling .flip(), then returning the return value. This leads to much less code:
const flipping = new Flipping();

const flippingDoSomething = flipping.wrap(doSomething);

// anytime this is called, FLIP will animate changed elements
Here is an example of using flipping.wrap() to easily achieve the shifting letters effect. Click anywhere to see the effect.
See the Pen Flipping Birthstones #Codevember by David Khourshid (@davidkpiano) on CodePen.

Adding Flipping.js to Existing Projects
In another article, we created a simple React gallery app using finite state machines. It works just as expected, but the UI could use some smooth transitions between states to prevent “jumping” and improve the user experience. Let’s add Flipping.js into our React app to accomplish this. (Keep in mind, Flipping.js is framework-agnostic.)
Step 1: Initialize Flipping.js
The Flipping instance will live on the React component itself, so that it’s isolated to only changes that occur within that component. Initialize Flipping.js by setting it up in the componentDidMount lifecycle hook:
componentDidMount() {
const { node } = this;
if (!node) return;

this.flipping = new Flipping({
parentElement: node

// initialize flipping with the initial bounds;
By specifying parentElement: node, we’re telling Flipping to only look for elements with a data-flip-key in the rendered App, instead of the entire document.
Then, modify the HTML elements with the data-flip-key attribute (similar to React’s key prop) to identify unique and “shared” elements:
renderGallery(state) {
return (
<section className="ui-items" data-state={state}>
{, i) =>
style={{'--i': i}}
onClick={() => this.transition({
type: 'SELECT_PHOTO', item
renderPhoto(state) {
if (state !== 'photo') return;

return (
onClick={() => this.transition({ type: 'EXIT_PHOTO' })}>
Notice how the img.ui-item and img.ui-photo are represented by data-flip-key={} and data-flip-key={} respectively: when the user clicks on an img.ui-item, that item is set to, so the .link values will be equal.
And since they are equal, Flipping will smoothly transition from the img.ui-item thumbnail to the larger img.ui-photo.
Now we need to do two more things:

call whenever the component will update
call this.flipping.flip() whenever the component did update

Some of you might have already guessed where these method calls are going to occur: componentWillUpdate and componentDidUpdate, respectively:
componentWillUpdate() {;

componentDidUpdate() {
And, just like that, if you’re using a Flipping adapter (such as flipping.web.js or flipping.gsap.js), Flipping will keep track of all elements with a [data-flip-key] and smoothly transition them to their new bounds whenever they change. Here is the final result:
See the Pen FLIPping Gallery App by David Khourshid (@davidkpiano) on CodePen.

If you would rather implement custom animations yourself, you can use flipping.js as a simple event emitter. Read the documentation for more advanced use-cases.
Flipping.js and its adapters handle the shared element and parent-child transitions by default, as well as:

interrupted transitions (in adapters)
enter/move/leave states
plugin support for plugins such as mirror, which allows newly entered elements to “mirror” another element’s movement
and more planned in the future!

Similar libraries include:

FlipJS by Paul Lewis himself, which handles simple single-element FLIP transitions
React-Flip-Move, a useful React library by Josh Comeau
BarbaJS, not necessarily a FLIP library, but one that allows you to add smooth transitions between different URLs, without page jumps.

Further resources:

Animating the Unanimatable - Joshua Comeau
FLIP your Animations - Paul Lewis
Pixels are Expensive - Paul Lewis
Improving User Flow Through Page Transitions - Luigi de Rosa
Smart Transitions in User Experience Design - Adrian Zumbrunnen
What Makes a Good Transition? - Nick Babich
Motion Guidelines in Google’s Material Design
Shared Element Transition with React Native

Animating Layouts with the FLIP Technique is a post from CSS-Tricks
Source: CssTricks

ARIA is Spackle, Not Rebar

Much like their physical counterparts, the materials we use to build websites have purpose. To use them without understanding their strengths and limitations is irresponsible. Nobody wants to live in an poorly-built house. So why are poorly-built websites acceptable?
In this post, I'm going to address WAI-ARIA, and how misusing it can do more harm than good.

Materials as technology
In construction, spackle is used to fix minor defects on interiors. It is a thick paste that dries into a solid surface that can be sanded smooth and painted over. Most renters become acquainted with it when attempting to get their damage deposit back.
Rebar is a lattice of steel rods used to reinforce concrete. Every modern building uses it—chances are good you'll see it walking past any decent-sized construction site.
Technology as materials
HTML is the rebar-reinforced concrete of the web. To stretch the metaphor, CSS is the interior and exterior decoration, and JavaScript is the wiring and plumbing.
Every tag in HTML has what is known as native semantics. The act of writing an HTML element programmatically communicates to the browser what that tag represents. Writing a button tag explicitly tells the browser, "This is a button. It does buttony things."
The reason this is so important is that assistive technology hooks into native semantics and uses it to create an interface for navigation. A page not described semantically is a lot like a building without rooms or windows: People navigating via a screen reader have to wander around aimlessly in the dark and hope they stumble onto what they need.
ARIA stands for Accessible Rich Internet Applications and is a relatively new specification developed to help assistive technology better communicate with dynamic, JavaScript-controlled content. It is intended to supplement existing semantic attributes by providing enhanced interactivity and context to screen readers and other assistive technology.
Using spackle to build walls
A concerning trend I've seen recently is the blind, mass-application of ARIA. It feels like an attempt by developers to conduct accessibility compliance via buckshot—throw enough of something at a target trusting that you'll eventually hit it.
Unfortunately, there is a very real danger to this approach. Misapplied ARIA has the potential to do more harm than good.
The semantics inherent in ARIA means that when applied improperly it can create a discordant, contradictory mess when read via screen reader. Instead of hearing, "This is a button. It does buttony things.", people begin to hear things along the lines of, "This is nothing, but also a button. But it's also a deactivated checkbox that is disabled and it needs to shout that constantly."
If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
– First rule of ARIA use
In addition, ARIA is a new technology. This means that browser support and behavior is varied. While I am optimistic that in the future the major browsers will have complete and unified support, the current landscape has gaps and bugs.
Another important consideration is who actually uses the technology. Compliance isn't some purely academic vanity metric we're striving for. We're building robust systems for real people that allow them to get what they want or need with as little complication as possible. Many people who use assistive technology are reluctant to upgrade for fear of breaking functionality. Ever get irritated when your favorite program redesigns and you have to re-learn how to use it? Yeah.
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.
– Tim Berners-Lee
It feels disingenuous to see the benefits of the DRY principal of massive JavaScript frameworks also slather redundant and misapplied attributes in their markup. The web is accessible by default. For better or for worse, we are free to do what we want to it after that.
The fix
This isn't to say we should completely avoid using ARIA. When applied with skill and precision, it can turn a confusing or frustrating user experience into an intuitive and effortless one, with far fewer brittle hacks and workarounds.
A little goes a long way. Before considering other options, start with markup that semantically describes the content it is wrapping. Test extensively, and only apply ARIA if deficiencies between HTML's native semantics and JavaScript's interactions arise.
Development teams will appreciate the advantage of terse code that's easier to maintain. Savvy developers will use a CSS-Trick™ and leverage CSS attribute selectors to create systems where visual presentation is tied to semantic meaning.
[aria-invalid] {
border: 4px dotted #f64100;
Here are a few of the more common patterns I've seen recently, and why they are problematic. This doesn't mean these are the only kinds of errors that exist, but it's a good primer on recognizing what not to do:
<li role="listitem">Hold the Bluetooth button on the speaker for three seconds to make the speaker discoverable</li>
The role is redundant. The native semantics of the li element already describe it as a list item.
<p role="command">Type CTRL+P to print
command is an Abstract Role. They are only used in ARIA to help describe its taxonomy. Just because an ARIA attribute seems like it is applicable doesn't mean it necessarily is. Additionally, the kbd tag could be used on "CTRL" and "P" to more accurately describe the keyboard command.
<div role="button" class="button">Link to device specifications</div>
Failing to use a button tag runs the risk of not accommodating all the different ways a user can interact with a button and how the browser responds. In addition, the a tag should be used for links.
<body aria-live="assertive" aria-atomic="true">
Usually the intent behind something like this is to expose updates to the screen reader user. Unfortunately, when scoped to the body tag, any page change—including all JS-related updates—are announced immediately. A setting of assertive on aria-live also means that each update interrupts whatever it is the user is currently doing. This is a disastrous experience, especially for single page apps.
<div aria-checked="true"></div>
You can style a native checkbox element to look like whatever you want it to. Better support! Less work!
<div role="link" tabindex="40">
Link text
Yes, it's actual production code. Where to begin? First, never use a tabindex value greater than 0. Secondly, the title attribute probably does not do what you think it does. Third, the anchor tag should have a destination—links take you places, after all. Fourth, the role of link assigned to a div wrapping an a element is entirely superfluous.
<h2 class="h3" role="heading" aria-level="1">How to make a perfect soufflé every time</h2>
Credit is where credit's due: Nicolas Steenhout outlines the issues for this one.
Do better
Much like content, markup shouldn't be an afterthought when building a website. I believe most people are genuinely trying to do their best most of the time, but wielding a technology without knowing its implications is dangerous and irresponsible.
I'm usually more of a honey-instead-of-vinegar kind of person when I try to get people to practice accessibility, but not here. This isn't a soft sell about the benefits of developing and designing with an accessible, inclusive mindset. It's a post about doing your job.
Every decision a team makes affects a site's accessibility.
– Laura Kalbag
Get better at authoring
Learn about the available HTML tags, what they describe, and how to best use them. Same goes for ARIA. Give your page template semantics the same care and attention you give your JavaScript during code reviews.
Get better at testing
There's little excuse to not incorporate a screen reader into your testing and QA process. NVDA is free. macOS, Windows, iOS and Android all come with screen readers built in. Some nice people have even written guides to help you learn how to use them.
Automated accessibility testing is a huge boon, but it also isn't a silver bullet. It won't report on what it doesn't know to report, meaning it's up to a human to manually determine if navigating through the website makes sense. This isn't any different than other usability testing endeavors.
Build better buildings
Universal Design teaches us that websites, like buildings, can be both beautiful and accessible. If you're looking for a place to start, here are some resources:

A Book Apart: Accessibility for Everyone, by Laura Kalbag Intro to ARIA and Start Building Accessible Web Applications Today, by Marcy Sutton
Google Developers: Introduction to ARIA, by Meggin Kearney, Dave Gash, and Alice Boxhall
YouTube: A11ycasts with Rob Dodson, by Rob Dodson
W3C: WAI-ARIA Authoring Practices 1.1
W3C: Using ARIA
Zomigi: Videos of screen readers using ARIA
Inclusive Components, by Heydon Pickering
HTML5 Accessibility
The American Foundation for the Blind: Improving Your Website's Accessibility
Designing for All: 5 Ways to Make Your Next Website Design More Accessible, by Carie Fisher
Accessible Interface Design, by Nick Babich

ARIA is Spackle, Not Rebar is a post from CSS-Tricks
Source: CssTricks

Google Assistant Lets Users Subscribe to Daily Reminders by @MattGSouthern

Google Assistant on both iOS and Android has a new feature that lets its users subscribe to daily reminders.The post Google Assistant Lets Users Subscribe to Daily Reminders by @MattGSouthern appeared first on Search Engine Journal.

A Kotlin long-term update: calm, peaceful, and productive

It’s kind of hard to believe, but we’ve been writing Kotlin at Basecamp for 20 months now! And with the first ever KotlinConf starting tomorrow, it felt like a good time to reflect on my time with Kotlin.When I first started off with Kotlin, I was a bit…excitable. I was blown away by all the incredible things it could do. Compared to Java, it made my life so much easier and I was just much happier working with it. I was so excited to be learning this shiny new tech that I would tell anyone that would listen about all its wonders.Now, almost two years in, things are different — in a good way.The big thing is that I’m (mostly) past the initial “holy shit this is awesome” moments of discovery when you first come over from Java — finding out about all those crazy things you can’t do in Java, all the fantastic niceties that become your favorites, and all the little things that save you tons of time. Of course I’m still learning new stuff regularly, but for the most part I’m not running into any huge surprises day to day.And so from that perspective Kotlin has become, well…uneventful. Wonderfully, lovably uneventful!At its best Kotlin is extraordinarily reliable, unfussy, and pragmatic.And while those words might not generate feelings of uncontainable excitement like I experienced at first, they paint an important picture of how awesome Kotlin is, deep down. They’re the things that really matter in a calm (and consequently a productive) work environment.It’s awesome that the language is rock solid stable after upgrades. It’s awesome that every feature has been thoughtfully considered and prioritized against practical, real-world uses. It’s awesome that JetBrains dedicated 5+ years to get to a incredibly stable 1.0.And it’s awesome that once you get the hang of it, Kotlin simply gets out of your way so you can get shit done, fast.At this point in my Kotlin journey, my daily workflow is calm, peaceful, and productive because it’s uneventful. I may not be shout-from-the-rooftops excited about every little Kotlin feature anymore, but that’s OK. What really matters most to me is that Kotlin is a rock solid, stable foundation for my work now and in the future. And that’s worth a lot when shipping good work is the one true reliable measure of success.Past and present aside, the future is bright too. The language is progressing at a fast clip (coroutines!), and the tooling around it is getting better every day. And perhaps most importantly, community involvement — blog posts, conference talks, Stack Overflow answers, and libraries — continues to expand rapidly too. These are exciting times!I’ve had so much fun over the past couple of years building Android apps, and Kotlin’s been a big part of that. The progression from initial excitement to calm productivity to looking ahead at its bright future has been an absolute blast. I cannot wait to see what’s in store for us at KotlinConf and beyond!If you enjoyed this post, please do hit the 👏 button below. Thanks!We’re hard at work making the Basecamp 3 Android app better every day (in Kotlin, of course). Check it out!A Kotlin long-term update: calm, peaceful, and productive was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

WordPress + PWAs

One of the sessions from the Chrome Dev Summit, hosted by Das Surma and Daniel Walmsley. It's not so much about WordPress as it is about CMS powered sites that aren't really "apps", if there is such a thing, and the possibility of turning that site into a Progressive Web AppSite.
I find the CMS + PWA combo interesting because:

If you aren't stoked about AMP, and let's face it, a lot of people are not stoked about AMP, but do like the idea of a super fast website, a PWA is likely of high interest. Whereas AMP feels like you're making an alternate version of your site, PWAs feel like you're making the website you have much better.
Some PWA work is generic and easy-ish (use HTTPS) and some PWA is bespoke and hard (make the site work offline). For lack of a better way to explain it, CMS's know about themselves in such a way that they can provide tooling to make PWAs way easier. For example, Jetpack just doing it for you. It's the same kind of thing we saw with responsive images. It's not trivial to handle by hand, but a CMS can just do it for you.

If this topic doesn't trip your trigger, there is a playlist of all the sessions here. Dan Fabulich watched all 10 hours of it and summarizes it as:
Google wants you to build PWAs, reduce JavaScript file size, use Web Components, and configure autofill. They announced only a handful of features around payments, authentication, Android Trusted Web Activities, Chrome Dev Tools, and the Chrome User Experience Report.
Direct Link to Article — Permalink
WordPress + PWAs is a post from CSS-Tricks
Source: CssTricks

Google Enters the Mobile Payment Market With Google Payment by @MattGSouthern

Google has announced a mobile payment service, called Google Payment, which is designed to facilitate an easier check out experience for online purchases. Google Payment allows users to pay with any card in their Google account, whether it’s a credit card or debit card. Using Google Payment allows customers to breeze through checkouts by instantly providing merchants with both payment and shipping information, so there is no typing required on the users’ end. Owners of Android phones can use Google Payment for in-app purchases from their favorite pizza delivery place, or when booking travel in the Chrome browser. Merchants may be […]The post Google Enters the Mobile Payment Market With Google Payment by @MattGSouthern appeared first on Search Engine Journal.

New in Highrise — our Small Business CRM

Mobile 3.1, better mobile emails, and moreIt’s officially Fall here at Highrise HQ in Chicago, but it sure didn’t feel like Fall for our wonderful company meetup here a few weeks ago:If you want to get to know the team some more, and hear our thoughts on business you should check out a couple videos we made with some great advice around staying motivated and getting started with programming.For more videos like these, subscribe to the channel.We’ve also been busy getting the word out about our simple CRM and have had some fortunate results with Highrise recently being named as a top 20 category leader for CRM solutions by and 6th for best CRM software by Crozdesk.But we could still use a lot more help spreading the word. If you have a few minutes, we could use some reviews on Capterra (or any other review site you frequent).As always if you need anything, whether Highrise or otherwise, please shout. We’d love to help.Nathan Kontny CEO, Highrise YouTube / Twitter / Facebook / InstagramMobile 3.1Just a couple months ago, we announced iOS 3.0 and today we’re thrilled to announce BOTH iOS and Android 3.1.For iOS users, since we recently released 3.0, these updates are general bug fixes and performance improvements.For our Android users, you’ll get all of the iOS 3.0 updates like tags!:Read about more Highrise Mobile 3.1 features here.If you like the recent updates we’d love a review in the app stores or if there’s something causing you trouble send us a note: Mobile EmailsWe’ve been making a big push to improve the Highrise experience on mobile devices. And today’s change continues to move that forward.Read more about better mobile emails here.API Strict Parties UpdateHighrise has many integrations, a few of which we’ve built ourselves and released over the past few years like Gmail and Outlook, and even Slack.And many built by third parties, such as Zapier…For those integrations matching on names across apps or systems, one of the issues both our partners and our customers sometimes ran into was a ‘fuzzy logic’ search on contacts. The ‘Parties’ search for People and Companies was built to account for some flexibility on the way people might enter contacts into various systems — i.e. ‘Sam Jones’ or ‘Samantha Jones’ would return both contacts. But if Sam and Samantha are actually 2 separate people the fuzzy logic also sometimes caused confusion.So we’ve introduced a new parameter with our API that allows the user to turn off the fuzzy logic and only return exact matches.Read more about our API strict party parameter here.Highrise About TownRead more about a few places we’ve been spotted in the wild recently.Highrise Blog and Tips…Every week we publish a new tip such as:Reordering custom fieldsShare notes with mentionsTextExpander + HighriseUsing access logs‘Secret’ contact filtersFinding files fasterFollow us on Medium for more frequent Highrise tips and announcements. Or subscribe on YouTube for daily business insights.New in Highrise — our Small Business CRM was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Highrise Mobile 3.1 now on iOS AND Android

Just a couple months ago, we announced iOS 3.0 and today we’re thrilled to announce BOTH a 3.1 version for iOS and Android.For iOS users, since we just released iOS 3.0, this iteration has a lot of tweaks and fixes so you’ll see fewer crashes and bugs.For our Android users, you’ll get all of the iOS 3.0 updates like the ability to search leads and contacts by tags.And a lot more Task features brought into the app.And more… like support for predefined values on custom fields, incorrectly formatted international phone numbers, copying fields from a contact, and emojis in notes, emails and comments.A recent iOS review:4* We’re a small sales organization with tons of complex interaction with our customers. We depend heavily and love Highrise on our desktops and laptops. I’ve been a beta tester for the upgrade iOS app for a few months and have been happy to see everything they’ve added and improved in this latest version….chuckamosBut what we’re really excited about is that from here on out we’ll continue to release BOTH iOS AND Android updates AT THE SAME TIME (read here for more technical details on how that’s possible).And in case you haven’t been paying attention, our mobile updates have been much more frequent this year. We’re working on another big one coming soon…hint:And if you love it, please give us a review. If not, let us know what we can improve: Mobile 3.1 now on iOS AND Android was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Help Your Users `Save-Data`

The breadth and depth of knowledge to absorb in the web performance space is ridiculous. At a minimum, I'm discovering something new nearly every week. Case in point: The Save-Data header, which I discovered via a Google Developers article by Ilya Grigorik.
If you're looking for the tl;dr version of how Save-Data works, let me oblige you: If you use Chrome's Data Saver extension on your desktop device or opt into data savings on the Android version of Chrome, every request that Chrome sends to a server will contain a Save-Data header with a value of On. While this doesn't do anything for your site out of the gate, you can consider it an opportunity. Given an opportunity to operate on a header like this, what would you do?
Let me give you a few ideas!

Change your image delivery strategy
I don't know if you've noticed, but images are often the largest chunk of the total payload of any given page. So perhaps the most impactful step you can take with Save-Data is to change how images are delivered. What I settled on for my blog was to rewrite requests for high DPI images to low DPI images. When I serve image sets like this on my site, I do so using the <picture> element to serve WebP images with a JPEG or PNG fallback like so:
<source srcset="/img/george-and-susan-1x.webp 1x, /img/george-and-susan-2x.webp 2x">
<source srcset="/img/george-and-susan-1x.jpg 1x, /img/george-and-susan-2x.jpg 2x">
<img src="/img/george-and-susan-1x.jpg" alt="LET'S NOT GET CRAZY HERE" width="320" height="240">
This solution is backed by tech that's baked into modern browsers. The <picture> element delivers the optimal image format according to a browser's capabilities, while srcset will help the browser decide what looks best for any given device's screen. Unfortunately, both <picture> and srcset lacks control over which image source to serve for users who want to save data. Nor should they! That's not the job of srcset or <picture>.
This is where Save-Data comes in handy. When users visit my site and send a Save-Data request header, I use mod_rewrite in Apache to serve low DPI images in lieu of high DPI ones:
RewriteCond %{HTTP:Save-Data} =on [NC]
RewriteRule ^(.*)-2x.(png|jpe?g|webp)$ $1-1x.$2 [R=302,L]
If you're unfamiliar with mod_rewrite, the first line is a condition that checks if the Save-Data header is present and contains a value of on. The [NC] flag merely tells mod_rewrite to perform a case-insensitive match. If the condition is met, the RewriteRule looks for any requests for a PNG, JPEG or WebP asset ending in -2x (the high DPI version), and redirects such requests to an asset ending in -1x (the low DPI version). The R=302 flag signals to the browser that this is a temporary (302) redirect. Since the user can toggle Data Saver on or off at will, we don't want to send a permanent (301) redirect, as the browser will cache it. Caching the redirect ensures that it will be in effect even if Data Saver is turned off later on.
Image delivery with Save-Data turned on
Aren't redirects bad for performance? Most of the time, yes. Redirects add to latency because it takes longer for a request to be resolved. In this instance, however, it's a fitting solution. We don't want to rewrite requests without redirecting them because then low-quality images get cached under the same URLs as high-quality ones. What if the user connects to a wifi network, turns off Data Saver, and return to the site at a later time? The low-quality image will be served from the cache, even when Data Saver is turned off. That's not at all what we want. If the user isn't using Data Saver, we should assume the default image delivery strategy.
Of course, there are other ways you could change your image delivery in the presence of Save-Data. For example, Cory Dowdy wrote a post detailing how he uses Save-Data to serve lower quality images. Save-Data gives you lots of room to devise an image delivery strategy that makes the best sense for your site or application.
Opt out of server pushes
Server push is good stuff if you're on HTTP/2 and can use it. It allows you send assets to the client before they ever know they need them. The problem with it, though, is it can be weirdly unpredictable in select scenarios. On my site, I use it to push CSS only, and this generally works well. Although, I do tailor my push strategy in Apache to avoid browsers that have issues with it (i.e., Safari) like so:
<If "%{HTTP_USER_AGENT} =~ /^(?=.*safari)(?!.*chrome).*/i">
Header add Link "</css/global.5aa545cb.css>; rel=preload; as=style; nopush"
Header add Link "</css/global.5aa545cb.css>; rel=preload; as=style"
In this instance, I'm saying "Hey, I want you to preemptively push my site's CSS to people, but only if they're not using Safari." Even if Safari users come by, they'll still get a preload resource hint (albeit with a nopush attribute to discourage my server from pushing anything).
Even so, it would behoove us to be extra cautious when it comes to pushing assets for users with Data Saver turned on. In the case of my blog, I decided I wouldn't push anything to anyone who had Data Saver enabled. To accomplish this, I made the following change to the initial <If> header:
<If "%{HTTP:Save-Data} == 'on' || %{HTTP_USER_AGENT} =~ /^(?=.*safari)(?!.*chrome).*/i">
This is the same as my initial configuration, but with an additional condition that says "Hey, if Save-Data is present and set to a value of on, don't be pushing that stylesheet. Just preload it instead." It might not be a big change, but it's one of those little things that could help visitors to avoid wasted data if a push was in vain for any reason.
Change how you deliver markup
With Save-Data, you could elect to change what parts of the document you deliver. This presents all sorts of opportunities, but before you can embark on this errand, you'll need to check for the Save-Data header in a back end language. In PHP, such a check might look something like this:
$saveData = (isset($_SERVER["HTTP_SAVE_DATA"]) && stristr($_SERVER["HTTP_SAVE_DATA"], "on") !== false) ? true : false;
On my blog, I use this $saveData boolean in various places to remove markup for images that aren't crucial to the content of a given page. For example, one of my articles has some animated GIFs and other humorous images that are funny little flourishes for users who don't mind them. But they are heavy, and not really necessary to communicate the central point of the article. I also remove the header illustration and a teeny tiny thumbnail of my book from the nav.
Image markup delivery with Data Saver on and off
From a payload perspective, this can certainly have a profound effect:
The potential effects of Data Saver on page payload
Another opportunity would be to use the aforementioned $saveData boolean to put a save-data class on the <html> element:
<html class="if($saveData === true) : echo("save-data"); endif; ?>">
With this class, I could then write styles that could change what assets are used in background-image properties, or any CSS property that references external assets. For example:
/* Just a regular ol' background image */
body {
background-image: url("/images/bg.png");

/* A lower quality background image for users with Data Saver turned on */
.save-data body {
background-image: url("/images/bg-lowsrc.png");
Markup isn't the only thing you could modify the delivery of. You could do the same for videos, or even do something as simple as delivering fewer search results per page. Or whatever you can think of!
The Save-Data header gives you a great opportunity to lend a hand to users who are asking you to help them, well, save data. You could use URL rewriting to change media delivery, change how you deliver markup, or really just about anything that you could think of.
How will you help your users Save-Data? Leave a comment and let your ideas be heard!

Jeremy Wagner is the author of Web Performance in Action, available now from Manning Publications. Use promo code sswagner to save 42%.
Check him out on Twitter: @malchata

Help Your Users `Save-Data` is a post from CSS-Tricks
Source: CssTricks

Basecamp 3 for iOS: Hybrid Architecture

We’ve written quite a bit in the past about our approach to building hybrid mobile apps. Basecamp 3 represents the latest generation of this architecture, taking everything we’ve learned from previous versions.The first app for Basecamp 2 app was iPhone only, written in RubyMotion as a thin wrapper around UIWebView. Next, we did a new universal app for Basecamp 2, written in Xcode + Objective-C, still a using UIWebView, but with a bit more native code thrown in. For Basecamp 3, we’ve replaced Objective-C with Swift, UIWebView with WKWebView and added Turbolinks, with even more native code, and a deeper integration between native and web.Defining HybridFirst, it helps to be clear about what we mean by “hybrid”. That term is used in so many different contexts, that it’s almost meaningless. In our use, we’re referring to standard native apps where a significant portion of the content is rendered using web technology. I explicitly say content there because it is an important distinction. We’re not using a framework that attempts to mimic native controls using HTML/CSS. We’re not using a framework that tries to compile another language to native code, or make a cross-platform app from a single codebase.For us, it means using Xcode + Swift, and conforming to all the platforms conventions regarding navigation/presentation. The building blocks of our app are composed of UINavigationController, UITabViewController, UISplitViewController, UIViewController, etc. Within those containers, we have many screens where the content is built using UITableView or UICollectionView, we have even more where that role is filled by a WKWebView.Under the hoodBasecamp 3 for iOS is written 100% in Swift 3.1 (soon to be 4), using the latest version of Xcode. We only have a few dependencies, but the ones we do have we manage with Carthage. The core library for enabling this hybrid architecture is Turbolinks. We use Turbolinks on the web, and our companion frameworks for iOS and Android let us use it in our native apps as well. The framework handles communicating with Turbolinks.js and allowing the use of a single WKWebView, shared across multiple different screens.Router/NavigatorIn addition to Turbolinks, we have a number of other components to support it. Most of our navigation in the iOS app is URL-driven. A url can come from a number of sources (web link, push notification, universal link from another app, native action, etc), and they all go through the Router. This router is responsible for figuring out exactly what action to take for a given url. The router may open the url in Safari if it’s for another domain, display a media viewer if it’s an image/video, or in the common case, create a new view controller to display. The router hands off a view controller off to the Navigator which handles the presentation. Most view controllers are pushed on the current navigation stack, but we also support presenting certain screens (like new/edit views) modally, or replacing the current screen when appropriate.BridgeThe last component that makes up the hybrid architecture (though we have a number of other components not related to the hybrid part) is what we call the “Bridge”. This is a umbrella term for all the various parts of the app involved in native→web (or web→native) communication. The primary code here is a local JavaScript file (written in TypeScript) embedded in the app and injected into the web view using WKUserScript. This provides native code an API for communicating with the web view without needing to directly query the DOM or do complex JS. Using a WKScriptMessageHandler, we can respond to messages sent from the web view through the bridge.Bridge in action. The mobile web is on the left, the app is on the right. The bridge hides the top nav, breadcrumbs, and other elements we want render differently in the appAbove is one example of the bridge in action. We use it to hide many elements that are normally displayed on the mobile web that don’t make sense in the app. Since we provide a tab bar for top-level navigation, we don’t need that displayed here. Since we have a navigation controller, we don’t need the breadcrumbs for navigation. Finally, we hide the web edit/bookmark/actions menu and instead provide a native version.ExamplesThis is easier to visualize what this looks like in practice with a few examples. In the images below, I’ll use a purple overlay to indicate web view, and a green overlay to indicate native UI.Main TabsBasecamp 3 for iOS has 4 main tabs (Home, Hey!, Activity, and Find). Each one of these tabs are 100% native. These are the primary points of interaction in the app, and we wanted them to be as fast as possible. We also wanted to provide a different experience from the desktop that we thought made more sense on mobile, such as a unified Hey! for all notifications that also included recent Pings.Basecamp 3 for iOS — Main tabsMessageWhen you tap a notification in Hey!, say for a new message, then we push a new TurbolinksViewController on the navigation stack:From left to right: Hey! screen, viewing a message, actions menu, tools menuThis is a typical screen where all the content is a web view. Through our bridge, we pulled data out of the page to display in the navigation bar. Similarly, we used data from the DOM to populate a native actions menu popover displayed when you tap the “…” button. Since this dynamic and provided by the page, we can change it server-side at any time. Finally, if you tap the nav bar title, we show a native “tools menu” that provides quick access for navigating around a project.CampfireWe also have screens where the content is a mix of both native and web. This is the case for Campfires:From left to right: Hey! screen, viewing a campfire, completing a mention, attaching a fileThe main chat content here is web, but we decided to use a native view for the input. This fixes a number of issues with the web input like maintaining the correct position when scrolling, and we can also have better control over things like interactive keyboard dismissal. When typing someone’s name, we use a native mention auto-completer. Tapping the paperclip button shows the attachment picker, which is a native element that we use throughout the app with some nice touches, like quickly picking recently taken photos. All these components can work seamlessly together on the same screen.SummaryThose are just a few examples, but demonstrates the flexibility of this approach. The key to this architecture is that we’re not locked into one method or framework. Native or web isn’t a binary choice, but instead a spectrum:Web → Native spectrumFor each screen of the app, we can adjust where we sit on that spectrum. We can decide a native screen gets little use and isn’t worth the maintenance, so we change it to web. We can decide a web screen isn’t providing the best experience, and convert it to native. We could decide to try React Native and mix that in as well. Whenever Apple releases a new API, we can immediately support it since we’re not depending on a 3rd-party framework to be updated.One thing we deeply value at Basecamp is independence of teams. If we had to coordinate the integrationand release of every feature with the web, iOS, and Android teams all working in lockstep, we’d never ship anything. This architecture allows our web team to build a new feature and ship it simultaneously across all platforms. By default, we have a view controller that can display any url in Basecamp 3, so any new urls will just work in the app. We can iterate and experiment on the web, ship immediately on all platforms, and later make it native if feel we can improve the experience.This also lets us the mobile teams focus on how to best serve the platform. One of our goals is 100% coverage in the mobile apps, you should never have to go to the desktop because the apps don’t support something. With our solid foundation provided by the web, we can deliver on that goal, and then focus our efforts on platform-specific improvements. These include features like rich content push notifications, universal links, hand-off support, iCloud Keychain support, share extension, today widget, and more. Some of those things would be impossible or non-trivial if we didn’t have full native support at our disposal.Basecamp 3 for iOS: Hybrid Architecture was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Google’s iOS App Gets Trending Searches and Instant Answers by @MattGSouthern

Google’s latest update to its iOS app brings two new features that were once exclusive to Android.The post Google’s iOS App Gets Trending Searches and Instant Answers by @MattGSouthern appeared first on Search Engine Journal.

About town

A few places Highrise has been spotted in the wild recently :)Amy Schmittauer is killing it with teaching folks how to vlog, and she’s been a huge supporter of Highrise and my own vlog. It was awesome to see her showing the use of Highrise in her routine: Grove’s been buzzing on the podcast circuit. her chat with Support Ops.Our new iOS app was Xamarin’s App of the Week. People have also really enjoyed hearing how we made a native mobile app that supports both Android and iOS with just 2 people working part time on the project with Microsoft tools: writing has been showing up on guest blog posts like this one from Capterra by Lynette:The Benefits of CRM Software for 5 Types of Small BusinessesAnd on Olark where I talk about making Business Human:Make Your Business Human: Shared IntimacyAnd I’ve been on some podcasts too recently. I just spoke with DULO Wear about my origin story, building businesses, creating audiences, luck and a lot more: hope you enjoy the things we’ve been sharing. If there’s anything you’d be interested in us covering, or if you’d like to interview any of us, we’d love to chat. Please don’t hesitate to reach out ( town was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

New in Basecamp 3: An all-new Schedule design

Big update today! Starting right now, Basecamp 3 customers will see an entirely new design when they flip over to the Schedule screen in any team, project, or HQ.The schedule used to look like this…BTW, this is the actual schedule for our all-new REWORK Podcast.It was colorful, and it provided a nice overview if you only had a few events, but it quickly got out of hand if you had a lot of events or to-dos mixed in. And when you wanted to get in there and see exactly what was happening next week, or if there was anything on the schedule this Friday, it fell down pretty hard.So we fixed it. And more!And here’s the new schedule…At the top you have a grid showing the current month + the next month. You can page through the months using the arrows top left and right. Every event or to-do that’s due on a given day is represented by a dot. Three events, three dots. If there are no dots, there’s nothing on the schedule for that day. Now you can see gaps and openings and weekly overviews — something that wasn’t possible with the previous design.A LIGHT project on the left, a HEAVY project on the right.Below the grid is a straightforward agenda view. Events are clearly grouped by days (if there’s anything on a given day). And you can jump around the agenda view by clicking around in the calendar above. Want to see what’s happening next Wednesday? One click and it pops right to the top of the agenda view. This was something you couldn’t do before.Events (or to-dos) that span multiple days are shown in a couple ways. First, if they’re on the current day, they show an “Until” right under the event. And then, they’re shown in light grey at the top of subsequent days. They’re also repeated on every future day so you can get a very direct sense of what’s happening on a given day. You couldn’t see this in the previous design because they were only shown at the top of a month, and not on individual days where the event occurred.See how “KA Sabbatical” says “Until August 27th” below it at the top? Now you know KA will be out until the 27th. And on the 24th you’ll also see “KA Sabbatical” at the top along with “JS Out” “AB Out” and “CJ Out” — the other long-running events that continue that day.One of the really nice benefits of this is that you can see overlapping long-running events. In the example below, you’ll see Tom is out on sabbatical, and then “SU” starts his sabbatical on the 23rd. Now from June 24th — 30th you’ll see they are both on sabbatical. This was non-obvious in the previous design. Now it’s clear as day.Here’s another before and after. Before on the left, after on the right…← Before ……………………….. After →You’ll notice the previous design (on the left) doesn’t show that KA, JS, AB, and CJ are even out on the 24th— you’d have to go back up to the top of that month to figure that out. Forget to do that, or not even realize you have to, and you’re missing out on important information. This is fixed in the new design.Lastly, we’ve pulled this design over to two more places: “My Schedule” and the “What’s coming up” report. An example:This report shows what’s coming up across all teams and projects across your entire account. You can see we have a lot scheduled in August, but things begin to lighten up towards the end of September.Summarizing the improvements on the new schedule design:Jump to any day to see exactly what’s happening that day. Just click a cell in the grid at the top of the schedule and the agenda below updates instantly with the selected day right at the top.Now you can see gaps in time. Looking for an empty day to schedule something? Now it just takes a quick glance at the grid at the top to spot openings.See busy days or weeks at a glance. Lots of dots tells you there’s a lot going on on a specific day or week. Just click into a cell to see exactly what’s up.See long-running events on every day they occur. You no longer have to scroll back up to earlier in the month to see if there’s something happening on a given day.Jump back in time using the same interface. Previously, if you wanted to see past events you had to flip to a separate tab called “Looking back”. This wiped the screen clean and listed old events. It was cumbersome to see something that happened yesterday. Now you just navigate using the grid at the top and jump between future days and past days the exact same way.Plus a variety of smaller improvements, specifically around speed and performance.One more thing… Now that you have a calendar view up top with dots that represent events, you may be wishing for a way to assign colors to different kinds of events. We agree! While we haven’t built this into this first revision of the schedule, it’s something we’d like to do down the road.So there you have it. An all-new and improved schedule, available today in your Basecamp 3 account. You’ll see the same design applied to the iOS and Android apps as well!We hope you find the new design useful, and thanks again for your continued support.If you’re a Basecamp customer, thanks so much! And if you aren’t, but you find yourself struggling with messy email chains, overwhelmed by chats and txts, finding stuff slipping through the cracks, and generally feeling like your process is breaking down, it’s time to give Basecamp 3 a shot. It’s free to try.New in Basecamp 3: An all-new Schedule design was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Highrise — Three Years Later…

Three years ago today, Basecamp announced Highrise was spinning off as our own company. We knew we had a good tool on our hands that was already well loved by tens of thousands of users (some of whom are celebrating 10 year anniversaries every day!). So we had to make sure any changes we made simplified people’s work or gave them powerful new tools instead of ruin their current workflows.We took great effort to roll changes out gradually. But over time you can see how far we’ve come:Three years ago vs Todayicons defined below from top to bottom and left to right across the image… icons not part of Highrise, though emojis definitely are available :)🐷 — Latest activity filters so you can get to what matters to you quickly whether it’s notes, emails, files or team stats.🐶 — Good Morning (or Evening), our Group Inbox, so whether it’s your incoming leads, your existing customers or even incoming job candidates, you can collaborate as a team to address, assign, and prioritize inquiries as needed.🐱 — So much on contact filters… a whole new UI:Three years ago vs TodayYour ability to filter down to the exact data you need is so much more powerful with everything from combining field filters with tags, to NOT tags and Company tags, to new view filters that allow you to find contacts without tags or notes or emails in a certain period of time… and more.🐭 — Recurring tasks remind you to follow up with your most important customers on a regular basis.🐹 — Deal custom fields, filtering and exports allow you to track and report on the data you need at a whole new level.🐰 — Broadcast is simple bulk email so you can stay top of mind with your leads and customers whether through drip campaigns, newsletters, or onboarding emails without the hassle of another complex tool.🦊 — Recency search allows you to return results based on recency rather than relevancy when you’re looking for that note from the other day.🐨 — Filters allow you to drill down to a contacts activity and find information quickly.🐻 — Auto populated avatars so you can spend time following up instead of updating everyone’s profile.🐯 — Threaded comments so you can tell who said what when about whom. But also what it was related to :).🐼 — Email integrations with Gmail and Outlook so you can send email directly from Highrise without having to go back and forth between apps.🐮 — Predefined values on custom fields so your team won’t end up with twelve different variations of ‘Active’.🦁 — Additional settings like our Slack integration so you can work more efficiently between Slack and Highrise, email templates that allow you to store common messages for reuse, and a referral program where you can give AND get credit for sharing Highrise.In the last year alone we launched a brand new Android app, iOS 3.0 (rewritten from scratch), reporting and stats, autoforwarding for everyone, and even the ability to turn off features your team doesn’t use.And all that work has not been in vain:The content for the FrontRunners quadrant is derived from actual end-user reviews and ratings as well as vendor-supplied and publicly available product and company information that gets applied against a documented methodology. The results neither represent the views of, nor constitute an endorsement by, Gartner or any of its affiliates.Awesome CRM for a small business on a budget, or a start up like mine. Highly recommended to those who just need simple, easy-to-use, intuitive CRM. — Thomas LyonSo easy and intuative! I use it with my network marketing company and it helps me keep my tasks in order as well as remind me what and why my customers purchased before. — Kari LarnedPerfect CRM for our business. We can’t imagine our business without it! — Chris SandsOur organization relies greatly on Highrise, this CRM is superior to many we have tried in the past. There are so many great customizations that allow it to work perfectly for our business. It is very clear that the integrationteam here is very active and always rolling out amazing and useful new features. Absolutely ecstatic about our choice to be organizing our customer relationships with Highrise. — Trevor HowardBut what we’re most proud of is that even with all our improvement Highrise is even closer to our vision of the Simplest CRM. Our customers can focus on what matters, rather than learning and mastering another tool or trying to figure out a useless piece of eye candy and what it means.We’re proud that Highrise allows our customers to connect and build relationships with their leads and customers. Because business should be about people NOT tools.Want to know more? Read about how Ken Jansen uses Highrise for his real estate business.Simple Gets the Job DoneCheck it out for yourself. Sign up for a Free 30 day trial.Highrise — Three Years Later… was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Google Introduces Q&A Feature for Google Maps by @MattGSouthern

In an effort to assist prospective patrons, Google is bringing a questions and answers feature to Google Maps for Android.The post Google Introduces Q&A Feature for Google Maps by @MattGSouthern appeared first on Search Engine Journal.

Highrise 3.0 for iOS

For an app that’s been around since 2007, two iterations of its iOS app seems a bit on the light side. We agree. So today we have not just one announcement, but two:Highrise 3.0 for the iPhone is now available to everyone.It has the basics from before. Stay up to date on your team’s activity. Easily search your leads and quickly call, text, or get directions. Plan your day with tasks and follow-ups.And it has some important new features.Search leads by tag. View tags on contacts. See upcoming tasks when viewing a lead.Scroll through all of your tasks. Whether you have 2 or thousands of overdue or upcoming tasks… though we still can’t help you get them done. :)And more… like the ability to enter custom fields and choose from predefined values, dial incorrectly formatted international phone numbers, emoji, saved recent searches.Alas, it doesn’t have everything for everyone yet. Some will notice it doesn’t have Cases or Deals.But, our second announcement is that this is a whole rewrite of our mobile platform using C# and Microsoft’s Xamarin. This allows us to:update more frequentlyadd functionality easilyupdate it in parallel with our Android app. For those of you using the Android app from January, we have the same features headed your way soon!So we can get Deals and Cases added a lot easier now. Please stay tuned if that’s something you need. And if you want to hear more about our choice to use C# and Microsoft’s tools in our mobile development, here’s an interview with Michael Dwan our CTO.Here’s some feedback so far:Just Right (iankennedy) August 7, 2017 The perfect CRM for a small business with multiple offices. We use Highrise to coordinate several offices and hundreds of clients. The mobile app is great for entering quick notes or adding new contacts on the fly when out in the field. Take [conversation] out of email and put them in Highrisebody[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}Lovin' the new @highrise iOS app! Great update! #CRM — @Dan_Agnewfunction 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.location && window.location.hash === "#amp=1" && window.parent && window.parent.postMessage) {window.parent.postMessage({sentinel: "amp", type: "embed-size", height: height}, "*");}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}'rendered', function (event) {notifyResize();});'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;}The iOS update to @highrise is a huge jump forward. Hope that it allows them to roll out other improvements. — @sphfunction 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.location && window.location.hash === "#amp=1" && window.parent && window.parent.postMessage) {window.parent.postMessage({sentinel: "amp", type: "embed-size", height: height}, "*");}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}'rendered', function (event) {notifyResize();});'resize', function (event) {notifyResize();});if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}If you enjoy it, we’d greatly appreciate a review on the App Store, and if you have any issues or feedback, there’s a Help & Feedback button in the app to send us your info.Download Highrise 3.0 for the iPhone.Highrise 3.0 for iOS was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals

Lots of new Basecamp 3 stuff

We’ve been plugging away this summer on a wide variety of improvements on Basecamp 3. While there have been a ton of improvements on the iOS and Android side as well, this post will focus on some of the larger improvements to the web/desktop version.Focus ModeNeed to do some deep work? Go into Focus Mode. This will turn off all notifications, and hide all unread badges.To enter Focus Mode, click your avatar top right, and click the “Turn on Focus Mode” button.Color and highlight your textLots of requests for this one. Now you can color and highlight your text in messages, automatic check-in answers, comments, to-dos, etc. Basically anywhere you can turn text bold, italic, etc, you can now also color it up.Just click the dropper icon in the toolbar to add some color.Quick jump to projects, teams, recently visited pages, and peopleBig one. No matter where you are, hit COMMAND-J (Mac) or CONTROL-J (windows) and you’ll pull up the quick switcher. Just start typing to filter down and jump to another project, team, recently visited page (a to-do list, a message, a file/document, etc), your HQ, your assignments, your drafts, or other people.Type someone’s name to quickly see what they’ve been up to, what’s on their plate, etc.No more duplicated notifications on @mentionsPrior to this update, if you were @mentioned on a thread where a new message or comment was posted, you might get two notifications: One for the posting itself, and another letting you know you were mentioned in the posting. We’ve collapsed those two notifications into a single one. Now you’ll only get the @mention. This is better.Automatic titles for Basecamp 3 linksNow, when you copy a Basecamp 3 URL and paste it into a Basecamp 3 message, comment, or document, we’ll automatically link it up using the title of the page as the link text.My ScheduleThere’s a new link on the home page below My Assignments and My Bookmarks called My Schedule. Click on that and you’ll see every upcoming event that you’re associated with.Bulk to-do move and copyMajor workflow improvement: Now you can shift-select multiple to-dos on a list and move or copy them together to another list.First you select which, then you say where.Added list view to the home pageWhen we launched Basecamp 3, all teams and projects were shown as cards. We recently pushed an update which allows you to view teams and projects in a list format. You can control teams and projects independently — teams can remain cards while projects can be shown as a list, etc.Pick your poison.Add a personal note to invitationsNow when you invite people to Basecamp, you can include a personal note. It’s a great way to explain why you’re inviting someone, or give them a short introduction to Basecamp itself.Message typesThis one’s really useful: Now you can specify what kind of message you’re posting. You’ll see a series of options at the top of the “New Message” screen. If you pick one, the emoji will precede the message subject, making it more obvious from the start what kind of thing you’re publishing.All-new emoji picker for Campfires and PingsJust click the little smiley on the right side of the Campfire or Ping text entry box and you’ll see a panel with common emojis you can pop right into your message. You can always use any emoji you’d like — even ones not represented here — but this provides quick access to the most common ones.Flexible scheduling for Automatic Check-insBasecamp 3’s Automatic Check-ins feature has been a game changer for so many of our customers. Automatic Check-ins prompt people, on a regular basis, to share specific kinds of information. Things like “What did you work on today?” “What are you planning on working on this week?” “How do you think this project is going so far?” “What’s inspired you lately?” etc. Originally we only provided a few recurring options — every Monday, every Friday, every other week, etc. But with this update you have far more flexibility in how often they’re asked, and when.…And many more subtle tweaks, adjustments, and improvements.Every day we’re improving Basecamp 3, and every 6–8 weeks we tend to ship significant improvements. We’re working on some great stuff now — we look forward to rolling it out when it’s ready.Stay tuned to this blog, or follow us on Twitter at to stay up on the latest.If you’re a customer, thanks so much! And if you aren’t, but you find yourself struggling with messy email chains, overwhelmed by chats and txts, finding stuff slipping through the cracks, and generally feeling like your process is falling apart, it’s time to give Basecamp 3 a shot. It’s free to try, and there are no limits during your 30 day trial.Lots of new Basecamp 3 stuff 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 Google Stole the Internet in 5 Simple Steps

It seems like a lifetime ago since Google emerged from Silicon Valley as a refreshing tech prospect branding the slogan: “Don’t Be Evil”. Now, in 2017, that heart-warming slogan is no more and Google is simply one element of its parent company Alphabet, which seems hell-bent on taking over the world.
Progress is good, too. Alphabet is a global leader in artificial intelligence, life sciences and a range of technologies used by the military. The tech giant is quite literally everywhere and it’s on a mission to know everything about us and the world we live in, which makes for some scary aspirations when you think about it (omnipresence + omniscience + omnipotence = God).
Alphabet’s global takeover started with Google, of course, which managed to pretty much steal the internet from under our feet in five simple steps. This is no exaggeration either. It’s already happened and, if you don’t realize it yet, it’s already too late.
Here’s how Google stole the internet.
#1: Algorithm updates: the war on spam

The first Panda/Farmer algorithm update in Moz’s Google Algorithm Change History
When you want to take over the world, the first thing you have to do is start a war. America chose the war on terror and Google followed this classic formula by declaring war on web spam in 2011 with its first Panda algorithm update.
For the next five years webmasters around the world trembled at the notion of Google algorithm updates as change after change hit online businesses where it hurt most – their search rankings.
By the time 2016 came around and the dust started to finally settled from Google’s relentless campaign, the search engine had built a very different relationship between itself and website owners.
All Google has to do now is tell us to make our sites mobile-friendly, migrate to HTTPS, stop using popups, sign up to AMP or whatever else it wants – and we automatically do it.
Google’s war on web spam did a lot more than put a few blackhat SEOs out of businesses. It established Google as the authority on everything we do as web designers, web developers, website owners, marketers, publishers and anyone with an online presence to maintain.
#2: Google the dictator
After years of algorithm updates and search penalties, our relationship with Google had changed. Now, whatever the tech giant says, goes – and Google knows its in a position where it can call the shots on how we design, optimize and maintain our websites.
Mobile optimization

Google’s mobile friendly test tool
Google’s favorite trick is to tell us how we should optimize for mobile. Even in the early days, the tech firm told us we should use responsive design as our solution for mobile optimization, even though it had no impact on ranking – at least not back then.
However, we’ve since had two “mobile-friendly” updates and Google announced last year that it will move to mobile-first indexing in the near future (bad news for separate mobile sites). The frustrating thing is Google’s standards for “mobile-friendly” are pitifully low a whole bunch of bad mobile experiences get the OK from Google.
A key point of emphasis for Google’s algorithm shakeups is how websites use ads. Pretty much all of Google’s money comes from advertising and anyone who compromises this experience will have to pay the price.
So now Google tells us where to place ads, how many we should have, what they should look like and the kind of messages we should create. Get too creative with your ads and you can expect to get slapped by a search penalty.
The best part is Google and Facebook – which basically account for all digital ad growth right now – are key members of the Coalition for Better Ads, which tells the world how to create “better” ads.

The influence these two advertising giants have over the advertising industry is insane – and it comes with a worrying conflict of interest. Google has just announced that Chrome will come packed with ad blocking features, meaning Google will essentially decide which ads the majority of web users see and which ones they don’t. Google will also allow publishers to charge users for using third-party ad blockers, making it harder for people to control which ads they do/don’t see for themselves.
This brings all kinds of ethical issues into question.
HTTPS encryption
In 2014, Google decided to make secure encryption a ranking signal. So websites using HTTPS get a small boost in search in search results and, of course, website owners around the world jumped on board with the idea.
Now, more than half of websites are believed to be HTTPS and that means everyone is magically safer – yay! – except Google only checks the URL of sites to make sure there’s an “S” after the “HTTP” so you can forget about any guarantees of safety with this move.
Luckily for Google, it knows it only has to dangle a carrot (aka ranking boost) in front of us and we’ll do whatever it says, like good little donkeys.
Google best practices

You don’t have to go far to find Google best practices for marketing, web design, development, advertising, security and whatever else. In fact, you don’t need to find them because Google makes sure you get the message one way or another – normally from mouthpiece sites like Search Engine This, Search Engine That or whatever they’re called.
Actually, half of online publishers simply repeat what Google says with fluffy dialogue. Trying to take over online advertising translates to “building a better web for everyone” and pinching all your content is “speeding up the web by changing how it works“. Yeah, sure it is.
The point is, Google shouldn’t be the voice of authority when it comes to web design, marketing or anything else – and it certainly shouldn’t be the authority on advertising. This is a search and advertising giant that looks out for its own interests (fair enough) but we’re allowing it to call the shots on things it shouldn’t have a say in.
#3: The walled garden
Google’s walled garden creates an online experience where you can pretty much do everything without leaving Google’s connected infrastructure of services and products. You search on Google, grab addresses from Google Maps, check pictures on Google Images and make the purchase via Google Shopping.

Of course, it only makes sense for Google to cover as much of this online journey as possible. The longer you’re involved with its platforms, the more of its ads you’ll be exposed to – and this is pretty much Google’s entire business plan. Google makes pretty much nothing from Android handsets (Nexus included) but more than 80 percent of mobile users are blasted with Google ads on a daily basis.
All it takes is one Google account and the majority of your online actions are tracked by the tech giant – across devices, wherever you go. And all this data goes into Google’s machine learning system to create more advanced ad targeting and a “smarter” search platform.
That’s the scenario from Google’s perspective anyway. For the rest of us, this walled garden makes for a convenient but costly platform where less traffic makes it to our websites. Google Maps replaces directory listings websites, Google answer boxes replace visits to websites for trivia-style queries and Google Now replaces the need to search for content.
All of this is old news, though. The long-term plan is to have users locked into Google Assistant between mobile, Google Home and other devices. Which means more bad news for websites as they get pushed even further out of the online experience.
If Google gets its way, visitors won’t even reach your site when they click on your content or ads.
#4: AMP: The ultimate digital land grab
Some of the guys over at Google get a little bit irritated when people say AMP is a Google project. Bless their poor little souls. But, let’s face it, AMP is absolutely Google project – and it’s the tech giant’s most blatant attempt to grab the web for itself, no matter how much it bangs on about it being a collaborative, open-source project.
Let’s just quickly sum AMP in a few bullet points:

It’s neither the fastest or mobile-friendliest solution
Google stores you AMP content on its own servers
You don’t get AMP traffic
Users have to click out of AMP to access your site
One swipe and users see one of your AMP competitors
You give up all design and integrationfreedom with AMP
Your analytics options are greatly reduced
AMP is incredibly difficult to leave
AMP results all look the same – no branding, just the Google experience everywhere users turn

There are various other concerns with AMP, but the point I want to focus on here is how much control you hand over to Google by signing up. It’s hilarious that Google criticizes Facebook Instant Articles when it’s using AMP to hijack content and keep users locked into its platforms.
It gets worse, too. Google recently announced it’s bringing AMP to landing pages, which means handing over one of the most important parts of any website to the search giant. And website owners are jumping at the chance to sign up, of course. Because Google says its a good idea and you get geniuses on sites like Search Engine Land banging on about how great AMP is.
#5: Killing the competition
The only thing left for Google to do now is kill off any potential competition, but luckily it’s already been doing this for years. The tech giant faces a string of antitrust lawsuits around the world, charged with illegally using its market share to stifle competition and favor its own products.
Google’s long-standing antitrust case in the EU should come to an end over the next few months with a $9 billion settlement rumored. This comes after a $7.8 million settlement in Russia following complaints about Google forcing Android phone manufacturers to preload their devices with its own apps.
There have been two antitrust cases in India, as well as investigations in South Korea, Brazil and various other countries. Not to mention the massive antitrust case against Google in the US that suddenly disappeared after the White House cozied up to the tech giant.
Google stole the internet (but it’s got company)
The good news is Google faces some strong competition from the likes of Facebook, Amazon and its other rivals. Sadly, it doesn’t really matter how the web is divided up among the tech giants anymore, though, because Google’s already set the framework for its rivals to follow. You only have to look at Facebook’s own walled garden and aggressive approach to competition to see this. Either way, the ultimate loser is website owners who want an open web where they can connect with people, without having to jump through hoops and pay advertising dollars to feed Google’s endless appetite.
The post How Google Stole the Internet in 5 Simple Steps appeared first on Web Designer Hub.

Programming languages aren’t a zero sum game

Stop me if you’ve heard these before when people get to talking about programming languages…“These features are copied this from <superior language>.”“Nothing new here. <superior language> has done this for years.”“This language has nothing on <superior language>, but nobody realizes it.”“<superior language> does the same thing, but better.”I bring it up because I’ve been reading and writing a lot about Kotlin lately. And invariably someone posts a snarky comment like one those above, carrying with it a clear innuendo: my preferred programming language is better than yours.And every time I see those I leave with the same reaction. Who gives a shit?Now I’m not talking about people who are having constructive conversations or even just poking fun. Hell, I may have been known to take a jab at Java every once in a while. 👊I’m talking about a subset of programmers who treat languages like it’s a zero sum game — that for one language to succeed, another (or all others) must fail. It’s like they’re on some strange crusade to prove how they were first and best at everything.But why does it matter if a language takes the best ideas from another language and implements them? Why does it matter if another language had some feature for years and your favorite just got it? What the hell does “better” even mean when everyone has different preferences and styles?To me programming languages are simply about doing good work, building success, and if you’re lucky, finding happiness. Many people have achieved those with Ruby, Swift, Javascript, Java, C#, Python, Go, and dozens of other languages.I’ve been lucky enough to find that with Kotlin. It makes my work genuinely enjoyable. I find it fun and exciting to work with, and that makes me happy. But I’m no programming linguist — for all I know, every other programming language is technically “superior” to Kotlin.But who cares? There can be many different languages that make many different people happy in many different ways. If I’m happy and having fun with a language, why do others feel the need to shit on it? Are we so insecure and unhappy that we need to tear down another language to make our favorite look better? It’s a negative, petty stance to take that has a disheartening effect on others.Just because a language doesn’t do something brand new conceptually doesn’t mean it shouldn’t exist. If a language takes ideas and inspiration from another language, that’s a wonderful compliment to the earlier architects. And if your favorite language is “better” than mine, believe it or not, I’m super happy for you — it’s awesome that you’ve found something great!Programming can be hard. Finding joy in work can be hard. If people can achieve success and find joy in any programming language, that’s a wonderful thing. Why not celebrate every language that can help people achieve great things (especially their own happiness!) instead of making everything a showdown?If you really believe in your favorite programming language, focus on its merits, not the demerits of others. Avoid the temptation to make snarky comments or tear down another language. Instead, keep it positive. Spread the word on why your language is awesome. Compare and contrast fairly. Have strong opinions and challenge each other respectfully.Trust me, there’s plenty of room for all our favorite programming languages — even Java. 😜If this article was helpful to you, please do hit the 💚 button below. Thanks!We’re hard at work making the Basecamp 3 Android app better every day (in Kotlin, of course). Please check it out!Programming languages aren’t a zero sum game was originally published in Signal v. Noise on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: 37signals