Month: December 2019

Wufoo + Zapier

Wufoo has always been great with integrations. They have integrations with specific apps, like Campaign Monitor, Mailchimp, and Typekit, but they also integrate with Zapier, which is sort of like an integration inside an integration.

That’s kinda meta, but the idea is actually pretty straightforward: Wufoo integrates with Zapier, which integrates with a gazillion (yes, I did the math) other apps. That opens up a whole world of possibilities for what you can do with a Wufoo form.

Some interesting ones:

  • Trigger an email to send to someone from Campaign Monitor or Mailchimp when they’ve submitted the form.
  • Collect submissions in a Google Sheet to build you own database of entries.
  • Automatically create a card in Trello once the form has been submitted.
  • Add the person who is submitting the form to a contact list in Salesforce.
  • Push notifications to Slack once someone completes the form.

Wufoo shared their own list of ideas. Let’s sum them up here:

  • Wufoo + your customer relationship management (CRM) tool
  • Wufoo + your email tool
  • Wufoo + your file storage tool
  • Wufoo + your website-building tool
  • Wufoo + your project management tool
  • Wufoo + your calendar tool
  • Wufoo + your spreadsheet tool

That one about website-building tools is pretty sweet. This lets Wufoo hook up to something, say WordPress, so that you can do something like publish a new page for every submission. Think about that. You have one integration to send an email to the user when they submit the form and perhaps it contains a link to a personalized page. Voltron powers, unite!

The post Wufoo + Zapier appeared first on CSS-Tricks.

CSS-Tricks

,

A Use Case for a Parent Selector

Having a “parent selector” in CSS is mentioned regularly as something CSS could really use. I feel like I’ve had that thought plenty of times myself, but then when I ask my brain for a use case, I find it hard to think of one. Well, I just had one so I thought I’d document it here.

A classic parent/child:

<div class="parent">   <div class="child"></div> </div>

Say it makes a lot of sense for this parent to have hidden overflow and also for the child to use absolute positioning.

.parent {    overflow: hidden;    position: relative; }  .child {    position: absolute;  }

Now let’s say there’s one special circumstance where the child needs to be positioned outside the parent and still be visible. Hidden overflow is still a good default for the vast majority of situations, so it’s best to leave that rule in place, but in this very specific situation, we need to override that overflow.

.special-child {    position: absolute;     bottom: -20px; /* needs to be slightly outside parent */ }  /* Not real, but just to make a point */ .special-child:parent(.parent) {    overflow: visible; }

That selector above is fake but it’s saying, “Select the parent of .special-child,” which would allow that override as needed. Maybe it’s like this:

.parent < .special-child {  }

…which is selecting the element on the left rather than the right. Who knows? Probably both of those are problematic somehow and the final syntax would be something else. Or maybe we’ll never get it. I have no idea. Just documenting a real use case I had.

You might be thinking, “Why not just use another special class on the parent?” I would have, but the parent was being injected by a third-party library through an API that did not offer to add a class of my choosing on it. Ultimately, I did have to add the class to the parent by writing some custom JavaScript that queried the DOM to find the .special-child, find the parent, then add the class there.

Do y’all have some other use-cases for a parent selector?

The post A Use Case for a Parent Selector appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Embedded Content in Markdown

Markdown supports HTML, so if you need to, say, embed a YouTube video, you can just copy and paste the embed code from them, drop it into a Markdown document, and you should be good to go. With YouTube specifically, there are other options. But in general, you don’t need to do anything special to embed third-party media in Markdown.

You do need to do whatever is necessary for that particular service though. For example, on CodePen, you visit any particular Pen to get the embed code, click “Embed” in the footer, choose options, and ultimately get the embed code. On Twitter, you click a down arrow thingy and choose Embed Tweet, then get forwarded to some other website where you choose options and ultimately get the embed code. It’s different on every service.

That’s the spirit behind gatsby-remark-embedder from Michaël De Boey, which I recently saw. It spells this out:

Trying to embed well known services (like CodePen, CodeSandbox, Slides, SoundCloud, Spotify, Twitter or YouTube) into your Gatsby website can be hard, since you have to know how this needs to be done for all of these different services.

So what this plugin does is allows you to drop a URL to the thing you’re trying to embed on its own line, and it’s magically transformed into embed code. For example, you put a URL to a Pen like this:

https://codepen.io/Coderesting/pen/yLyaJMz

…and you get:

<iframe   src="https://codepen.io/team/codepen/embed/preview/PNaGbb"   style="width:100%; height:300px;" ></iframe>

