CSS

I’ve said a number of times in the past:

I wish I could just check a checkbox and make certain Google Analytics data public.

I get that analytics can be a very private thing for some sites. I think there are just as many sites where that data just doesn’t need to be private. Not only would it be interesting, but insight might be gleaned from having more eyeballs on the data, and it could contribute to a wider data set of analytic trends.

Anyway, there is no such checkbox. But Zach Aten pointed out to me there is a thing called Data Studio that allows you to build custom visual reports, and you can make them public with the same kind of sharing controls you find in other Google products (like Google Docs).

I slapped together a quick dashboard for just raw traffic data. Not the most useful thing to look at, but sometimes the most fun. I’d embed it here, but…

Can I embed charts on other sites?

No. Data Studio is currently a stand alone product.

Embedding a Data Studio report in an iframe is blocked by Chrome as a potential security risk.

So here’s a link to it and a picture:

Sorry about the awful design. It just, you know, proves it’s authentic. Their templates are much nicer, and all the tools are there to do as good of a job as you’d like.

Of course, you can do a way better job of not only building more beautiful and useful charts but also of collecting more useful data. If you’re using Google Analytics, doing a little bit more than using the default snippet goes a long way. Remember we have an article and video on that subject.


Google Analytics Data Studio is a post from CSS-Tricks

Source: Google Analytics Data Studio


CSS

Lea Verou writes about the design of HTML APIs and how we might write better documentation for web designers. An HTML API is term for a JavaScript library that is configured and controlled through HTML rather than through JavaScript. For example <div data-open-modal="#modal"></div> might tell a library that this element is in charge of opening a modal. There is no configuration or initting other than loading the library itself.

My favorite part of this piece is where Lea confronts what might generally be seen as a simple plug-n-play JavaScript library:

Even this tiny snippet of code requires people to understand object literals, arrays, variables, strings, how to get a reference to a DOM element, events, when the DOM is ready and much more. Things that seem trivial to programmers can be an uphill battle to HTML authors with no JavaScript knowledge

By giving folks an HTML API we can avoid potential headache.

…remember that many of these people do not speak any programming language, not just JavaScript. Do not talk about models, views, controllers or other software engineering concepts in text that you expect them to read and understand. All you will achieve is confusing them and turning them away.

Lea’s made a collection of libraries that have HTML APIs.

Direct Link to ArticlePermalink


HTML APIs: What They Are And How To Design A Good One is a post from CSS-Tricks

Source: HTML APIs: What They Are And How To Design A Good One


wired.com Design

Hypnotic Animations Show Why Trees Depend on Forest Fires

Fire ecology is a big topic. Eleanor Lutz, the infographic-maker of the <em>Tabletop Whale</em> blog, breaks it down. The post Hypnotic Animations Show Why Trees Depend on Forest Fires appeared first on WIRED.
Source: Hypnotic Animations Show Why Trees Depend on Forest Fires


CSS

You might have heard of RxJS, or ReactiveX, or reactive programming, or even just functional programming before. These are terms that are becoming more and more prominent when talking about the latest-and-greatest front-end technologies. And if you’re anything like me, you were completely bewildered when you first tried learning about it.

According to ReactiveX.io:

ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.

That’s a lot to digest in a single sentence. In this article, we’re going to take a different approach to learning about RxJS (the JavaScript implementation of ReactiveX) and Observables, by creating reactive animations.

Understanding Observables

An array is a collection of elements, such as [1, 2, 3, 4, 5]. You get all the elements immediately, and you can do things like map, filter and map them. This allows you to transform the collection of elements any way you’d like.

Now suppose that each element in the array occurred over time; that is, you don’t get all elements immediately, but rather one at a time. You might get the first element at 1 second, the next at 3 seconds, and so on. Here’s how that might be represented:

This can be described as a stream of values, or a sequence of events, or more relevantly, an observable.

An observable is a collection of values over time.

Just like with an array, you can map, filter, and more over these values to create and compose new observables. Finally, you can subscribe to these observables and do whatever you want with the final stream of values. This is where RxJS comes in.

Getting Started with RxJS

The easiest way to start using RxJS is to use a CDN, although there are many ways to install it depending on your project’s needs.

<!-- the latest, minified version of RxJS -->
<script src="https://unpkg.com/@reactivex/rxjs@latest/dist/global/Rx.min.js"></script>

Once you have RxJS in your project, you can create an observable from just about anything:

const aboutAnything = 42;

