Web Standards

Don’t use empty or low content for your design system grid examples

Css Tricks - Tue, 09/25/2018 - 8:44am

Dave and I had Jen Simmons on ShopTalk the other day. Jen was talking about Intrinsic Web Design and how one of the core tenets of it is grids with rows and columns that don't necessarily change at the same rate or ones that have essentially different rules for how they behave.

For example, take this (contrived) grid setup:

.grid { display: grid; grid-template-columns: 1fr minmax(50px, 100px) 20% auto; }

Each of those columns will behave differently.

I'm just wrapping my head about this, and definitely don't fully understand it. Here's what it seems like to me, numbered 1-4 based on the "strength" (I guess?) of the width.

.grid { display: grid; grid-template-columns: 1fr /* #4 - Weakest, will fill remaining space */ minmax(50px, 100px) /* #3 - Will only start changing when other columns force it */ 20% /* #1 - Definite size, steady */ auto /* #2 - Indefinite size, entirely based on content, pushy */ ; }

This is much different from quite a long history of how we've set up grid columns in the past. Float-based grids typically use percentages (a definite size) to set columns. Same with inline-block-based grids, typically.

Even with grid, if you set up all your columns with all percentages or all fractional units, you'd likely have a steady grid in which the content inside won't mess with sizing. But Jen is saying that it's interesting to have a grids where the content has a say in how they size. Embrace it. Sounds fun to me.

But anyway, say you're setting up a grid that uses mixed values for column widths like this. Don't do that with totally empty columns, otherwise, you'll get a false sense of how those columns will behave.

Just look at this demo where these four grids have the exact same setup and all that is different is the amount of text in each column.

See the Pen Different Collapse Rates of Different Column Width Values by Chris Coyier (@chriscoyier) on CodePen.

Cool'n'weird.

The post Don’t use empty or low content for your design system grid examples appeared first on CSS-Tricks.

Putting things on top of other things

Css Tricks - Tue, 09/25/2018 - 7:09am

A plain-language romp through the trials and tribulations of z-indexby Isabel Brison. On the surface, z-index seems simple. It's a number and it represents what is on top of what... assuming it is positioned... and assuming it is within the same stacking context as the other things.

... that is the gist of it: stacking contexts are caused by a variety of properties and the main reasons for their existence are performance concerns and ease of implementation by browsers. They are not always related to z-index or ordering; they pop up wherever it makes sense to have several elements all on the same layer for rendering purposes.

Direct Link to ArticlePermalink

The post Putting things on top of other things appeared first on CSS-Tricks.

The Complete Guide to Lazy Loading Images

Css Tricks - Tue, 09/25/2018 - 4:32am

Images are critical. Whether it is marketing banners, product images or logos, it is impossible to imagine a website without images. Sadly though, images are often heavy files making them the single biggest contributor to the page bloat. According the HTTP Archive’s State of Images report, the median page size on desktops is 1511 KB and images account for nearly 45% (650 KB) of that total.

That said, it’s not like we can simply do away with images. They’re too important to the overall user experience. Instead, we need to make our web pages load really fast with them. In this guide, we will cover all of the ins and outs of lazy loading images, a technique that helps improve the time it takes for a web page to load by deferring image loads until they are needed.

Before we dive right in, here is a sample video that demonstrates the concept. In short, a gray placeholder box is rendered on the page until it scrolls into view—at which point the actual image loads in place of the box.

Chapter 1: What is Lazy Loading?

We often associate the word “lazy" with avoiding work as long as possible, or the sheer act of wanting to do nothing at all.

Similarly, lazy loading defers the loading of resources on the page as long as they are not needed. Instead of loading them right away, which is what normally happens, we allow them to load later.

Lazy Loading is a set of techniques in web and application development that defers the loading of resources on a page to a later point in time—when those resources are actually needed instead of loading them up front. These techniques help in improving performance, better utilization of the device’s resources and reducing associated costs.

The technique of lazy loading can be applied to just about any resources on a page. For example, even a JavaScript file can be held back if it is best not to load it initially. Same deal for an image—load it when we need it.

We will stick to lazy loading images in this guide, but it’s good to know it can be applied to other assets.

Chapter 2: Why Lazy Load at All?

If the user never scrolls to the point of the page that contains the image, then the user will never see that image. It also never loads in the first place because, hey, it was never needed.

You may already start to see how this benefits both you and the user. Here are two of the advantages we get with lazy loading.

Performance Gains

The obvious benefit is that we get smaller web pages that load faster. Lazy loading reduces the number of images that need to be loaded on a page up front. Fewer image requests mean fewer bytes to download. And fewer bytes to download means the page renders faster than if those bytes and requests were being made.

This ensures that any device on any network is able to download and process the remaining resources much faster. Hence, the time from request to render becomes smaller and the page becomes usable much earlier. Win-win!

Cost reduction

The second benefit is for you as a website administrator. Cloud hosting services, like Content Delivery Networks (CDNs) or web servers or storages, deliver images (or any asset for that matter) at a cost based on the number of bytes transferred. A lazy loaded image may never get loaded if the user never reaches it. Thus, you may reduce the total bytes delivered on the page and ultimately save yourself a few pennies in the process. This is especially true for users that instantly bounce off a page or interact only with the top portion of the content.

The reduction in bytes transferred from your delivery network or server reduces delivery costs. This will become more apparent as we explore lazy loading in the coming sections.

Just how much will you save? You can find out which images are a candidate for lazy loading and how many bytes you can save on the initial page load by using the Google Lighthouse audit tool. This has a section dedicated for offscreen images. You can also use ImageKit’s website analyzer to identify if your website uses lazy loading or not apart from other critical image related optimizations on your page.

Lazy loading is critical not only to good performance but also to deliver a good user experience. Since combining performance and user experience with lazy loading is important and challenging, we will continue to address this topic in more detail throughout this guide after we have looked at different ways to lazy load images.

Chapter 3: Lazy Loading Techniques for Images

There are two common ways that we load images to a page: the <img> tag and the CSS background-image property. We will first look at the more common of the two, the <img> tag and then move to CSS background images.

Lazy loading images in an image tag

Let’s start with the typical HTML markup for an image:

<img src="/path/to/some/image.jpg" />

The markup for lazy loading images is pretty similar.

Step one is to prevent the image load up front. The browser uses the src attribute of the tag to trigger the image load. It doesn’t matter if it is the first or the 1,000th image in your HTML. If the browser gets the src attribute, it will trigger the image to be downloaded, regardless of whether it is in or out of current view.

To defer the load, put the image URL in an attribute other than src. Let’s say we specify the image URL in the data-src attribute of the image tag. Now that src is empty and the browser won’t trigger the image load:

<img data-src="https://ik.imagekit.io/demo/default-image.jpg" />

Now that we’re preventing the image from loading, we need to tell the browser when to load it. Otherwise, it will never happen. For this, we check that as soon as the image (i.e. its placeholder) enters the viewport, we trigger the load.

There are two ways to check when an image enters the viewport. Let’s look at both of them with working code samples.

Method 1: Trigger the image load using Javascript events

This technique uses event listeners on the scroll, resize and orientationChange events in the browser. The scroll event is pretty clear cut because it watches where the user is on a page as scrolling occurs. The resize and orientationChange events are equally important. The resize event occurs when the browser window size changes, whereas orientationChange gets triggered when the device is rotated from landscape to portrait, or vice versa.

We can use these three events to recognize a change in the screen and determine the number of images that become visible on the screen and trigger them to load accordingly.

When any of these events occur, we find all the images on the page that are deferred and, from these images, we check which ones are currently in the viewport. This is done using an image’s top offset, the current document top position, and window height. If an image has entered the viewport, we pick the URL from the data-src attribute and move it to the src attribute and the image will load as a result.

Note that we will ask JavaScript to select images that contain a lazy class. Once the image has loaded, we’ll remove the class because it no longer needs to trigger an event. And, once all the images are loaded, we remove the event listeners as well.

When we scroll, the scroll event triggers multiple times rapidly. Thus, for performance, we are adding a small timeout to our script that throttles the lazy loading function execution so it doesn’t block other tasks running in the same thread in the browser.

Here is a working example of this approach.

See the Pen Lazy loading images using event handlers - example code by ImageKit.io (@imagekit_io) on CodePen.

Note that the first three images in this example are loaded up front. The URL is present directly in the src attribute instead of the data-src attribute. This is essential for a good user experience. Since these images are at the top of the page, they should be made visible as soon as possible. There’s no need to wait for JavaScript to load them.

Method 2: Trigger the image load using the Intersection Observer API

The Intersection Observer API is relatively new. It makes it simple to detect when an element enters the viewport and take an action when it does. In the previous method, we had to bind events, keep performance in mind and implement a way to calculate if the element was in the viewport or not. The Intersection Observer API removes all that overhead by avoiding the math and delivering great performance out of the box.

Below is an example using the API to lazy load images. We attach the observer on all the images to be lazy loaded. Once the API detects that the element has entered the viewport, using the isIntersecting property, we pick the URL from the data-src attribute and move it to the src attribute for the browser to trigger the image load. Once this is done, we remove the lazy class from the image and also remove the observer from that image.

See the Pen Lazy loading images using IntersectionObserver - example code by ImageKit.io (@imagekit_io) on CodePen.

If you compare the image loading times for the two methods (event listeners vs. Intersection Observer), you will find that images load much faster using the Intersection Observer API and that the action is triggered quicker as well— and yet the site doesn’t appear sluggish at all, even in the process of scrolling. In the method involving event listeners, we had to add a timeout to make it performant, which has a slightly negative impact on the user experience as the image load is triggered with a slight delay.

However, like any new feature, the support for Intersection Observer API is not available across all browsers.

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