…by the time the content makes its way to the DOM.

As an owner of CodePen, I can’t help but to remind you that doing it this way means you can’t take advantage of having a theme or making it editable. But hey, I get it.

What I think is a smidge funny is that… this is exactly what oEmbed is. The whole spirit of oEmbed is, “Put a URL to a thing on its own line and we’ll try to make it into an embed for you.” It’s a clearly defined spec and there is a clear source of data of sites that support the feature.

But I suppose it’s a failing of oEmbed that people either don’t know about it or don’t use it. Even Embedly seems kinda dead-ish?

The post Embedded Content in Markdown appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

A CSS Tribute to SVG

This demo from Jérémie Patonnier is incredible. Make sure to look at it in Firefox because some Chrome bug apparently prevents the entire thing from working.

The big idea is that the entire demo is one <rect> element. That’s it. It is duplicated with <use> elements when needed, and each individual duplication is styled via CSS, which can control stuff like stroke, fill, x, y, etc.

Direct Link to ArticlePermalink

The post A CSS Tribute to SVG appeared first on CSS-Tricks.

CSS-Tricks

[Top]

Gatsby and WordPress

Gatsby and WordPress is an interesting combo to watch. On one hand, it makes perfect sense. Gatsby can suck up data from anywhere, and with WordPress having a native REST API, it makes for a good pairing. Of course Gatsby has a first-class plugin for sourcing data from WordPress that even supports data from popular plugins like Advanced Custom Fields.

On the other hand, Gatsby is such a part of the JAMstack world that combining it with something as non-JAMstack-y as WordPress feels funny.

Here’s some random thoughts and observations I have about this pairing.

  • Markus says this combination allowed him to “find joy again” in WordPress development.
  • A world in which you get to build a WordPress site but get to host it on Netlify, with all their fancy developer features (e.g. build previews), is certainly appealing.
  • Scott Bolinger has a five-minute tour of his own site, with the twist of some of the pages can be statically-built, and other parts dynamically loaded.
  • There is a GraphQL plugin for WordPress, which I suppose would be an alternate way to yank data in a Gatsby-friendly way. Jason Bahl, the wp-graphql guy, literally works for Gatsby now and has “Development sponsored by Gatsby” as the plugin’s Twitter bio. It’s unclear if this will be the default future way to integrate Gatsby and WordPress. I sort of suspect not, just because the REST API requires no additional plugin and the GraphQL plugin takes a little work to install. Anecdotally, just installing it and activating it triggers a fatal error on my site, so I’ll need to work with my host on that at some point because I’d love to have it installed.
  • We see big tutorial series on the subject, like Tim Smith’s How To Build a Blog with WordPress and Gatsby.js.
  • Getting a WordPress site on static hosting seems like a big opportunity that is barely being tapped. Gatsby is just an early player here and is focused on re-building your site the React way. But there are other tools like WP2Static that claim to export a static version of your WordPress site-as is then upload the output to a static host. Ashley Williams and Kristian Freeman get into that in this video (starting about 20 minutes in) and host the result on a Cloudflare Workers site.

The post Gatsby and WordPress appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Making Room for Variation

Say you have a design system and you’re having a moment where it doesn’t have what you need. You need to diverge and create something new. Yesenia Perez-Cruz categorizes these moments from essentially ooops to niiice:

There are three kinds of deviations that come up in a design
system:

  • Unintentional divergence typically happens when designers can’t find the information they’re looking for. They may not know that a certain solution exists within a system, so they create their own style. Clear, easy-to-find documentation and usage guidelines can help your team avoid unintentional variation.
  • Intentional but unnecessary divergence usually results from designers not wanting to feel constrained by the system, or believing they have a better solution. Making sure your team knows how to push back on and contribute to the system can help mitigate this kind of variation.
  • Intentional, meaningful divergence is the goal of an expressive design system. In this case, the divergence is meaningful because it solves a very specific user problem that no existing pattern solves.

We want to enable intentional, meaningful variation.

This is an excerpt from her book Expressive Design Systems on A Book Apart, the same publishers as the incredible iconic book Practical SVG.

And while we’re linking up books about design systems, check out Andrew Couldwell’s Laying the Foundations.

System design is not a scary thing — this book aims to dispel that myth. It covers what design systems are, why they are important, and how to get stakeholder buy-in to create one. It introduces you to a simple model, and two very different approaches to creating a design system. What’s unique about this book is its focus on the importance of brand in design systems and creating documentation.

Direct Link to ArticlePermalink

The post Making Room for Variation appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

One Way to Break Users Out of the Habit of Reloading Too Much