// From just about anything (single value).
// The observable emits that value, then completes.
const meaningOfLife$ = Rx.Observable.just(aboutAnything);

// From an array or iterable.
// The observable emits each item from the array, then completes.
const myNumber$ = Rx.Observable.from([1, 2, 3, 4, 5]);

// From a promise.
// The observable emits the result eventually, then completes (or errors).
const myData$ = Rx.Observable.fromPromise(fetch('http://example.com/users'));

// From an event.
// The observable continuously emits events from the event listener.
const mouseMove$ = Rx.Observable
  .fromEvent(document.documentElement, 'mousemove');

Note: the dollar sign ($) at the end of the variable is just a convention to indicate that the variable is an observable. Observables can be used to model anything that can be represented as a stream of values over time, such as events, Promises, timers, intervals, and animations.

As is, these observables don’t do much of anything, at least until you actually observe them. A subscription will do just that, which is created using .subscribe():

// Whenever we receive a number from the observable,
// log it to the console.
myNumber$.subscribe(number => console.log(number));

// Result:
// > 1
// > 2
// > 3
// > 4
// > 5

Let’s see this in practice:

See the Pen

const docElm = document.documentElement;
const cardElm = document.querySelector('#card');
const titleElm = document.querySelector('#title');

const mouseMove$ = Rx.Observable
  .fromEvent(docElm, 'mousemove');

mouseMove$.subscribe(event => {
  titleElm.innerHTML = `${event.clientX}, ${event.clientY}`
});

From the mouseMove$ observable, every time a mousemove event occurs, the subscription changes the .innerHTML of the titleElm to the position of the mouse. The .map operator (which works similar to the Array.prototype.map method) can help simplify things:

// Produces e.g., {x: 42, y: 100} instead of the entire event
const mouseMove$ = Rx.Observable
  .fromEvent(docElm, 'mousemove')
  .map(event => ({ x: event.clientX, y: event.clientY }));

With a little math and inline styles, you can make the card rotate towards the mouse. Both pos.y / clientHeight and pos.x / clientWidth evaluate to values between 0 and 1, so multiplying that by 50 and subtracting half (25) produces values from -25 to 25, which is just what we need for our rotation values:

See the Pen

const docElm = document.documentElement;
const cardElm = document.querySelector('#card');
const titleElm = document.querySelector('#title');

const { clientWidth, clientHeight } = docElm;

const mouseMove$ = Rx.Observable
  .fromEvent(docElm, 'mousemove')
  .map(event => ({ x: event.clientX, y: event.clientY }))

mouseMove$.subscribe(pos => {
  const rotX = (pos.y / clientHeight * -50) - 25;
  const rotY = (pos.x / clientWidth * 50) - 25;

  cardElm.style = `
    transform: rotateX(${rotX}deg) rotateY(${rotY}deg);
  `;
});

Combining with .merge

Now let’s say you wanted this to respond to either mouse moves or touch moves, on touch devices. Without any callback mess, you can use RxJS to combine observables in many ways. In this example, the .merge operator can be used. Just like multiple lanes of traffic merging into a single lane, this returns a single observable containing all of the data merged from multiple observables.

Source: http://rxmarbles.com/#merge
const touchMove$ = Rx.Observable
  .fromEvent(docElm, 'touchmove')
  .map(event => ({
    x: event.touches[0].clientX,
    y: event.touches[0].clientY
  }));

const move$ = Rx.Observable.merge(mouseMove$, touchMove$);

move$.subscribe(pos => {
  // ...
});

Go ahead, try panning around on a touch device:

See the Pen

There are other useful operators for combining observables, such as .switch(), .combineLatest(), and .withLatestFrom(), which we’ll be looking at next.

Adding Smooth Motion

As neat as the rotating card is, the motion a bit too rigid. Whenever the mouse (or finger) stops, the rotation instantly stops. To remedy this, linear interpolation (LERP) can be used. The general technique is described in this great tutorial by Rachel Smith. Essentially, instead of jumping from point A to B, LERP will go a fraction of the way on every animation tick. This produces a smooth transition, even when mouse/touch motion has stopped.

Let’s create a function that has one job: to calculate the next value given a start value and an end value, using LERP:

function lerp(start, end) {
  const dx = end.x - start.x;
  const dy = end.y - start.y;

  return {
    x: start.x + dx * 0.1,
    y: start.y + dy * 0.1,
  };
}