DesktopChromeOperaFirefoxIEEdgeSafari584555No16NoMobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid FirefoxNo46No676962

So, we need to fall back to the event listener method in browsers where the Intersection Observer API is not supported. We have taken this into account in the example above.

Chapter 4: Lazy Loading CSS Background Images

A common background image in CSS:

.my-class { background-image: url('/path/to/some/image.jpg'); /* more styles */ }

CSS background images are not as straightforward as the image tag. To load them, the browser needs to build the DOM tree as well as the CSSOM tree to decide if the CSS style applies to a DOM node in the current document. If the CSS rule specifying the background image does not apply to an element in the document, then the browser does not load the background image. If the CSS rule is applicable to an element in the current document, then the browser loads the image.

Huh? This may seem complex at first, but this same behavior forms the basis of the technique for lazy loading background images. Simply put, we trick the browser into not applying the background-image CSS property to an element, till that element comes into the viewport.

Here is a working example that lazy loads a CSS background image.

See the Pen Lazy Loading background images in CSS by ImageKit.io (@imagekit_io) on CodePen.

One thing to note here is that the JavaScript code for lazy loading is still the same. We are still using the Intersection Observer API method with a fallback to the event listeners. The “trick" lies in the CSS.

We have an element with ID bg-image that has a background-image. However, when we add the lazy class to the element, we can override the background-image property by setting the value of it to none in the CSS.

Since an element with an ID and a class has higher specificity in CSS than an ID alone, the browser applies the property background-image: none to the element initially. When we scroll down, the Intersection Observer API (or event listeners, depending on which method you choose) detects that the image is in the viewport, it removes the lazy class from the element. This changes the applicable CSS and applies the actual background-image property to the element, triggering the load of the background image.

Chapter 5: Creating a Better User Experience With Lazy Loading

Lazy loading presents a great performance benefit. For an e-commerce company that loads hundreds of product images on a page, lazy loading can provide a significant improvement in initial page loads while decreasing bandwidth consumption.

However, a lot of companies do not opt for lazy loading because they believe it goes against delivering a great user experience?(i.e. the initial placeholder is ugly, the load times are slow etc.).

In this section, we will try to solve some concerns around user experience with lazy loading of images.

Tip 1. Use the Right Placeholder

A placeholder is what appears in the container until the actual image is loaded. Normally, we see developers using a solid color placeholder for images or a single image as a placeholder for all images.

The examples we’ve looked at so far have used a similar approach: a box with a solid light gray background. However, we can do better to provide a more pleasing user experience. Below are some two examples of using better placeholders for our images.

Dominant Color Placeholder

Instead of using a fixed color for the image placeholder, we find the dominant color from the original image and use that as a placeholder. This technique has been used for quite some time by Google in its image search results as well as by Pinterest in its grid design.

Pinterest uses the dominant color of the image as the background color for image placeholders.

This might look complex to achieve, but a very simple way of accomplishing this is to scale down the image to down to a 1×1 pixel and then scale it up to the size of the placeholder—a very rough approximation but a simple, no-fuss way to get a single dominant color. Using ImageKit, the dominant color placeholder can be obtained using a chained transform in ImageKit as shown below.

<!-- Original image at 400x300 --> <img src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300" alt="original image" /> <!-- Dominant color image with same dimensions --> <img src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-1,h-1:w-400,h-300" alt="dominant color placeholder" />

The placeholder image is just 661 bytes in size compared to the original image that is 12700 bytes—19x smaller. And it provides a nicer transition experience from placeholder to the actual image.

Here is a video demonstrating how this effect works for the user.

See the Pen Dominant color placeholder - Lazy loading images using IntersectionObserver - example code by ImageKit.io (@imagekit_io) on CodePen.

Low Quality Image Placeholder (LQIP)

We can extend the above idea of using a dominant color placeholder further. Instead of using a single color, we use a very low-quality, blurred version of the original image as the placeholder. Not only does it look good, but it also gives the user some idea about what the actual image looks like and the perception that the image load is in progress. This is great for improving the perceived loading experience. This technique has been utilized by the likes of Facebook and Medium.

LQIP image URL example using ImageKit:

<!-- Original image at 400x300 --> <img src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300" alt="original image" /> <!-- Low quality image placeholder with same dimensions --> <img src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300,bl-30,q-50" alt="dominant color placeholder" />

The LQIP is 1300 bytes in size, still almost 10x smaller than the original image and a significant improvement in terms of visual experience over any other placeholder technique.

Here is a video demonstrating how this effect works for the user.

See the Pen LQIP placeholder - Lazy loading images using IntersectionObserver - example code by ImageKit.io (@imagekit_io) on CodePen.

It is clear that using either dominant color or LQIP placeholders provides a smoother transition from the placeholder to the actual image, gives the user an idea of what is to come in place of that placeholder, and improves loading perception.

Tip 2: Add Buffer Time for Images to Load

When we discussed different methods to trigger image loads, we checked for the point of time where the image enters the viewport, i.e. the image load is triggered when the top edge of the image placeholder coincides with the bottom edge of the viewport.

The problem with this is that users might scroll really fast through the page and the image will need some time to load and appear on the screen. Combined with throttling possibly further delaying the load, the user may wind up waiting a few milliseconds longer for the image to show up. Not great for user experience!

While we can get a pretty good user experience using the Intersection Observer API for performance and LQIP for smoother transitions, there is another simple trick that you can use to ensure that the images are always loaded completely when they enter the viewport?: introduce a margin to the trigger point for images.

Instead of loading the image exactly when it enters the viewport, load it when it’s, let’s say, 500px before it enters the viewport. This provides additional time, between the load trigger and the actual entry in the viewport, for the images to load.

With the Intersection Observer API, you can use the root parameter along with the rootMargin parameter (works as standard CSS margin rule), to increase the effective bounding box that is considered to find the intersection. With the event listener method, instead of checking for the difference between the image edge and the viewport edge to be 0, we can use a positive number to add some threshold.

See the Pen Lazy loading images with additional threshold - example code by ImageKit.io (@imagekit_io) on CodePen.

If you watch the following screencast closely, you’ll notice that the fifth image in the sequence is loaded when the third image is in view. Similarly, the sixth image is loaded when the fourth is in view, and so on. This way, we are giving sufficient time for the images to load completely and, in most cases, the user won’t see the placeholder at all.

If you didn’t notice earlier, in all our examples, the third image (image3.jpg) is always loaded up front, even though it is outside the viewport. This was also done following the same principal: ?load slightly in advance instead of loading exactly at the threshold for better user experience.

Tip 3: Avoid Content Reflow

This is another trivial point, which if solved, can help maintain a good user experience.

When there is no image, the browser doesn’t know the size it will take up. And if we do not specify it using CSS, then the enclosing container would have no dimensions, i.e. it will be read as 0x0 pixels.

When the image loads, the browser will drop it into the screen and reflow the content to fit it. This sudden change in the layout causes other elements to move around and it is called content reflow, or shifting. Michael Scharnagl goes into great depth explaining how this creates an unpleasant user experience.

This can be avoided by specifying a height and/or width for the enclosing container so that the browser can paint the image container with a known height and width. Later, when the image loads, since the container size is already specified and the image fits into that perfectly, the rest of the content around that container does not move.

Tip 4: Avoid Lazy Loading Every Image

This is a mistake that developers often make because it’s super tempting to think that deferring image loads is good all the time. But, like life itself, it is possible to have too much of a good thing. Lazy loading might reduce the initial page load, but it also might result in a bad user experience if some images are deferred when they should not be.

We can follow some general principles to identify which images should be lazy loaded. For example, any image that is present in the viewport, or at the beginning of the webpage, should probably not be lazy loaded. This applies to any header image, marketing banner, logos, or really anything that the user would see when initially landing on a page. Also, remember that mobile and desktop devices will have different screen sizes and hence a different number of images that will be visible on the screen initially. You’ll want to take the device that’s being used into account and decide which resources to load up front and which to lazy load.

Another example is any image that is even slightly off the viewport in the initial load should not probably not be lazy loaded. This is going by the principle discussed above—load slightly in advance. So, let’s say any image that is 500px or a single scroll from the bottom of the viewport can be loaded up front as well.

One more example is if the page is short. It may be just a single scroll or a couple of scrolls, or perhaps there are less than five images outside the viewport. In these cases, you can probably leave lazy loading out altogether. It would not provide any significant benefit to the end user in terms of performance and the additional JavaScript that you load on the page to enable lazy loading will offset any potential gain you get from it.

Chapter 5: Lazy Loading’s Dependency on JavaScript

The entire idea of lazy loading is dependent on JavaScript being enabled and available in the user’s browser. While most of your users will likely have JavaScript enabled, it is essential to plan for cases where it is not.

You could either show a message telling users why the images won’t load and encourage them to either use a modern browser or enable JavaScript.

Another route is to use the noscript tag. However, this approach comes with some gotchas. This question thread on Stack Overflow does a great job addressing these concerns and is a recommended read for anyone looking to address this set of users.

Chapter 6: Popular JavaScript Libraries for Lazy Loading

Since environments and implementation details can vary across browsers and devices, you might want to consider a tried and tested library for lazy loading rather than spinning something up from scratch.

Here is a list of popular libraries and platform specific plugins that will allow you to implement lazy loading with minimal effort:

    >Yet Another Lazy Loader: This library uses the Intersection Observer API and falls back to event-based lazy loading for browsers that do not yet support it. This is great for just about any HTML element but unfortunately does not work on background images in CSS. The good news is that it supports IE back to version 11.

  • lazysizes:?This is a very popular library with extensive functionality. It includes support for responsive image srcset and sizes attributes and provides superb performance even though it does not make use of the Intersection Observer API.
  • WordPress A3 Lazy Load: There are plenty of lazy loading WordPress plugins out there, but this one comes with a robust set of features, including a fallback when JavaScript is unavailable.
  • jQuery Lazy: A simple library that uses a jQuery implementation.
  • WeltPixel Lazy Loading Enhanced:?A Magento 2 extension.
  • Magento Lazy Image Loader:?Another Magento extension, for 1.x.
  • Shopify Lazy Image Plugin (paid): Enable lazy loading on a Shopify site.