Page reloads are a thing. Sometimes we refresh a page when we think it’s unresponsive, or believe that new content is available. Sometimes we’re just mad at the dang site and rage-refresh to let it know we’re displeased.

Wouldn’t be nice to know when a user refreshes the page? Not just that, but how many times? That data can help us trigger some sort of behavior after a certain number of reloads.

A sports site is a good example. If I want to check the score of a game that’s in progress but the scores aren’t live-updated, then I might find myself refreshing a bunch.

Our goal is to break users out of that habit. We’ll use our page-refresh-counting powers to let folks know that refreshes are unnecessary, thanks to real-time score updates. And if they reload more than three times? We’ll kick ‘em out of their session. That’ll show them.

Here’s a simple demo of that concept.

Let’s re-create it together. But before we get going, there are few questions we need to answer before we start coding:

  • How can we persist the number of times user reloaded the site? We need a place to keep the number of times user reloaded the site (reloadCount), this place needs to persist that value between the reloads — localStorage sounds like a good solution.
  • How do we detect if user reloaded the site or just came back after few hours? If we store the reloadCount in localStorage it will persist the value between the reloads, but it will keep that value until we remove programmatically or clear the browser storage. It means that if we come back after few hours the site will still remember last reloadCount and may perform logout after first refresh without warning. We want to avoid that and allow user to reload the site two times each time the user comes back after some period of time. That last sentence holds the answer to the question. We need to store the time when the user left the site and then when the site loads again check when that happened. If that time period wasn’t long enough, we activate the reload counting logic.
  • How do we know when the user leaves the site? To store that time, we use beforeunload window event and store that value in localStorage.

OK, now that we have the answers, let’s dive into the code.

Step 1: We’ve gotta store the last reload time

We will store the time of last reload using a beforeunload window event. We need two things: (1) an event listener that will listen to the event and fire the appropriate method, and (2) our beforeUnloadHandler method.

First, let’s create a function called initializeReloadCount that will set our event listener using the addEventListener method on the window object.

function initializeReloadCount() {   window.addEventListener("beforeunload", beforeUnloadHandler) }

Then we create a second method that will be fired before we leave the site. This method will save the time the refresh happens in localStorage.

function beforeUnloadHandler() {   localStorage.setItem("lastUnloadAt", Math.floor(Date.now() / 1000))   window.removeEventListener("beforeunload", beforeUnloadHandler); }

Step 2: We need a way to handle and store the reload count

Now that we have the time when the site was last closed, we can proceed and implement logic that’s responsible for detecting and counting how many times the site was reloaded. We need a variable to hold our reloadCount and tell us how many times user reloaded the site.

let reloadCount = null

Then, in our initializeReloadCount function, we need to do two things:

  1. Check if we already have a reloadCount value stored in our localStorage, and if so, get that value and save it in our reloadCount. If the value doesn’t exist, it means that the user loaded the site for the first time (or at least did not reload it). In that case, we set the reloadCount to zero and save that value to localStorage.
  2. Detect if the site was reloaded or the user came back to the site after longer period of time. This is the place where we need our lastUnloadAt value. To detect if the site was actually reloaded, we need to compare the time when the site gets loaded (the current time) with the lastUnloadAt value. If those two happened within, say, five seconds (which is totally arbitrary), that means the user reloaded the site and we should run reload count logic. If the time period between those two events is longer, we reset the reloadCount value.

With that, let’s create a new function called checkReload and keep that logic there.

function checkReload() {   if (localStorage.getItem("reloadCount")) {     reloadCount = parseInt(localStorage.getItem("reloadCount"))   } else {     reloadCount = 0     localStorage.setItem("reloadCount", reloadCount)   }   if (     Math.floor(Date.now() / 1000) - localStorage.getItem("lastUnloadAt") <     5   ) {     onReloadDetected()   } else {     reloadCount = 0;     localStorage.setItem("reloadCount", reloadCount)   } }

The last function we need in this step is a method responsible for what happens when we confirm that the user reloaded the site. We call that function onReloadDetected, and inside it, we increment the value of reloadCount. If the user refreshed the site third time, we drop the bomb and call our logout logic.

function onReloadDetected() {   reloadCount = reloadCount + 1   localStorage.setItem("reloadCount", reloadCount)   if (reloadCount === 3) {     logout()   } }

Step 3: “Dear user, why you didn’t listen?!”

In this step, we implement the logic responsible for the situation when the user reloads the site to the point of breaching our three-limit threshold, despite our clear warnings to stop doing it.