Short and sweet. We have a pure function that returns a new, linearly interpolated position value every time, by moving a current (start) position 10% closer to the next (end) position on each animation frame.

Schedulers and .interval

The question is, how do we represent animation frames in RxJS? Turns out, RxJS has something called Schedulers which control when data is emitted from an observable, among other things like when subscriptions should start receiving values.

Using Rx.Observable.interval(), you can create an observable that emits values on a regularly scheduled interval, such as every one second (Rx.Observable.interval(1000)). If you create a tiny interval, such as Rx.Observable.interval(0) and schedule it to emit values only on every animation frame using Rx.Scheduler.animationFrame, a value will be emitted about every 16 to 17ms, within the animation frame, as expected:

const animationFrame$ = Rx.Observable.interval(0, Rx.Scheduler.animationFrame);

Combining with .withLatestFrom

To create a smooth linear interpolation, you just need to care about the latest mouse/touch position on every animation tick. To do that, there is an operator called .withLatestFrom():

const smoothMove$ = animationFrame$
  .withLatestFrom(move$, (frame, move) => move);

Now, smoothMove$ is a new observable that emits the latest values from move$ only whenever animationFrame$ emits a value. This is desired — you don’t want values emitted outside animation frames (unless you really like jank). The second argument is a function that describes what to do when combining the latest values from each observable. In this case, the only important value is the move value, which is all that’s returned.

Source: http://rxmarbles.com/#withLatestFrom

Transitioning with .scan

Now that you have an observable emitting the latest values from move$ on every animation frame, it’s time to add linear interpolation. The .scan() operator “accumulates” the current value and next value from an observable, given a function that takes those values.

Source: http://rxmarbles.com/#scan

This is perfect for our linear interpolation use-case. Remember that our lerp(start, end) function takes two arguments: the start (current) value and the end (next) value.

const smoothMove$ = animationFrame$
  .withLatestFrom(move$, (frame, move) => move)
  .scan((current, next) => lerp(current, next));
  // or simplified: .scan(lerp)

Now, you can subscribe to smoothMove$ instead of move$ to see the linear interpolation in action:

See the Pen

Conclusion

RxJS is not an animation library, of course, but handling values over time in a composable, declarative way is such a core concept to ReactiveX that animation serves as a great way to demonstrate the technology. Reactive Programming is a different way of thinking about programming, with many advantages:

  • It is declarative, composable, and immutable, which avoids callback hell and makes your code more terse, reusable, and modular.
  • It is very useful in dealing with all types of async data, whether it’s fetching data, communicating via WebSockets, listening to external events from multiple sources, or even animations
  • “Separation of concerns” – you declaratively represent the data that you expect using Observables and operators, and then deal with side effects in a single .subscribe() instead of sprinkling them around your code base.
  • There are implementations in so many languages – Java, PHP, Python, Ruby, C#, Swift, and others you might not have even heard of.
  • It is not a framework, and many popular frameworks (such as React, Angular, and Vue) work very well with RxJS.
  • You can get hipster points if you want, but ReactiveX was first implemented nearly a decade ago (2009), stemming from ideas by Conal Elliott and Paul Hudak two decades ago (1997), in describing functional reactive animations (surprise surprise). Needless to say, it’s battle-tested.

This article explored a number of useful parts and concepts of RxJS – creating Observables with .fromEvent() and .interval(), operating on observables with .map() and .scan(), combining multiple observables with .merge() and .withLatestFrom(), and introducing Schedulers with Rx.Scheduler.animationFrame. There are many other useful resources for learning RxJS:

If you want to dive further into animating with RxJS (and getting even more declarative with CSS variables), check out my slides from CSS Dev Conf 2016 and my talk from JSConf Iceland 2016 on Reactive Animations with CSS Variables. For inspiration, here’s some Pens that use RxJS for animation:


An Animated Intro to RxJS is a post from CSS-Tricks

Source: An Animated Intro to RxJS


CSS

Vincent De Oliveira has written an epic post that details pretty much everything you might ever want to know about the line-height and vertical-align properties. If you’ve ever had trouble aligning things next to text or wondered why two fonts look so wildly different from one another then this post is certainly for you.

Direct Link to ArticlePermalink


Deep dive CSS: font metrics, line-height and vertical-align is a post from CSS-Tricks

Source: Deep dive CSS: font metrics, line-height and vertical-align


CSS

Dan Wilson documents a classic annoyance with transforms:

button {
  transform: translateY(-150%);
}
button:hover {
  /* will (perhaps unintentionally) override the original translate */
  transform: scale(.8);
}