Chapter 7: Testing Lazy Load

Once you have implemented lazy loading, you will likely want to check that it’s working as intended. The simplest way would be to open up the developer tools in your browser.

From there, go to Network > Images. When you refresh the page for the first time, you should only see loaded images in the list.

Then, as you start scrolling down the page, other image load requests would get triggered and loaded. You can also notice the timings for image load in the waterfall column in this view. It would help you identify image loading issues if any or issues in triggering the image load.

Another way would be to run the Google Chrome Lighthouse audit report on your page after you have implemented the changes and look for suggestions under the “Offscreen images" section.

Conclusion

We have covered a lot of ground about lazy loading images! Lazy loading—if implemented well—can have significant benefits on your site’s performance the loading performance while reducing the overall page size and delivery costs, thanks to deferring unnecessary resources up front.

So, what are you waiting for? Get started with lazy loading images now!

The post The Complete Guide to Lazy Loading Images appeared first on CSS-Tricks.

Give Usability Maintenance A Seat At The Table

Usability Geek - Mon, 09/24/2018 - 8:55am
In user experience, not all tasks are created equal. Think of the tasks you associate with being exciting. Prototyping, designing a user interface, working on a slick product upgrade, and generally,...
Categories: Web Standards

Control the Internet With Chrome Extensions!

Css Tricks - Mon, 09/24/2018 - 4:03am

As a web UI developer and designer, there are countless things to learn and only so many hours in the day. There are topics I’ve purposefully avoided, like mobile and offline application development because, at some point, you have to draw a line somewhere in the millions of shiny new topics and get some work done. One of the areas I’ve avoided in the past is browser extension development. I didn’t understand how they worked, what the development environment was, or how permissions interacted with overriding pages because, frankly, I didn’t think I was interested.

Then one day, my very talented designer/developer friend Natalie Schoch asked me to get her Chrome Extension across the finish line. She had the front-end prototyped, but needed some help plugging in the data set and with interactive JavaScript. The project is called Wordsmith and it’s out now at the Chrome Extension Store. It’s a free and aesthetically pleasing way to learn new vocabulary as you browse the web. The extension surfaces a new vocabulary word, along with its definition and synonyms in each new tab.

Anyway, enough plugging the new thing we made and on to the fun of figuring out Chrome Extensions!

An animation showing how the Wordsmith extension works when you open a new tab in Chrome.

First, what is a Chrome Extension anyway? According to the Chrome developer docs:

Extensions are event based programs used to modify or enhance the Chrome browsing experience. They enable users to tailor Chrome functionality and behavior to individual needs or preferences. They are built on web technologies such as HTML, JavaScript, and CSS.

(Emphasis mine)

Basically, a Chrome Extension is a one-trick pony tool built on top of the normal browsing experience to override a focused set of interactions.

Getting a bare-bones extension up and running

The Chrome docs are mostly straightforward but can get overly complicated for a beginner. The first thing you need to make in your local project directory is a manifest.json file. This file functions as the command center for your extension. This is where you will tell Chrome what files it should be paying attention to and what type of extension logic you are using.