When that happens, we call our API to log the user out, then we clean up all properties related to the reload count logic. That will allow the user to come back and have a clean account of reloads. We can also redirect the user somewhere useful, like the login screen. (But wouldn’t it be funny to send them here instead?)

function logout(params) {   // logout API call   resetReloadCount() }  function resetReloadCount() {   window.removeEventListener("beforeunload", beforeUnloadHandler)   localStorage.removeItem("lastUnloadAt")   localStorage.removeItem("reloadCount"); }

Bonus: Let’s re-Vue it!

Now that we have the logic implemented, let’s see how can move that logic to a Vue site based on this example:

First, we need to move all of our variables into our component’s data, which is where all reactive props live.

export default {   data() {     return {       reloadCount: 0,       warningMessages: [...]     }   },

Then we move all our functions to methods.

// ...   methods: {     beforeUnloadHandler() {...},     checkReload() {...},     logout() {...},     onReloadDetected() {...},     resetReloadCount() {...},     initializeReloadCount() {...}   } // ...

Since we are using Vue and its reactivity system, we can drop all direct DOM manipulations (e.g. document.getElementById("app").innerHTML) and depend on our warningMessages data property. To display the proper warning message we need to add a computed property that will re-calculate each time our reloadCount is changed so that we can return a string from our warningMessages.

computed: {   warningMessage() {     return this.warningMessages[this.reloadCount];   } },

Then we can access our computed property directly in the component’s template.

<template>   <div id="app">     <p>{{ warningMessage }}</p>   </div> </template>

Last thing we need to do is find a proper place to activate the reload prevention logic. Vue comes with component lifecycle hooks that are exactly what we need, specifically the created hook. Let’s drop that in.

// ...   created() {     this.initializeReloadCount();   }, // ...

Nice.

Wrapping up

And there it is, the logic that checks and counts how many times a page has been refreshed. I hope you enjoyed the ride and you find this solution useful or at least inspiring to do something better. 🙂

The post One Way to Break Users Out of the Habit of Reloading Too Much appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

What it means to be a front-end developer in 2020 (and beyond)

I wrote a piece for Layout, the blog of my hosting sponsor Flywheel.

Stick around in this field for a while, and you’ll see these libraries, languages, build processes, and heck, even entire philosophies on how best to build websites come and go like a slow tide.​​

You might witness some old-timer waving their fist from time to time, yelling that we should learn from the mistakes of the past. You could also witness some particularly boisterous youth waving their fists just as high, pronouncing the past an irrelevant context and no longer a useful talking point.

​​They’re both right, probably. As long as nobody is being nasty, it’s all part of the flow.

I’ve spent this whole year thinking about how I think the term front-end developer is still pretty meaningful, despite the divide in focus. The widening of the role just brings about more opportunity.

Direct Link to ArticlePermalink

The post What it means to be a front-end developer in 2020 (and beyond) appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

So Many Color Links

There’s been a run of tools, articles, and resources about color lately. Please allow me to close a few tabs by rounding them up here for your enjoyment.

Curated colors in context

Happy Hues demonstrates a bunch of color palettes in the context of the site itself. That’s a nice way to do it, because choosing nice colors isn’t enough — it’s all about context. It can go bad, as the Refactoring UI blog demonstrates.

Dynamic, Date-Based Color with JavaScript, HSL, and CSS Variables

Rob Weychert shows off how he created date-based color schemes (so that every single day of the past 30 years would have a unique color scheme, each day looking slightly different than the day before).

Calculating Color: Dynamic Color Theming with Pure CSS.

Una Kravets creates color themes just with CSS. No JavaScript. No CSS preprocessing. Just Custom Properties, HSL colors, and some calc() in Calculating Color: Dynamic Color Theming with Pure CSS.

Color Tools

We’ve tweeted about color tools a lot. We’ve even threaded them up from time-to-time.

Visualizing Every Pantone Color of the Year

Adam Fuhrer took 20 years of top Pantone colors and matched them with wonderful photos. I love that the photos link to the personal sites of the actual photographers. It weirdly reminds me that you can browse Dribbble by color.

A Handy Sass-Powered Tool for Making Balanced Color Palettes

Stephanie Eckles blogged about using Sass to do math on colors to calculate and graph their luminance, saturation, and lightness, which can give you a by-the-numbers look to see if your color scheme is cohesive or not.

Leonardo

Leonardo is an interactive color palette tool that helps interpolate colors and generate variations based on contrast ratio.

Color Puns

Nice.

The post So Many Color Links appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

7 Uses for CSS Custom Properties

, ,
[Top]