The native (and WET) solution is list the original transform again:

button:hover {
  transform: translateY(-150%) scale(.8);
}

Dan’s trick is to use custom properties instead. Set them all on the element right up front, then re-set them the :hover state:

:root {
  --tx: 150%;
  --scale: 1;
}
button {
  transform: 
    translateY(var(--tx))
    scale(var(--scale));
}
button:hover {
  --scale: 0.8;
}

Cascading custom properties FTW.

Direct Link to ArticlePermalink


Individual CSS Transform Functions is a post from CSS-Tricks

Source: Individual CSS Transform Functions


wired.com Design

Someone Finally Mapped Cape Town’s Bewildering Taxi Network

For decades, Cape Town’s commuters have learned to navigate the city’s vast informal taxi network by word of mouth. Now they have a map. The post Someone Finally Mapped Cape Town’s Bewildering Taxi Network appeared first on WIRED.
Source: Someone Finally Mapped Cape Town’s Bewildering Taxi Network


CSS

Kevin Vigneault:

I don’t believe that the overall page length itself is inherently problematic. I have noticed though that in many responsive designs, purposeful groupings of content are easy to spot on larger screens, but get muddled when things start to stack on mobile screens.

This is probably mostly a problem on “content” sites in which you smash things down into the ol’ tube of content. I don’t mind the tube, but I think Kevin is doing some smart thinking here. There are plenty of different patterns that can happen while tubizing, and it’s probably not thought about enough.

This site is particularly guilty. A quick document.documentElement.offsetHeight test showed 14749px, more than double the height of an example Kevin pointed out that was a bit excessive.

Direct Link to ArticlePermalink


Do responsive sites have to be so tall on mobile? is a post from CSS-Tricks

Source: Do responsive sites have to be so tall on mobile?


CSS

The DevTools (in any browser) are an invaluable development tool for CSS developers. If you need to see (and play with) the styles on any given element, a quick inspection is only a few clicks away.

Right click on something and “Inspect Element”, or, open DevTools and use its selection tools to grab what you need.

But… sometimes it can be difficult or impossible to target the element you need to target in the DevTools. The DOM events needed to work with the DevTools themselves can interfere.

Say I inserted an element on the mouseenter event of a certain other element, then removed it on mouseleave.

Try as I might, I just can’t target that newly-added element for inspection.

Chrome DevTools can simulate a :hover style, but that doesn’t really help us here. It doesn’t fire the DOM event, it just simulates the CSS state.

This is very useful, but won’t help us here.

The trick is to fire a debugger; right when you need it

A debugger; statement, when the DevTools are open, kinda freezes the DOM. No more events are fired and script excecution is completely paused.

But… you can still use DevTools!

This is your opportunity to select that otherwise-impossible thing to select and do what you need to do. You can put that debugger; statement right in your code where you need it (remember DevTools has to be open for it to work). Or (Tim Holman taught me the trick) you can trigger it with a setTimeout() right from the console.

setTimeout(function() {
  debugger;
}, 3000);

Give yourself a few seconds to get the DOM how you need it, then the debugger; will fire and you can inspect as needed.

I tried this, and it works, in Chrome, Firefox, Edge, and Safari, so it’s a pretty cross-browser DevTools friendly trick. Only Chrome and Safari let you do mouse selection of elements while in debugger mode though, so in Edge or Firefox, you might have to do the drilling through the Elements tab to find what you need manually.


Set a Timed Debugger To Web Inspect Hard-To-Grab Elements is a post from CSS-Tricks

Source: Set a Timed Debugger To Web Inspect Hard-To-Grab Elements


CSS

The following is a guest post by Jan Östlund. Jan is the creator of the GitFTP-Deploy, now at v2.0. He wrote to me about GitFTP-Deploy, and I thought it was pretty cool. As you’ll learn in this post, it’s macOS Git-based deployment software. I think it’s worth knowing about as it sits nicely between free (and usually a bit more complex) roll-your-own solutions, and solutions with monthly or yearly subscription costs. GitFTP-Deply is a flat cost. This is slightly tricky territory, as it’s advertorial in nature. So full disclosure: Jan didn’t pay for this, but I opted to use affiliate links.

Let’s set the scene. Say you are a web freelancer and are almost finished with a client’s new website. Over the years, you have learned the hard way not to edit the files directly over FTP. It’s too easy to make breaking changes with no record of what changed and who did what. Nowadays you are using Git to manage the version of the files.