{ “manifest_version”: 2, // Just use 2, it's the stable version you want “name”: “Wordsmith”, // The name of your extension! “description”: “New tab? New word!”, // The description of your extension! “author”: “Natalie Schoch and Lindsay Grizzard”, // Who you are “chrome_url_overrides” : { “newtab”: “newtab.html” } }

Let’s talk about that chrome_url_overrides bit. This is telling Chrome, “Hey, that thing you would normally load (in this case) in a new tab, load this cool thing I made instead.” I recommend starting with a new tab Chrome extension because it is the quickest way to see that you are getting this little extension thing to work. You could also override history or bookmarks, but I’ll let you explore that on your own.

Now we can create a new file called newtab.html:

<!DOCTYPE HTML> <html> <body> <h1> Hey there world </h1> </body> </html>

Great! Now all you have to do is load this into Chrome’s extension developer system to see your beautiful work. To get this up and running, load your project into Chrome’s developer mode with the following steps:

  1. Go to chrome://extensions
  2. Turn on "Developer Mode" in the top right
  3. Click "Load Unpacked"
  4. Load the directory containing your manifest.json and newtab.html files
  5. Open a new tab!

You should see this magic:

You just built a Chrome Extension. Congrats! At this point, you can go on your own adventure and make any static design for a new tab. You can write CSS as you normally would (set up SCSS compiling, script tags, inline if you are a monster, etc…), and create new static things.

The most important thing to remember when changing the manifest.json file or JS files is that you must go back into chrome://extensions and hit the reload icon for your extension. It will not update from your local development automatically and your changes will not be reflected without this step. This confused the heck out of me.

Now let’s talk about JavaScript

There are two types of script files in Chrome Extensions: content scripts and background scripts.

Background scripts are used for handling central application tasks. They can act like a controller for your application, staying dormant until an event fires and unloading after the event completes. Use background scripts when you want to control the core logic of your application or listen for interactions that are outside of the page’s DOM. An example would be clicking your Chrome extension’s icon in the top right of the toolbar. That isn’t part of the page-specific DOM. If you want to manipulate things outside of the sandboxed page you are on, you will need background scripts.

Clicking the icon and having a popup load is an example of a background script command.

As a note, these rely on the Chrome API and are a bit more advanced. In Wordsmith, I decided to forgo background scripts completely as we only needed DOM-specific UI. I found background scripts particularly tricky and got the most help from Daniel Shiffman’s video tutorial. In fact, his whole tutorial series is a lovely introduction to extension development.

Content scripts execute JavaScript in the context of a specific webpage and in isolation. This means each script can access the current DOM and manipulate it, but the DOM and its scripts, cannot manipulate the Chrome extension in return. Content scripts have limited Chrome API access and exist to work in single, isolated instances. This secures extension information and halts library conflicts.

Cool, but what does all that actually mean? It says two things. You can use content scripts to perform regular browser JavaScript, as you would in a simple web application. The isolation definition means your extension’s JavaScript is in it's own universe, separate from any webpage's JavaScript. This keeps things like API secret keys private from page scripts. It also let’s you use any version of a JavaScript library in your extension without worrying about conflicting versions on a given webpage.

The practical difference in using content scripts is how they are loaded. Instead of linking directly to the file in HTML, use the manifest.json file to indicate the scripts you would like to call.

{ “manifest_version”: 2, “name”: “Wordsmith”, “description”: “New tab? New word!” “author”: “Natalie Schoch and Lindsay Grizzard”, “chrome_url_overrides” : { “newtab”: “newtab.html” }, "content_scripts": [ { "matches": [ "<all_urls>" //see all match pattern options in the chrome docs ], "js": ["[your-path-to]/jquery.min.js","[your-path-to]/scripts.js"] } ] }

This new content script command in the manifest.json file tells Chrome a few things. It tells Chrome where you want that file to run with the “matches” statement. Do you want it to load on every single Chrome page? Are you making an extension that should only affect certain pages? To specify this, add the appropriate URL match pattern to tell Chrome what to pay attention to. It also tells the manifest file where to find your content scripts and in what order to execute them.

When changing the manifest.json file or JavaScript files is that you must go back into chrome://extensions and hit the reload icon for your extension.

Add a console.log() to your new script file, reload your extension, navigate to any URL, and you will see your console message. Seeing the console log tells you that you now have access to the DOM and can start manipulating it. CHROME EXTENSIONS ARE SO COOL. You have the power to play around with the front-end of the internet without needing source code or a complex dev environment. Now let’s have some fun by making all the divs on a page red!

$('div').css('background-color','red');

Now, go to another website. Everything is awful and red, but you have so much power! You can manipulate any webpage to do your bidding. Go forth and mold the design of the internet into something better (or worse) for yourself or others!

That’s basically everything you need to know to get started with Chrome Extensions. Although the documentation can be a little foreign at first, start with a simple static new tab extension and iterate from there!

Happy manifest(.json)ing!

Check out Wordsmith’s GitHub repo to see how we built out our first Chrome Extension and feel free to fork and let us know about bugs!

The post Control the Internet With Chrome Extensions! appeared first on CSS-Tricks.

Having fun with link hover effects

Css Tricks - Fri, 09/21/2018 - 4:39am

A designer I work with was presenting comps at a recent team meeting. She had done a wonderful job piecing together the concept for a design system, from components to patterns and everything in between that would make any front-end developer happy.

But there was a teeny tiny detail in her work that caught my eye: the hover state for links was a squiggle.

Default link (top) and hover effect (bottom)

Huh! Not only had I not seen that before, the idea had never even crossed my mind. Turns out there are plenty of instances of it on live sites, one being The Outline. That was the one that was implementation that inspired the design.

Cool, I figured. We can do something like a linear background gradient or even a background image. But! That wasn't the end of the design. Turns out it's animated as well. Again, from The Outline:

Screenshot from The Outline article (source)

Whoa! That's pretty wild. I wasn't sure how to approach that, honestly, because animating any of my initial ideas would be difficult, especially for cross-browser support.

So, how did The Outline do it? Turns out, it's SVG. We can make a squiggly path and animate it pretty easily:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

But how does that work with a link? Well, we can use SVG on the background-image property:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

But that's kinda crappy because we can't really animate that. We need better values for that. However, we can inline CSS directly on the SVG in the background-image property. We can't simply copy and paste the SVG code into the property, but we can with some proper encoding:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

And, since SVG can contain its own styles within the markup, the animation can be tossed right there in the background-image property, the same way we would do it with CSS in an HTML document head or inline CSS in HTML.

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

We can style it up a little differently, if we'd like:

See the Pen Link Effectz - Squiggle by Geoff Graham (@geoffgraham) on CodePen.

This is inspiring!

I have no idea if an animated squiggle makes for a good user experience and, frankly, that's not the point of this post. The point is that The Outline had a fun idea with a slick CSS implementation.

That got me thinking about other non-standard (perhaps even unconventional) hover styling we can do with links. Again, tossing aside usability and have a grand ol' time with CSS...

The Border to Background Effect

Maybe that same bottom border on the default link can grow and become the full background of the link on hover:

See the Pen Link Effectz - Background on hover by Geoff Graham (@geoffgraham) on CodePen.

Heck, we can even do something similar horizontally:

See the Pen Link Effectz - Horizotonal Background by Geoff Graham (@geoffgraham) on CodePen.

The Outlined Text Effect

Let's strip out the font color and leave an outline behind.

See the Pen Link Effectz - Outline on hover by Geoff Graham (@geoffgraham) on CodePen.

The Raised Text Effect

Another idea is to raise the text as if it grows out of the page on hover:

See the Pen Link Effectz - Raised text on hover by Geoff Graham (@geoffgraham) on CodePen.

The Font Swapper-oo Effect

This is so impractical that it makes me LOL, but why not:

See the Pen Link Effectz - Swap font on hover by Geoff Graham (@geoffgraham) on CodePen.

The "Turn it Up, Chris" Effect

Sorry, Chris. You know you love it. ❤️

See the Pen Link Effectz - Turn it up, Chris! by Geoff Graham (@geoffgraham) on CodePen.

What can you come up with?

Have ideas? Let me know in the comments and I'll toss 'em in the CodePen collection I've started.

The post Having fun with link hover effects appeared first on CSS-Tricks.

Safari Ripper ??

Css Tricks - Thu, 09/20/2018 - 8:36am

Security researcher Sabri posted a bit of code that will "force restart any iOS device." It's interesting to see HTML & CSS have this kind of dangerous power. It's essentially a ton of <div>s scaled to be pretty huge and then set over a repeating JPG image with each <div> blurring the background via backdrop-filter. It must cause such extreme and unhandled memory usage that it wreaks havoc on the browser as well as the entire operating system.

I was trying to test it out myself and be really careful not to execute it... but of course I did, and it crashed my Chrome 68 on a MacBook Pro. Not the whole operating system, but I had to force quit the browser. Then again, I suppose even while(true) {} can do that!

The comment thread on the gist hast more interesting details, like how it crashes iOS Safari 9+ (including the new version 12!) and weird behavior on the PlayStation 3 native browser.

Direct Link to ArticlePermalink

The post Safari Ripper ☠️ appeared first on CSS-Tricks.

All Fired Up About Specificity

Css Tricks - Thu, 09/20/2018 - 3:54am

You never know where the next Grand Debate™ in front-end is going to come from! Case in point: we just saw one recently based on a little Twitter poll by Max Stoiber in which 57% of people got it wrong. There were reactions ranging from the innocuous hey fun a little brain teaser! to the state of web education is in shambles and beyond.

I heard from a number of folks that they just felt sad that so many people don't know the answer to a fairly simple question. To be fair, it was (intentionally, I'm sure) rather tricky! It wasn't really a question about CSS — it was more about the idea that the order of HTML attributes doesn't matter. It's the order of CSS that does.

One extreme response I saw said that front-end stuff like this is needlessly complicated and getting it wrong is almost a point of pride. This sentiment was so strong that I heard it suggested that people who know the answer have filled their brains with useless information and that somehow makes them a worse developer. Equally extreme were suggestions that writing HTML and CSS raw like that should always be avoided in favor of tooling abstractions to "fix" these "problems."

(Excuse the quotes there, I'm not trying to pick a side so much as to emphasize that not everyone considers these problems that need to be fixed.)

Another take was that the vibe would be different if something similar happened in JavaScript-land. The perception is that it's embarrassing or bad not to know JavaScript basics, but not knowing HTML and CSS basics is the fault of the language, or that the value of knowing it is not worth bothering to understand.

At the same time, this poll became the perfect mirror to see the strong opinions people have about front-end practices. Fascinating, really.

Here are a few more takes from folks who chimed from their own blogs:

Keith Grant:

I hate that this has somehow become some “old guard” vs. “new guard” thing.

The problem with drawing lines like this: whichever side you find yourself on, there are some whackos out there throwing ridiculous arguments into the mix. And now people on the other side associate that viewpoint with you.

Tim Kadlec:

It doesn’t bother me too much that people are getting the question wrong. Everyone is at different stages in their career and everyone has different problems they’re facing in their daily tasks, so sure, not everyone is going to know this yet.

I do find it a bit alarming just how many folks got it wrong though.

John Allsopp:

One the one hand (and this will somewhat simplify each ‘side’, for the sake of brevity, not disrespect to either), we have those, and I’d on balance probably include myself in this camp, who’d argue that the core technologies of the Web are precisely that–foundational, and a deep understanding of them conceptually (not necessarily an encyclopedic knowledge of every syntactic aspect) is fundamental working knowledge for professional Web developers.

Kevin Ball:

With the growth of the importance of front-end development, we're seeing the story play out again.

The systematic devaluation of CSS, and more, the people who use CSS.

The constant "mansplaining" of CSS features to women who literally are the reason it exists.

Conference speakers asked questions about whether "there is any value in people who cannot write JavaScript?".

All of this at a time when CSS is improving faster than ever and enabling dramatic changes in web design.

This isn't about better technology, it's about exclusion.

Have you seen any other takes or have any of your own?

The post All Fired Up About Specificity appeared first on CSS-Tricks.

Introducing the YOOtheme Pro Page Builder

Css Tricks - Thu, 09/20/2018 - 3:50am

(This is a sponsored post.)

YOOtheme Pro is a powerful theme and page builder developed by YOOtheme that provides a new experience of building websites in WordPress. Designers will get an easy and exciting way to design and create websites due to premium layouts and an intuitive page builder, and developers will especially appreciate its extendability and clean and semantic code. YOOtheme has been known as a leading theme provider for over 10 years, and now with YOOtheme Pro they created the next page builder to be watched for on the WordPress market.

The Page Builder

If you are familiar with WordPress, YOOtheme Pro is a perfect choice for you since it is seamlessly integrated into the native WordPress customizer. You can easily create your layouts by dividing your content into sections, rows and grids. And thanks to the drag and drop interface, you can design beautiful responsive page layouts without even having to code. All your changes will be instantly shown in live preview.

Arrange Your Content With Ease

YOOtheme Pro has a growing library of over 30 content elements. Here you can find both common elements like the Video, Panel, Image or Heading, but you can also expect some advanced elements such as the Slider, Slideshow or Gallery with the masonry effect and filter option and even more. YOOtheme Pro also allows you to place WordPress widgets anywhere in your layout. All elements are built with the popular front-end framework UIkit that provides modern codebase with fast and sleek JavaScript.

Sophisticated Layouts for Your Website

YOOtheme invests a lot of time and effort into the development of their layouts. A team of professional designers regularly creates complete website concepts with a thought-out content structure and focus on modern design trends. They already have over 100 layouts with free-to-use images and even hand-made illustrations that can be found in the Layout Library. You can filter layouts according to topics and types, mix and match them, save your own layouts to reuse them later. This provides you with unlimited possibilities and makes creating websites in WordPress as easy as can be.

A Library of Over 70 Beautiful Styles

What makes YOOtheme Pro stand out even more is the Style Library that includes over 70 handcrafted styles. One click, and the look of your website changes completely. Whether you are looking for a minimalistic or a bold style, this substantial collection represents all trends. You can customize next to anything with YOOtheme Pro, from changing the style of each item separately to applying changes globally. This gives you all the power to style your WordPress website with none of the coding.

Integrated Unsplash Image Library

The popular Unsplash library that provides quality and free-to-use photos is seamlessly integrated into YOOtheme Pro. Due to this integration you can search through the library and try out images directly on your website without having to leave YOOtheme Pro. Use filter, browse through collections and users and insert images directly into your layouts. The images will only be downloaded after your click Save. This feature is a real time-saver for every designer.

Lightning-fast and Developer-friendly

YOOtheme Pro is a true piece of German engineering, it is fast, lightweight and easy like no other page builder. Powered by Vue.js and Uikit, it provides a great user experience. YOOtheme Pro also cares about speed. The small code size as well as the latest web technologies ensure the first meaningful paint gets quickly on the screen. And with auto-generated srcsets, lazy loading images and next-gen image formats like WebP YOOtheme Pro will boost the Google PageSpeed rank for your WordPress website. What's more, Google Fonts are stored locally, which saves the request to Google and ensures GDPR compliance.

A modular and extendable architecture makes YOOtheme Pro extremely developer-friendly. It allows you to override everything, add custom elements, CSS, JavaScript and new themes settings. An extensive documentation including video tutorials and a section specifically written for developers will help you get started in no time.

Get YOOtheme Pro

YOOtheme Pro both simplifies and empowers website building. Regular release of theme packages including sophisticated layouts on a specific topic, six style variations and free-to-use images will make YOOtheme Pro the only thing you'll need to create a website. And while we could talk more about how YOOtheme Pro supports WooCommerce and has a a Footer Builder and many desktop and mobile header layouts, we'd rather let you see for yourself. Get YOOtheme Pro and experience the future of website building today.

Direct Link to ArticlePermalink

The post Introducing the YOOtheme Pro Page Builder appeared first on CSS-Tricks.

Using Scoped Slots in Vue.js to Abstract Functionality

Css Tricks - Wed, 09/19/2018 - 3:47am

Let’s start with a short introduction to Vue.js slots concept. Slots are useful when you want to inject content in a specific place of a component. Those specific places that you can define are called slots.

For example, you want to create a wrapper component that is styled in a specific way but you want to be able to pass any content to be rendered inside that wrapper (it might be a string, a computed value, or even another component).

There are three types of slots:

  • default / unnamed slots: used when you have a single slot in a component. We create them by adding <slot> in the template where we want to be able to inject our content. This <slot> tag will be replaced with any content passed to the component’s template.
  • named slots: used when you have multiple slots in a component and we want to inject different content in different places (slots). We create those by adding <slot> with a name attribute (e.g. <slot name="header"></slot>). Then when we render our component, we provide a slot content for each named slot by adding a slot attribute with the slot name.
<base-layout> <template slot="header"> <h1>My awsome header</h1> </template> <template slot="footer"> <p>My awsome footer</p> </template> </base-layout>

By doing that, the <slot> tags in the component will be replaced by content passed to the component.

  • scoped slot: used when you want a template inside a slot to access data from the child component that renders the slot content. This is particularly useful when you need freedom in creating custom templates that use the child component’s data properties.
Real-World Example: Creating a Google Map Loader component

Imagine a component that configures and prepares an external API to be used in another component, but is not tightly coupled with any specific template. Such a component could then be reused in multiple places rendering different templates but using the same base object with specific API.

I’ve created a component (GoogleMapLoader.vue) that:

  1. initializes the Google Maps API
  2. creates google and map objects
  3. exposes those objects to the parent component in which the GoogleMapLoader is used

Below is an example of how this can be achieved. We will analyze the code piece-by-piece and see what is actually happening in the next section.

Let’s first establish our GoogleMapLoader.vue template:

<template> <div> <div class="google-map" data-google-map></div> <template v-if="Boolean(this.google) && Boolean(this.map)"> <slot :google="google" :map="map" /> </template> </div> </template>

Now, our script needs to pass some props to the component which allows us to set the Google Maps API and Map object:

import GoogleMapsApiLoader from "google-maps-api-loader"; export default { props: { mapConfig: Object, apiKey: String }, data() { return { google: null, map: null }; }, async mounted() { const googleMapApi = await GoogleMapsApiLoader({ apiKey: this.apiKey }); this.google = googleMapApi; this.initializeMap(); }, methods: { initializeMap() { const mapContainer = this.$el.querySelector("[data-google-map]"); this.map = new this.google.maps.Map(mapContainer, this.mapConfig); } } };

This is just part of a working example. You can dive in deeper this example.

OK, now that we have our use case set up, let’s move onto breaking that code down to explore what it’s doing.

1. Create a component that initializes our map

In the template, we create a container for the map which will be used to mount the Map object extracted from the Google Maps API.

// GoogleMapLoader.vue <template> <div> <div class="google-map" data-google-map></div> </div> </template>

Next up, our script needs to receive props from the parent component which will allow us to set the Google Map. Those props consist of:

  • mapConfig:?Google Maps config object
  • apiKey:?Our personal api key required by Google Maps
// GoogleMapLoader.vue import GoogleMapsApiLoader from "google-maps-api-loader"; export default { props: { mapConfig: Object, apiKey: String },

Then, we set the initial values of google and map to null:

data() { return { google: null, map: null }; },

On the mounted hook, we create an instance of googleMapApi and the map object from it. We also need to set the values of google and map to the created instances:

async mounted() { const googleMapApi = await GoogleMapsApiLoader({ apiKey: this.apiKey }); this.google = googleMapApi; this.initializeMap(); }, methods: { initializeMap() { const mapContainer = this.$el.querySelector("[data-google-map]"); this.map = new this.google.maps.Map(mapContainer, this.mapConfig); } } };

So far, so good. With all that done, we could continue adding the other objects to the map (Markers, Polylines, etc.) and use it as an ordinary map component.

But, we want to use our GoogleMapLoader component only as a loader that prepares the map — we don’t want to render anything on it.

To achieve that, we need to allow the parent component that will use our GoogleMapLoader to access this.google and this.map that are set inside the GoogleMapLoader component. That’s where scoped slots really shine. Scoped slots allow us to expose the properties set in a child component to the parent component. It may sound like an inception, but bear with me one more minute as we break that down further.

2. Create component that uses our initializer component

In the template, we render the GoogleMapLoader component and pass props that are required to initialize the map.

// TravelMap.vue <template> <GoogleMapLoader :mapConfig="mapConfig" apiKey="yourApiKey" /> </template>

Our script tag should look like this:

import GoogleMapLoader from "./GoogleMapLoader"; import { mapSettings } from "@/constants/mapSettings"; export default { components: { GoogleMapLoader, }, computed: { mapConfig() { return { ...mapSettings, center: { lat: 0, lng: 0 } }; }, } };

Still no scoped slots, so let’s add one.

3. Expose google and map properties to the parent component by adding a scoped slot

Finally, we can add a scoped slot that will do the job and allow us to access the child component props in the parent component. We do that by adding the <slot> tag in the child component and passing the props that we want to expose (using v-bind directive or :propName shorthand). It does not differ from passing the props down to the child component, but doing it in the <slot> tag will reverse the direction of data flow.

// GoogleMapLoader.vue <template> <div> <div class="google-map" data-google-map></div> <template v-if="Boolean(this.google) && Boolean(this.map)"> <slot :google="google" :map="map" /> </template> </div> </template>

Now, when we have the slot in the child component, we need to receive and consume the exposed props in the parent component.

4. Receive exposed props in the parent component using the slot-scope attribute

To receive the props in the parent component, we declare a template element and use the slot-scope attribute. This attribute has access to the object carrying all the props exposed from the child component. We can grab the whole object or we can de-structure that object and only what we need.

Let’s de-structure this thing to get what we need.

// TravelMap.vue <template> <GoogleMapLoader :mapConfig="mapConfig" apiKey="yourApiKey" > <template slot-scope="{ google, map }"> {{ map }} {{ google }} </template> </GoogleMapLoader> </template>

Even though the google and map props do not exist in the TravelMap scope, the component has access to them and we can use them in the template.

Yeah, OK, but why would I do things like that? What is the use of all that?

Glad you asked! Scoped slots allow us to pass a template to the slot instead of a rendered element. It’s called a scoped slot because it will have access to certain child component data even though the template is rendered in the parent component scope. That gives us a freedom to fill the template with custom content from the parent component.

5. Create factory components for Markers and Polylines

Now, when we have our map ready, we will create two factory components that will be used to add elements to the TravelMap.

// GoogleMapMarker.vue import { POINT_MARKER_ICON_CONFIG } from "@/constants/mapSettings"; export default { props: { google: { type: Object, required: true }, map: { type: Object, required: true }, marker: { type: Object, required: true } }, mounted() { new this.google.maps.Marker({ position: this.marker.position, marker: this.marker, map: this.map, icon: POINT_MARKER_ICON_CONFIG }); }, }; // GoogleMapLine.vue import { LINE_PATH_CONFIG } from "@/constants/mapSettings"; export default { props: { google: { type: Object, required: true }, map: { type: Object, required: true }, path: { type: Array, required: true } }, mounted() { new this.google.maps.Polyline({ path: this.path, map: this.map, ...LINE_PATH_CONFIG }); }, };

Both of these receive google that we use to extract the required object (Marker or Polyline) as well as map which gives as a reference to the map on which we want to place our element.

Each component also expects an extra prop to create a corresponding element. In this case, we have marker and path, respectively.

On the mounted hook, we create an element (Marker/Polyline) and attach it to our map by passing the map property to the object constructor.

There’s still one more step to go...

6. Add elements to the map

Let’s use our factory components to add elements to our map. We must render the factory component and pass the google and map objects so data flows to the right places.

We also need to provide the data that’s required by the element itself. In our case, that’s the marker object with the position of the marker and the path object with Polyline coordinates.

Here we go, integrating the data points directly into the template:

// TravelMap.vue <template> <GoogleMapLoader :mapConfig="mapConfig" apiKey="yourApiKey" > <template slot-scope="{ google, map }"> <GoogleMapMarker v-for="marker in markers" :key="marker.id" :marker="marker" :google="google" :map="map" /> <GoogleMapLine v-for="line in lines" :key="line.id" :path.sync="line.path" :google="google" :map="map" /> </template> </GoogleMapLoader> </template>

We need to import the required factory components in our script and set the data that will be passed to the markers and lines:

import { mapSettings } from "@/constants/mapSettings"; export default { components: { GoogleMapLoader, GoogleMapMarker, GoogleMapLine }, data() { return { markers: [ { id: "a", position: { lat: 3, lng: 101 } }, { id: "b", position: { lat: 5, lng: 99 } }, { id: "c", position: { lat: 6, lng: 97 } } ], lines: [ { id: "1", path: [{ lat: 3, lng: 101 }, { lat: 5, lng: 99 }] }, { id: "2", path: [{ lat: 5, lng: 99 }, { lat: 6, lng: 97 }] } ] }; }, computed: { mapConfig() { return { ...mapSettings, center: this.mapCenter }; }, mapCenter() { return this.markers[1].position; } } }; And we’re done!

With all those bits and pieces completed, we can now re-use the GoogleMapLoader component as a base for all our maps by passing different templates to each one of them. Imagine that you need to create another map with different Markers or just Markers without Polylines. By using a pattern of scoped slots, it becomes very easy since all we need to pass now is different content to the GoogleMapLoader component.

This pattern is not strictly connected to Google Maps; it can be used with any library to set the base component and expose the library’s API that might then be used in the component that summoned the base component.

It might be tempting to create a more complex or robust solution, but this gets us the abstraction we need and it becomes an independent piece of our codebase. If we get to that point, then it might be worth considering extraction to an add-on.

The post Using Scoped Slots in Vue.js to Abstract Functionality appeared first on CSS-Tricks.

Push Notifications: Top 5 Mistakes To Avoid Making

Usability Geek - Tue, 09/18/2018 - 1:37pm
Web and mobile push notifications are one of the most efficient and handy tools that can help you increase your conversion rates and engage your audience in real time and with actual results....
Categories: Web Standards

Twenty Years as a Freelance Web Developer: Wisdom Gained and Lessons Learned

Css Tricks - Tue, 09/18/2018 - 3:50am

In the summer of 1998, when President Clinton fended off allegations of sexual impropriety and Donald Trump filmed a cameo in a Woody Allen movie, I embarked on my career as a freelance web developer. Twenty years and more than 300 websites later, I’m still at it—always working on my own and always from home. Over that time, I’ve had the pleasure of partnering with many prominent advertising agencies and boutique design firms as well as scores of local businesses and individuals.

Those interested in making the switch to freelancing have often asked me for advice, and I’ve been happy to help with whatever words of wisdom I can provide. This article is a distillation of much of that. And it may prove helpful not only to developers and programmers who wish to freelance, but also designers, project managers, copywriters—anyone who desires to work independently from home in our industry. It’s a career path that I have loved, but it’s not for everyone.

My background

None of this was planned. I did have a teenage interest in programming, first learning BASIC on the Timex Sinclair 1000 and then Assembly Language on the Apple II. Despite this, after graduating college, I pursued a career on the business side of magazine publishing. Less than six years later, however, I needed a change, and my path took me to Pratt Institute in New York where I enrolled in a graphic design program. This included electives in HTML and JavaScript that unexpectedly rekindled my desire to program. A teacher then referred me to a recruiter and my new career as a freelance front-end developer was born.

The primary element of successful freelancing

When I’m asked the more existential question of how I’ve survived so long as a freelancer, my response is always the same: above all, be reliable. Don’t get me wrong; it’s important that my delivered websites work as promised—requirements must be met and best practices followed. But I quickly found that my clients were not necessarily looking for perfection in the work itself. In fact, to this day, I often have the odd feeling that no one even looks at my code as long as there aren’t any bugs.

What really matters is delivering on time. Deadlines are sacrosanct. If project managers, who seem perpetually overworked and under pressure, can depend on me to keep to a schedule, that’s one less part of their overall responsibilities to keep them up at night. For that, I’m routinely thanked. My creative use of CSS or efficient JavaScript coding? Rarely is that even acknowledged.

Achieving this kind of reliability ends up being the primary challenge for a freelancer, especially when juggling multiple projects for multiple clients. Then there’s the additional stress of knowing that there’s no one to step in during sickness or emergencies. My go-to sports metaphor is that working as part of a group is like being on a basketball team. Having a poor shooting night? Dish the ball off to one of your teammates to pick up the slack. A freelancer working from home is more like a boxer—you’re alone in the ring with no one else to take credit or assume blame. Throwing in the towel is not an option.

Inevitably, though, there will be issues that can affect a freelancer’s ability to be reliable. Delays occur, scopes change, deadlines shift. That’s when open and honest communication with the client is necessary. In earlier days, I feared that I wouldn’t be hired for future projects if I rocked the boat in any way. In reality, though, I have found quite the opposite to be true. If the best interests of the project and its processes are kept in mind, I believe clients appreciate when red flags are pointed out, as difficult as those conversations may be. Being a successful freelancer is not the same as one who is excessively pliant. One must be proactive in voicing concerns that may affect his or her role on any project.

Be the generalist who specializes

My specialty is front-end development. Clients hire me to take beautiful designs and translate them into code that works in everyone’s browsers. To do this, I’ve had to master HTML, CSS, and JavaScript. Despite having marketable knowledge in related areas, including Flash when it was popular and now WordPress, my core expertise remains unchanged. And it’s this core expertise that gets me work.

This is important because I have found that most projects for which I’m hired as a freelancer, particularly the larger ones, resemble an assembly line—different individuals are tasked to complete one specific part of the process while working alongside others doing the same. Ultimately, everything is assembled into the final product. It’s in these instances when I’m utilizing that one skill that I’m expected to do very well. That I possess much ancillary knowledge is irrelevant.

As I’m sure everyone has noticed, the descriptives "full stack developer" and "full stack designer" have gained prominence of late. In earlier days, we simply referred to these individuals as having a broad skill set in their discipline. Whatever the terminology, having a wide swath of knowledge is certainly a huge plus and can only serve to extend one’s career, but bear in mind that it’s important to have that one defined skill that you do better than most. The freelancer who is the proverbial jack of all trades and master of none is not often seen as enticing to hire.

The myth of diversification

My perception early on was that being a freelancer would provide more financial security than the alternative. Instead of having all my eggs in the one basket of a permanent employer, I expected to spread the risk among a roster of clients. There would always be someone to pick up the slack if any one of them flew the coop.

In practice, though, I have found this to be an unsustainable model as it’s simply not possible to satisfy all requests for your services during peak times—there’s only so much work any of us can handle at once. This results in some clients necessarily forced to look elsewhere to staff their projects. Then, the next time around, you may no longer be at the top of their resource list of freelancers.

This contributes to the inevitable equilibrium where one or two clients emerge to represent well more than half of my business. I’ve seen this dynamic play out again and again, no matter the ups and downs of the economy and demand for my services. The smaller, less-frequent clients are there for when I’m otherwise available but are not my priority. On the bright side, having primary clients who hire me on a regular basis provides a dependable source of income; the negative is that I’m rarely as diversified as I once hoped I would be.

Homebound networking

So how does one obtain work in the first place? After using a recruiter early on, which, for me, was particularly necessary since I lacked any relevant experience, my network expanded as people with whom I had worked inevitably moved on to new employers. These contacts, most often designers and project managers, kept me in their virtual Rolodex as a potential resource, thus growing my network.

My other significant channel for leads has been from the simple act of meeting people in everyday life and sharing with them what I do for a living. These casual conversations —even with those who seemingly had no need for my services—often create serendipitous opportunities that lead to new work. As the saying goes, it’s not the people you know, but the people they know. Don’t be shy—tell the world what you do to help generate word-of-mouth referrals. You are your own greatest advocate.

While LinkedIn serves as a useful conduit for exposure, it’s the freelancer’s own website that provides the best and most-controlled opportunity to show who you are and what you do. But, as someone who has consulted with clients in hiring decisions, I have seen so many of these websites obscure the very information necessary to make such a choice. Avoid the temptation of making the website itself a demonstration of one’s skills. Eschew needless animations or distractions. It’s best to keep key information, such as the portfolio and resume, easy to find and, yes, even to print.

Of course, the more repeat business one can secure, the less need there is to obtain new clients. I believe the personal relationships I have sought to cultivate are what have helped me with this. By meeting with key contacts in person, unspoken bonds are formed that lead to genuine partnerships, transcending traditional employer/contractor interactions. In the age of Skype and Slack, the freelancer working from home can go long stretches without any direct face-to-face communication with those for whom they are working. If logistically possible, one must move past the screen and make an impression in the real world.

Show me the money!

There’s no question that my least favorite part of freelancing is the constant need to submit estimates. In fact, I tend to look at it as a no-win situation. If my estimate is readily accepted, there’s a shallow feeling that I’ve left money on the table; if a client responds in disbelief that I asked for so much, I feel a sense of shame that I’ve greatly overreached. But there’s a misplaced fear that by asking for too much, the client will be offended and walk away. That’s never happened to me. If anything, apologies are offered and negotiations commence.

Always remember, though, that your work has value and deserves to be compensated appropriately at market rates. By significantly underbidding estimates, which is always a temptation when work is slow, it implies to a client that you don’t value your own work. On those rare occasions when I’ve made the mistake of selling myself short, I tend to work on those projects "angry"—not at the client, but at myself for being placed in a situation where I must invest more time for less money.

The invoice has been submitted and paid. Then what? Many prominent financial advisors recommend keeping a three- to six-month reserve fund for emergencies. What I say is that, as a freelancer, you can never save enough. Booms and busts are common in the modern economy and seem to happen with greater frequency. Therefore, save and then save some more. I’ve endured two major economic downturns—the collapse of the dot-com bubble in 2001 and the Great Recession of 2008. Each time, my income essentially dried up for a lengthy duration. Having enough savings set aside enabled me to ride out the storm.

Maintaining a work/life balance

Much has been written lately about the mental health challenges faced by those who work in our industry. Most of us go through various stages of our career when, at times, the stresses of one’s professional and personal experiences can take their toll. I have not been immune to this. As my career progressed, the care-free mindset of youth was gradually supplanted by concerns of where my life was headed. Self-confidence became self-doubt. I don’t see this necessarily as a manifestation unique to our industry, but simply the result of being a human being in modern society.

Working from home as a freelancer can make matters worse. In the relative isolation of a home office, it’s easy to slip into a downward spiral without having others nearby to offer encouragement. When the time came, it was my responsibility to make a concerted effort to reach out to my clients and friends (often one and the same) for support. People can relate and empathize. We are not alone in our struggles.

What helps most in keeping myself balanced is getting away from the computer, or any video screen for that matter, as often as possible. Regardless of workload, I make sure to take trips to the gym, visit friends, or simply go for a walk. I also frequently take classes that have nothing to do with my career to stimulate different parts of my brain. Right now, I’ve dedicated a significant amount of free time to learning German, which is a welcome challenge wholly unrelated to web development.

When teaching yourself something new related to work, try creating projects that are both rewarding and challenging. To keep motivated, pretend to be your own client and set deadlines and milestones. Last year, I did just that and developed a jQuery plugin, which I wrote about for CSS-Tricks, that allows the browser to read webpages aloud. It was a terrific learning experience, and I had fun along the way.

Moving forward

These have been my own reflections on a freelance career that’s closer to its end than its beginning. Others with a similar career history may have different impressions and advice—the comments section below is a terrific forum for voicing any corroborating or contrasting opinions.

As with any career path, being a freelancer has embodied its own set of rewards and sacrifices. And while my regrets are few, those who consider freelancing will have to decide for themselves whether it’s right for them. The liberating part of making that decision is that there really is no "right" answer. We are all different, always changing, ever evolving. What didn’t work for us professionally ten years ago may feel perfectly appropriate at a later time.

In a sense, though, perhaps the decision has already been made for us. With the era of lifetime employment long past and companies discharging employees at a faster rate than ever before, it may be time to recognize that we are all freelancers now.

The post Twenty Years as a Freelance Web Developer: Wisdom Gained and Lessons Learned appeared first on CSS-Tricks.

How UX Designers Can Innovate

Usability Geek - Mon, 09/17/2018 - 12:31pm
Recently, I have written about different, often unexpected sources user experience designers can mine inspiration from. Whether you are stuck in a creative rut or want that motivational spark that...
Categories: Web Standards

What makes a good front-end developer?

Css Tricks - Mon, 09/17/2018 - 9:54am

Defining what a front-end developer is and what they do is tough as it is. So, how do we set the bar for what makes for a good front-end developer?

Here's what a few folks have to say on the topic.

I’ll argue that front-end developers need to master four different skills.

  1. Empathy
  2. Code
  3. Design
  4. Communication
Zell Liew

Front-End Developers, having learnt HTML, CSS and JS, are forced to take functionality into account when creating user experiences or making sure that the two disciplines work as one from a development perspective. They become all-rounders, having to understand what is actually happening between the AJAX data and the PHP file that’s sending off a mail or returning errors.

Daine Mawer

In my opinion, what defines a good front-end developer is one that has skilled knowledge of HTML, CSS, JS with a vast understanding of User design thinking as they'll be building web interfaces with accessibility in mind. They should also be excited to learn, as the world of Front-End Development keeps evolving. The ability to stay in the loop is critical.

Egwuenu Gift

After I started to feel more comfortable with my responsibilities ... I soon found my next challenge: to help build a stronger connection between the design and development teams. Though we regularly collaborated to produce high-quality work, these teams didn’t always speak the same language.

Ronald Méndez

I think that front-end developers need to have a holistic view of the architecture of the software that they and their team are creating. They can't silo themselves on the Front-End, but need to have an appreciation for the complexities of the Back-End as well in order to create the best user experience for their customers. In the end, it's about continual learning and team communication, as well as listening to the customer to create a great experience.

Jen Looper

The longer I work on the web, the more I realize that what separates the good people from the really good people isn’t what they know; it’s how they think. Obviously knowledge is important—critical in some cases—but in a field that changes so quickly, how you go about acquiring that knowledge is always going to be more important (at least in the long term) than what you know at any given time. And perhaps most important of all: how you use that knowledge to solve everyday problems.

Philip Walton

Having a working understanding of HTML, CSS and JS is certainly a no-brainer, but it's only one part of the equation. I believe a good front-ender connects the dots between user experiences and business goals while closing any gaps that would prevent holistic user flows. That requires good communication, creative problem solving, empathy and, perhaps above all, an willingness to listen to and accept criticism.

Geoff Graham

It's a difficult question in some ways because the nature of Front-end Development is constantly expanding. The types of things we build as front ends become increasingly complex and varied.

For that reason, I think a good Front-end Developer understands the scope, requirements, and technical restraints of the project they are currently working on. This can invariably mean: what their teams expect from them, what their users need, and because things are changing- curiosity!

Sarah Drasner

I admire how good front-end developers answer questions. If they’re super dogmatic about this one particular approach to something being the only one true way then I start to worry. Take SVG illustrations. Or image optimization. Or how to markup navigation. There’s a lot of different ways to tackle each of those things and none of them are perfect. On this note, Chris wrote a wonderful post all about dogmatism a while back and I think about it all the time. That’s the mark of a great front-end developer right there: someone who’s okay with not having the perfect answers all the time.

Robin Rendle

A good front-end developer is flexible, eager to learn, eager to share and has a pragmatic approach to the ever-changing landscape

Oh yeah, and something something cascade.

Andy Bell What do you think?

This is an open conversation. No right answers. No wrong answers. How would you grade a "good" front-end developer?

The post What makes a good front-end developer? appeared first on CSS-Tricks.

How To Create Emotionally Rewarding UX Designs

Usability Geek - Mon, 09/17/2018 - 9:14am
What makes a website’s design genuinely effective? Is it the way it looks or the way that it works? In truth, it is a little bit of both. Both the aesthetic and the functionality of a web page...
Categories: Web Standards

Aspect Ratio Media Elements and intrinsicsize

Css Tricks - Mon, 09/17/2018 - 3:50am

If you need an aspect-ratio sized <div> (or any element that can have children), you can do it. Perhaps the cleanest way is a custom-property-sized pseudo-element that pushes the correct minimum height through padding-based-on-width.

But media elements like <img> don't have children. The <video> tag isn't self-closing, but when it is supported (almost always), the content of it is replaced with a shadow DOM you don't control. Besides, these are the only two elements that "size to an external resource." So, how do you enforce aspect ratio on them when using a variable width like 100% or 75vw? Well, once they load, they will have their natural aspect ratio, so that's nice. But it also means they don't know the height while they are loading and it may cause performance jank-ening reflow.

One solution is to put them into a container with an aspect ratio, forcing them to the corners with absolute positioning. But, all by themselves, they are incapable of sizing to the aspect ratio correctly until they load.

Hence, the intrinsicsize attribute for "all image element types (including SVG images) and videos" that is now under development.

<img intrinsicsize="400x300" style="width: 100%">

The explainer document is helpful. The reason it is intrinsicsize and not aspectratio is because an aspect ratio doesn't provide as much useful or usable information. I'd love to see it work on any element and be brought to CSS as well.

The post Aspect Ratio Media Elements and intrinsicsize appeared first on CSS-Tricks.

Removing jQuery from GitHub.com frontend

Css Tricks - Fri, 09/14/2018 - 12:00pm

Here’s how and why the team at GitHub has slowly been deprecating jQuery from their codebase:

We have recently completed a milestone where we were able to drop jQuery as a dependency of the frontend code for GitHub.com. This marks the end of a gradual, years-long transition of increasingly decoupling from jQuery until we were able to completely remove the library. In this post, we will explain a bit of history of how we started depending on jQuery in the first place, how we realized when it was no longer needed, and point out that—instead of replacing it with another library or framework—we were able to achieve everything that we needed using standard browser APIs.

The team explores how using tools like eslint-plugin-jquery discourages developers at GitHub from using jQuery, but the team also notes that they decided to remove certain design behaviors altogether to help them achieve this goal:

As part of our refined approach to building frontend features on GitHub.com, we focused on getting away with regular HTML foundation as much as we could, and only adding JavaScript behaviors as progressive enhancement. As a result, even those web forms and other UI elements that were enhanced using JS would usually also work with JavaScript disabled in the browser. In some cases, we were able to delete certain legacy behaviors altogether instead of having to rewrite them in vanilla JS.

I think all of this is wonderful news. It’s good for jQuery, it’s good for developers, and it’s good for the web. But it also shows just how far browsers have come since the first release of jQuery back in 2006. What will browsers be capable of 12 years from now, I wonder.

Direct Link to ArticlePermalink

The post Removing jQuery from GitHub.com frontend appeared first on CSS-Tricks.

HTML elements, unite! The Voltron-like powers of combining elements.

Css Tricks - Fri, 09/14/2018 - 4:08am

Guides, resources and discussions about Semantic HTML are often focused around specific elements, like a heading, or a sectioning element, or a list. It’s not often that we talk specifically about how we can combine HTML elements to increase their effectiveness.

Normally, when we introduce HTML, we talk about how it is used to apply meaning to content in a document, and we do this by using examples like:

  • "Is it a paragraph?"
  • "Is it a heading?"
  • "Is it a numbered list"
  • "Is it a button"

We use these examples because they are easy to understand — it’s a single piece or chunk of the same content that needs to be represented in a particular way. This is useful, but it only scratches the surface of how we can use and combine elements to provide more context and meaning.

You remember Voltron, right? Each member of the Voltron force was powerful in their own right, but it was when they combined together to form a towering figure that their mighty powers became unstoppable.

The same is true of HTML elements. I have a few favorite combinations that I’ll take you through. They may seem obscure, but you’d be surprised at how often they come up when you take the time to think outside of divs and spans.

Abbreviations and Definitions

<abbr> and <dfn> are two of my favorite HTML elements. I particularly like them because they work really well together.

You can combine the abbreviation and definition elements to allow browsers, search bots, and other technologies to recognize that something is being defined and that the acronym is associated to that phrase.

<p> The <dfn><abbr title="International Good Dog Association">IGDA</abbr></dfn> is an international, not-for-profit organization responsible for determining that all dogs are good. </p>

In the above example, I’m defining that the acronym "IGDA" as "International Good Dogs Association." I do this by wrapping the acronym in an <abbr> element with a title attribute defining the full name. By adding the <dfn> element around the abbreviation, it indicates that the surrounding paragraph defines the term "International Good Dogs Association."

The <abbr> element is useful because it can provide a useful visual representation in the form of a tooltip explaining what the abbreviation is.

Visual representation of <abbr> and <dfn>. Keyboard, Sample and Variable

If you haven’t heard of these elements, then get ready to have your socks blown off, because they are awesome.

First up, the <kbd> element is used to represent text for a textual user input (e.g. from a keyboard). You can also nest multiple <kbd> elements to represent multiple keystrokes. I love this because, as developers, we find ourselves (hopefully) writing documentation, blog posts, and guides on a regular basis and HTML provides us with native ways to represent this content straight out of the box!

If I wanted to tell someone how you copy and paste with the keyboard, I could mark it up like the code below.

<p>I like to <kbd><kbd>Ctrl</kbd>+<kbd>C</kbd></kbd> and <kbd><kbd>Ctrl</kbd>+<kbd>V</kbd></kbd> a lot.</p>

It looks a bit nuts but the above code, when rendered, looks like the following without any styling applied to it. If you are wondering why kbd is nested inside another kbd element, what this does is specify that the key or input is part of a larger input. Even more combined superpowers!

See the Pen rZpNPy by CSS-Tricks (@css-tricks) on CodePen.

You can further target the <kbd> elements with CSS to make it look more like little keyboard controls. (Note: Browsers tend to render this by default with a monospace font.)

See the Pen gdoOqE by CSS-Tricks (@css-tricks) on CodePen.

If you’re wondering what the difference is between using <kbd> versus a span, I believe it comes down to information. I will repeat this sentiment a lot: we do not know how someone is going to consume our HTML, so give your content it’s best chance by representing it in the most meaningful and contextual way possible. If you are still not on board, then please go read my post about HTML as told by TypeScript.

The <samp> element is really cool because you can nest it inside the <kbd> element and vice versa. WHAT? I know, so versatile! Let’s have a look at some examples from MDN.

The following code is an example of nesting a <samp> element inside a <kbd> element. This is used to mark up content that represents input based on the text displayed by the system (e.g. button names).

<p>To save the image file, select <kbd><kbd><samp>File</samp></kbd> - <kbd><samp>Save as...</samp></kbd></kbd>. </p>

See the Pen YOYzbJ by CSS-Tricks (@css-tricks) on CodePen.

In the above code, we define our keyboard shortcuts the same as our previous example, but we also determine that the menu and menu item names (contained within both <kbd> and <samp>) are an input selected from something displayed by the system, e.g. a dialog or widget.

In other words, this piece of text is a message from the system which has some user inputs that you need to follow (like File and Save as…).

Whereas, when we nest <kbd> inside <samp>, we determine that the input has been echoed back to the user by the system.

<p><samp>yarn start:theproject does not exist, did you mean:</p> <blockquote><samp><kbd>yarn start:the-project</kbd></samp></blockquote>

Finally, the <var> element! This is used to mark up the name of a variable in math or programming, for example:

<var>E</var> = <var>m</var><var>c</var><sup>2</sup>. <samp>Error: <var>console<var> is undefined.</samp>

Here you can start to see how combining <var> with other elements like <pre>, <code>, <kbd> or <samp> starts to make your content’s markup more explicit by adding more context. Anything that interprets your HTML markup can start to derive more meaning from the elements you are using rather than just assuming that it’s all standard text.

If you put this content in a paragraph with some spans, there is no way for technology to distinguish this from any other old text on your page. You don’t have to resort to <span> or a <div> to represent this content because HTML already provides us with more semantically accurate elements we can use. HTML is not just about presentation; it’s about meaning. Various technologies outside of visual rendering engines rely on this meaning to make decisions about how to communicate our content in the most meaningful way (e.g. screen readers, text to voice, reading apps, bots, or the next big thing in the future).

Figures

Figures (<figure>) are a great example of a power combination element. Unfortunately, I think it is widely misused and under appreciated (much like <aside>, which I could talk about for hours). The obvious combination you are probably familiar with is using <figure> and <figcaption> together. We often use this duo to represent graphical content like images, illustrations and diagrams — but it can also be used for things like code, poems and quotes!

Because a figure is so flexible in what kind of content it represents, there are a bunch of different HTML elements you can use within a figure to provide more context around the type of content you are putting in your page.

Figcaption

The <figure> element is often seen with an optional <figcaption> which represents a caption or legend for a figure. It should be the first child or last child of the <figure> element. You can also use any flow content (e.g. paragraphs, headings, etc.) in the <figcaption> to provide more context and you can have multiple images inside a <figure> represented by a single <figcaption>.

<figure> <img src="jello.jpg" alt="Golden Retriever Puppy" /> <figcaption>Jello the Golden Retriever enjoying being carried home.</figcaption> </figure> Preformatted Text

The <pre> element is used to display preformatted text or code and is usually rendered using a monospace font. While <pre> can be used on its own, it can also be combined with <figure> and <figcaption>. By doing this, the content inside the <pre> element becomes more accessible to assistive technologies, like screen readers, since it allows us to use <figcaption> as a label for the text or code.

We can go even further by combining the <pre> and <code> elements to identify the pre- formatted content as code.

See the Pen QVaWVW by CSS-Tricks (@css-tricks) on CodePen.

Because <code> is considered flow content, it can also be used inside a <figcaption> to mark up inline references to code (i.e. a single phrase or line).

Cite and Blockquote

Quotations are something I use a lot and it honestly didn’t occur to me it could be used as part of a figure. But it still makes sense to use a cite or blockquote if the content they contain is relevant to the overall content, even if it is not part of the main document flow.

I like the example of using a figure for poems, mainly so I could share the amazing poem I wrote about my dog. Here I use the <cite> element inside the <figcaption>:

<figure> <p> Jello - A little fluffy dog. Hello! Squishy Jello - you little fluffy fellow. BOUNCY yellow Jello. A very mellow fellow. EATING MY MARSHMALLOW. </p> <figcaption><cite>Eating my Marshmallow by Mandy Michael</cite></figcaption> </figure>

It’s easy to fall into the trap of thinking that the figure element is just for images or image-like content, but you can use it for content like audio, video, charts, poems, quotations or even tables of statistics. Because the element is so versatile you can combine it with so many other elements to provide more and more context about the figure for assistive technology, browsers, and other technologies consuming your website.

Wrapping Up

These are just some of the ways HTML elements can be combined for better context. HTML elements are indeed useful and valuable on their own when used as isolated pieces — and using them this way is a good first step. But, like Voltron, when you combine HTML elements together, the individual pieces form a greater whole and gain much more meaning and power. It’s important that we don’t think of HTML as individual pieces of code, but parts of a whole because HTML is really a mass of totally amazing combinations.

You can combine and use HTML elements in any number of ways to best represent your content. Don’t simply stick to the same old things you know; take the time to explore HTML and learn about all it has to offer. Like any language, we should make the most of it and use it to its full potential.

The more accurate you are in marking up your content, the better that content will be represented across technologies, and the more prepared it will be for anything else that is used to interpret your HTML in the future.

So, go forth and HTML elements, unite!

Resources

In my opinion, the best resource for learning and understanding how to use HTML (outside of the spec itself) is the MDN Web Docs. It lists all the HTML elements you could ever need.

The following are among the elements covered in this post:

If you are a TypeScript fan and don’t understand why Semantic HTML is important, I wrote this post just for you: Understanding why Semantic HTML is important as told by TypeScript.

The post HTML elements, unite! The Voltron-like powers of combining elements. appeared first on CSS-Tricks.

Why Designers Don’t Want to Think When They Read

Css Tricks - Fri, 09/14/2018 - 4:08am

We've all seen articles like "The Top 5 Ways To Fix Your Sign Up Flow and Get On With Your Life." Articles like this aren't wrong or bad, they are just shallow and a bit junk food-y and BuzzFeed-y. Of course, a designer's actual job is complicated, nuanced, and difficult. But deep dives into all that are far less common.

Khoi Vinh has been writing about this and points to some heavy self-reflection from Fabricio Teixeira and Caio Braga, publishers of the very popular UX Collective.

It’s clear that the currency of design discourse is really concerned with the “how” of design, not the “why” of it. As Teixeira and Braga write:

While designers tend to be skeptical of magic formulas—we’re decidedly suspicious of self-help gurus, magic diets, or miraculous career advice—we have a surprisingly high tolerance for formulaic solutions when it comes to design.

That’s a pointed criticism but, from my perspective, it’s also quite accurate.

Direct Link to ArticlePermalink

The post Why Designers Don’t Want to Think When They Read appeared first on CSS-Tricks.

XOXO 2018

Css Tricks - Thu, 09/13/2018 - 9:34am

There’s not much talk about frameworks here. There’s no shaming about old techniques, or jokes about JavaScript. There’s just a couple hundred people all around me laughing and smiling and watching talks about making things on the web and it all feels so fresh and new to me. Unlike many other conferences I’ve visited, these talks are somehow inclusive and rather feel, well, there’s no other word for it: inspiring.

I’m sitting in a little room buried underneath the Veterans Memorial Coliseum in Portland and I’m here for my third XOXO. And I can’t stop smiling.

Although the festival is not entirely focused on coding and front-end development, there are a lot of developers here that make art on the web for fun. From Jenn Schiffer’s pixel art to Monica Dinculescu’s emoji projects and Nicole He’s buck-wild enhance.computer, there’s a lot of interesting discussions about coding — but! — it’s from a very different perspective than the one I’m familiar with.

Most conferences tend to focus on being practical. Here’s the newest technique! Here’s how to improve your career! Here’s the coolest new folks that you should be following! But it’s important to remember that the web isn’t only a serious place for serious work. It can be this entirely other thing, too.

The web can be for fun. It can be utterly weird and unexpected. And that’s what we’re all seeing in this little room right now at XOXO; websites that can’t be monetized, websites that can’t be controlled by corporate interests or giant ad networks.

Websites that are just for fun.

The post XOXO 2018 appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.