Why use version control?

There are many benefits of using a version control system for your projects. Even if you’re a very organized person, you still might get confused with a naming system like `index-2017-01-12.html` or `header_image_final_final_v2.svg`. Is it really final? How do you know what exactly is different between these versions and the last?

A version control system (VCS, like Git) enforce that there is only one version of your files at any given time. All past versions of files are neatly packed up inside the VCS. When you need it, you can request any version at any time, and you’ll have a snapshot of the complete project at hand.

Every time you save a new version of your project, your VCS requires you to provide a short description of the changes. Additionally (if it’s a code/text file), you can see exactly what has been modified in the file’s content. The VCS helps you understand how your project evolved between versions.

Deployment / Uploading

As useful as a VCS is, it doesn’t directly help with uploading files to a live website. (We’ll refer to that as deployment.)

Deploying files can be very easy. Use an FTP client (e.g. Transmit) to upload files via FTP or SFTP straight to your server. The initial release of a site is especially easy: just upload all the files.

When you make changes to a site, you also need to upload files. But… which ones? Do you always remember which files you have changed? If your panicked client calls to tell you that the site is broken, do you know what changed the last few times you uploaded files?

If you are using Git, it’s easy to see. But still, Git doesn’t do deployment, and manually checking which files have changed and moving those is error prone and tedious. You still need a smart way to upload and deploy your changed files only.

So what other options do you have for deploying files? One option is also installing Git on the server. Then just like you push and pull from your Git repository locally, you can pull from that repository on the server and the server will pull down the latest changes. This isn’t an option for everyone, though. It will require shell access to the server and that just isn’t possible on many shared hosting solutions.

Another possibility is to rely on third-party cloud services like DeployBot, Springloops, or Beanstalk. None of these choices are bad, but there are potential downsides:

  • There are monthly or annual costs to these services, whether you are actively using them at the moment or not.
  • Setting up external Git repositories may take some time and can be complicated.
  • There is also the increased risk of relying on a third party service. The deployment service can be down at the moment you want to deploy.
  • The speed of the deployment is dependent on that service. There may be a long queue of other deployments before yours.

A Look at GitFTP-Deploy

Let’s take a look at my alternative: GitFTP-Deploy. GitFTP-Deploy is a native macOS app that only uploads the changed files (through SFTP, FTP or FTPS) since the last deployment. You don’t have to remember which files you have changed, added, or deleted.

Since GitFTP-Deploy reads what have changed from your local Git repository, you also get in the habit of using a Git for your project: once a file is committed, it’s also ready for deployment.

Another feature which could ease up your deployment is GitFTP-Deploy’s ability to run pre- and post-deployment scripts. Are you using a JavaScript compiler (like Babel) or CSS preprocessor (like Stylus)? Are you concatenating and compressing assets? Running these tasks can be make automatic by the app.

Other times it can be a real time saver just to commit the last changes, and it’s automatically pushed onto the server, just with a single Git commit command.

Getting started

In less than two minutes you can start to deploy your files.

1) Create a new site

2) Point to your local repository and select which commit you want to start deploying from

3) Setup your server connection

4) Click Deploy

Maybe your workflow is a bit more complicated? You need more power?

You can specify scripts to be run both locally and on your server, before and after uploads. For example, before uploading, you may want to run your favorite JavaScript compiler or a Gulp script that concatenates and optimizes your JavaScript files for production.

Or perhaps you are using a workflow with another task runner like Grunt? Grunt can also be configured to help you with optimizing images, compressing scripts, compiling preprocessors, and countless other things.

Running gulp --production

The ability to run tasks can be quite powerful. For example, even WordPress has WP-CLI, meaning you could script out things like database syncing and settings updates with your deployment.

Other Notes on Usage

If you prefer not to have build files under version control, you can add this folder to “always upload”.

Using GitFTP–Deploy does not mean that you cannot use GitHub or another third-party hosted Git repository service. Just make sure to pull the changes from there before deploying.

Team Usage

While GitFTP–Deploy is not exactly built for teams, you can still use it. The easiest way it that one person handles the deployments. Another more advanced option is to run GitFTP-Deploy on a server.

This way may not work for large teams, and commits are done through many different individuals. However, GitFTP-Deploy will attempt to check which branch and commit that which was last deployed.


GitFTP-Deploy is a post from CSS-Tricks

Source: GitFTP-Deploy

1 2 3 30