Tag Archives: article

Thumbnail

A Deep Dive Into Adobe Edge Reflow

Most of us were thrown for a loop when responsive design came into being. We tried to jam it into our existing, pixel-perfect, old-as-the-web-itself processes. It’s been a steep learning curve (and still is).

In my previous article “Next-Generation Responsive Web Design Tools: Webflow, Edge Reflow, Macaw1” for Smashing Magazine, I didn’t have enough space to dive as deep into those tools, as I wanted. So, in this article, I’m going to dive deep into just one of those tools: Adobe Edge Reflow CC.

Edge Reflow is one in an avalanche of tools that have come out that make it possible to visually design a responsive website. What you do with that design is up to you (and the capabilities of the tool). Edge Reflow was created to address how responsive design has changed our web workflows.

Reflow takes your static Photoshop (PSD) files and breathes responsiveness into them. Instead of having to create 3, 7, 14 or however many Photoshop comps for each necessary device or size, you can let Reflow convert the Photoshop content into HTML and CSS and then visually adjust the design using breakpoints in Reflow.

Where Does Reflow Fit In Our Web Workflow?

This is the question I get most often. As Adobe states, Reflow is meant to “start responsive designs faster and create high-fidelity prototypes through media query breakpoints, precise CSS layouts, grouping and more.” A big plus is that it connects directly with Photoshop, so the thought is that you can go from a static design to a responsive prototype (or at least a starting point) in a few moves.

Edge Reflow product page.2
Edge Reflow’s product page. (View large version3)

What can you use Reflow for right now? I’ve seen Reflow used as a simple way to mock up a one-page concept for a client, which can work well. Reflow can also be used to visually resolve a website design problem. It’s a great tool for wireframing. If you want to build a complete responsive website without getting your fingers dirty with code, however, you’ll work too hard to accomplish a goal that other tools do better in less time.

Reflow may be part of a web developer’s toolbox, but it’s not meant to be a one-stop website creation tool. You’ll need to decide if it could (or should) play a part in your workflow based on what it can and can’t do. If you work with designers upstream, or you are a designer, then it might fit. As a developer myself, I’ll cut to the chase and add also that the code it generates is not how I would do it. For starters, it uses IDs for style names and is only optimized for WebKit browsers. Does that mean you throw the code in the trash? Not necessarily, as you’ll see.

You Can Start With Photoshop

Currently, Reflow is being positioned as a visual design tool, which means you can drag and drop content and make formatting edits using panels, but it does require some knowledge of HTML and CSS (at least the basics). If you step into Reflow not knowing what a float is or how margins affect a layout, then the learning curve will be steeper.

There are a few ways to start a responsive design project in Edge Reflow. You could crack open Reflow and choose File → New Project and start jamming on a blank canvas, pulling content from Photoshop or pushing content from Photoshop to Reflow (or a combination of those methods). Adobe focuses on the Photoshop connection because that’s how most designers used to start their designs (and maybe still do, depending on their workflow and distaste for code), so we’ll do the same.

Edge Reflow CC's workspace.4
Edge Reflow CC’s workspace. (View large version5)

A lot of people I talk to start designing in Photoshop and then push (or export) to Reflow. This way, they use the same design features and knowledge of Photoshop that they’ve always had. That said, here are a few best practices for working with Photoshop if you plan to go to Reflow from it.

  • Use smart objects
    Smart objects are useful because they link shared content, such as navigation and footer content, to your Photoshop file. Smart objects for images also allow you to keep full-resolution versions for later editing (think non-destructive editing).
  • Be careful about linked smart objects
    Right after I said to use them, right? Highly suspect, Brian. Currently, any linked smart objects (PSB) files in Photoshop will be simply flattened when exported to Reflow. Suppose you have shared navigation with text — that will become rasterized.
  • Set the right size
    This doesn’t really need to be said, but start in Photoshop with the size that you are aiming for, whether it’s mobile first or something else.
  • Set up Extract Assets
    This is a must if you plan to export from Photoshop to Reflow. File → Extract Assets in Photoshop will generate the optimized assets (you’ll learn about this shortly).
  • Round your numbers
    As with all things web, we try not to keep our formatting values at things like 12.347655893pt.
  • Use shapes, not filled layers
    Shapes become <div>s in Reflow, and filled layers become nothing (they are dropped when you export).
  • Organize your layers
    The HTML that is generated follows the stacking order in the Layers panel. Content at the top of the Layers panel will appear at the top of the HTML document. In other words, make sure that your footer content isn’t a top layer in the Layers panel, otherwise it will be close to the opening <body> tag, and you’ll have to use some unsavory methods to position it at the bottom of the page in the HTML.
  • Mind layered images
    Images with content layered on top of them are treated as background images in a <div> in Reflow.
  • Think about naming layers
    If you name a layer something like image.png, 200% image@2x.png, then two images will be generated. The first image in the list will be placed in the design in Reflow, and the other will be generated and will hang out in the assets folder.
  • Mind text objects
    Text objects that are drawn in Photoshop as a type area will have a dimension in Reflow. If you simply click with the Type tool in Photoshop, then the paragraph in Reflow will not have a width.

Photoshop Extract Assets

Adobe Photoshop CC has a feature called Extract Assets (File → Extract Assets) which utilizes Adobe Generator. You can generate JPEG, PNG, GIF, or SVG image assets from the contents of a layer or layer group in a PSD file when you export to Reflow. Choosing File → Extract Assets allows you to optimize assets, setting sizes, formats, and more. After setting up the optimization settings, your layer names are altered, adding a supported extension for an image format (PNG, GIF, JPG, or SVG) to a layer name or a layer group name. Generator will create the images used in Reflow and free us from having to slice in most cases (yay!). Even if you wind up not using Reflow, Extract Assets is worth a look. You can then export to Reflow and the optimized assets will be automatically generated.

Named layers in Photoshop CC 2014.6
Named layers in Photoshop CC 2014.

With the content named in the Layers panel, you can finally breathe responsiveness into your Photoshop file by exporting to a Reflow project file (File → Generate → Edge Reflow Project). When it’s complete, a folder will be generated in the same folder as the PSD. This folder contains a Reflow project (.rflw), as well as the generated assets in an assets folder.

The generated content after exporting to Reflow from Photoshop.
The generated content after exporting to Reflow from Photoshop.

Toss It Over To Reflow

After you export from Photoshop, you can open the Reflow project file (.rflw) in Edge Reflow to see what was created. If any fonts are missing, Reflow will show a prompt allowing you to fix them with Typekit fonts, Edge Web Fonts, web-safe fonts or local fonts.

Dialog for missing fonts in Edge Reflow CC.7
Dialog for missing fonts in Edge Reflow CC. (View large version8)

The Photoshop content was converted to HTML and CSS according to the original content (text, vector, raster) and the layer structure in Photoshop. If you click the Elements panel icon on the right, you will see the code (DOM) for the HTML that has been generated. If you look at the structure and naming, you will see that it is loosely based on the Layers panel in Photoshop. You will find that hidden content is ignored and that groups (the folders) are also ignored, but that the content within is not. Also, text is still editable (in most cases), and named vector content and raster content are now raster images.

The Elements panel in Reflow showing the DOM.9
The Elements panel in Reflow showing the DOM. (View large version10)

The code that is generated uses HTML5 Boilerplate for a CSS “normalize” sheet, but the layout really isn’t based on an existing framework, such as Twitter’s Bootstrap. Below is an example of code generated for the <head> of a page when exported.

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="boilerplate.css">
    <link rel="stylesheet" href="page.css">
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0">
  </head>
  <body>
  …

The image content that is generated from your named layers in Photoshop is in the assets folder (as we saw earlier) and can be found in the Asset Library panel on the right in Reflow. The Asset Library panel shows all images in the assets folder, even those not currently in the design, and it functions similarly to the Links panel in InDesign and Illustrator. You can tell which images are not being used in your design because they have a number 0 to the right of their name in the panel. In this panel, you can search for assets, replace assets, update assets and more.

Asset Library panel in Reflow.11
Asset Library panel in Reflow. (View large version12)

The Photoshop CC Connection

Once you export from Photoshop CC, the connection to your Photoshop design is still somewhat alive in Reflow. I say “somewhat” because any changes to generated image content made in Photoshop (and that you named in the Layers panel) can be updated in Reflow. Text, page elements and other unnamed content will not.

In Reflow, the Photoshop CC Connect panel (on the right) is where you will see the connection to Photoshop. If Photoshop CC is open, then the panel will show you that Reflow is connected to whatever file is open in Photoshop. This threw me at first. You could have a PSD open in Photoshop that has nothing to do with the Reflow design, and it will still show you that it’s connected.

“Connected” can mean a few things. You can open the PSD file that the Reflow project was created from and make updates, which in turn will update the applicable content in Reflow. You can open a different PSD (or even show a different layer comp) — say, for a new page on the website — and create a new page from that PSD content by clicking the “Create New Page” button in Reflow. You can even open a PSD file and simply generate the named layer content and save it into the project’s assets folder (maybe from a PSD that contains icons or other elements) by clicking the “Import Assets” button in Reflow.

Photoshop CC Connect panel in Reflow.13
Photoshop CC’s Connect panel in Reflow. (View large version14)

To make changes to the design in Photoshop and update the Reflow project, you will first need to turn on “Photoshop Asset Sync” (an arrow is pointing to it in the following screenshot). You can then open the PSD in Photoshop and make changes to the design, and any named layer content that is generated by Photoshop Generator will need to be updated in the Asset Library panel in Reflow (circled below).

Updating Photoshop content in turn updates Reflow content.15
Updating Photoshop content in turn updates Reflow content. (View large version16)

Adding And Editing Breakpoints

By default, your project in Reflow contains no breakpoints (i.e. media queries) and is a purely fluid design (set to percentage widths, with no maximums or minimums). It’s your job to add breakpoints where you see fit (usually where the design falls apart). Clicking the “+” (plus) button in the upper-right corner will add an initial breakpoint (which is a good idea). If you click and hold down “+” in the upper-right corner, a menu will appear that lists all of the breakpoints. Here is where you can edit an existing breakpoint (the value or the label) or delete a breakpoint. You can also set the breakpoints (media queries) to be either minimums or maximums (one or the other).

I really wish Reflow would take media queries further, allowing for a mixture of max/min or other types of media queries (think Retina), but at its core, it’s a visual responsive design tool meant to prototype.

Editing breakpoints for a Reflow project.17
Editing breakpoints for a Reflow project. (View large version18)

If you drag the gripper bar on the right edge of the page’s content to the right or left, you will see how the design responds. When you need to make a design change, click “+” to set a new breakpoint. Click on the colored bars above the ruler (indicating a breakpoint) to resize the design to that breakpoint.

The handles for setting breakpoints and resizing in the design.19
The handles for setting breakpoints and resizing in a design. (View large version20)

Adding and deleting breakpoints are easy, but there is a catch in Reflow (and other programs like this). If you go to make a design change, make sure to select the correct breakpoint! If not, it’ll bite you at some point because undoing in Reflow (Edit → Undo) still needs some work.

How Reflow Interprets Your Design (Floats, <div>s, Etc.)

With the Selection tool selected in the Tools panel (by default), you can select content on the page. All of your page’s content lies within a primary container (<div>) that is set to center horizontally and that has a 100% width. Shapes in Photoshop typically become <div>s in Reflow; text becomes <p> elements with styles applied; images become either regular images or background images, and so on. Almost all of the content in your Reflow project will be positioned using the CSS properties float: left and margin. Knowing this is important when you attempt to edit the design in Reflow by simply dragging content. I’ve seen a lot of people get tripped up if they haven’t learned the basics of layout, including margins, padding and floating.

The layout editing and formatting controls are found in the Layout and Styling panels on the left. The Layout panel is where you will find typical CSS properties like sizing (including maximum and minimum widths and heights), margins and padding, positioning, floats, clears and more. The more advanced formatting options are hidden initially in the Advanced section of the Layout panel. In Reflow, most people either use a combination of dragging and sizing the content manually or adjusting the layout options “by the numbers” in the Layout panel.

The layout options in Reflow.21
The layout options in Reflow. (View large version22)

Styling options for text formatting, backgrounds, shadows, rounded corners and more are found in the Styling panel on the left. Text formatting is relatively straightforward, and Reflow allows you to use Edge Web Fonts, web-safe fonts, fonts on your hard drive, and fonts via a Typekit kit that you create. The Styling panel is where you also go to add rounded corners, borders and drop-shadows and to edit the opacity of other objects as well.

Font formatting and other styling options.23
Font formatting and other styling options. (View large version24)

If you’ve designed to a grid in Photoshop or you know that the goal for the project is to work with a particular grid or framework, then you can edit the visible grid in Reflow to match. With nothing selected (by clicking in a blank area of the design area), you will see the grid settings below the Tools panel in the upper-left corner. Of course, the grid in Reflow is merely a guide. It doesn’t generate a series of CSS styles, such as for fluid grids.

Settings for the grid in Reflow.25
Settings for the grid in Reflow. (View large version26)

Editing The DOM

As mentioned, you can see the HTML structure in the Elements panel on the right side of the workspace. In that panel, you can hover over an element to see the corresponding content in the design (it will be highlighted) and click to select it. The eye icon in the Elements panel is a toggle for the display CSS property. Renaming content in the panel will change the name of the ID applied to the HTML object (as you can see in the screenshot below). Yes, I said ID. Reflow doesn’t generate classes in the CSS, and currently there is no way to add a style name or change the type of style (to a class, for instance). This is limiting, because you can’t inject any code (any code — even JavaScript) or make actual style changes outside of what the program can do. You need to export the code and take it somewhere else with no chance of bringing that code back in.

Editing the DOM using the Elements panel in Reflow.27
Editing the DOM using the Elements panel in Reflow. (View large version28)

You can also organize content in the Elements panel by dragging content, which will directly affect the HTML’s ordering and layout. You cannot nest content within, say, a new <div> using the Elements panel, but content that is nested may be moved out or moved between those groups. To nest selected content in a parent element (a <div>) to make a column, for instance, you could use the menu item Edit → Add Parent or even group the selected content (Edit → Group).

Selected content in the design (left) after choosing Edit → Add Parent to add a parent div to the content.29
Selected content in the design (left) after choosing Edit → Add Parent to add a parent <div> to the content (View large version30)

Note: Clicking the “Page” element in the Elements panel allows you to edit the layout and styling properties of the <body> tag. Clicking the “Container” element allows you to edit the properties of the main containing <div> that all content is within by default.

Creating Pages

You can create pages in your Reflow project using the Page menu, Photoshop’s Assets panel (by clicking the “Create New Page” button) or the super-simple Pages panel on the right side of the workspace. In the Pages panel in Reflow, you can either duplicate a page or add a new blank page. If you duplicate a page, it will have no connection to the original page except for the images (which are linked to the same source images). In later builds of Reflow, thankfully, breakpoints are copied in duplicate layouts. If you create a series of pages that share navigation or footer content, the only real way (currently) to update that content on all pages is to go to each and make the changes, or to copy and paste the content from one page to the next. There are no such things as library items, symbols, or whatever you would call them to edit shared content in one place.

Duplicating a page in the Pages panel in Reflow.31
Duplicating a page in the Pages panel in Reflow. (View large version32)

Each page in Reflow becomes a separate HTML page that gets its file name from the page’s name in the Pages panel. Each page has its own CSS file, and formatting that is the same across pages is not pulled into a shared CSS; it’s simply duplicated across multiple CSS files. The screenshot below shows what was generated when I chose File → Export For Code Editor.

What is generated when I create a Reflow project and duplicate the only page.33
What is generated when I create a Reflow project and duplicate the only page. (View large version34)

Working With Images

Within Reflow, you can insert PNG, GIF, JPEG and SVG images by dragging images into the design from the Assets panel or from a folder on your hard drive or by using the Add An Image tool to click and add an image. If you use the Add An Image tool, then you would choose an image and, with the place gun, click and place the image where you’d like.

Note: The best practice is to put images in the assets folder that was generated by Reflow when you exported from Photoshop. If you insert an image in the design using the Add An Image tool that is outside of the assets folder, then it will be copied there.

Reflow also allows for multiple layered background images (and solid-color and gradient backgrounds), and it supports the most widely used CSS3 properties for adjusting the background images.

A few of the CSS3 properties for background images in Reflow.35
A few of the CSS3 properties for background images in Reflow. (View large version36)

One of my favorite commands in Reflow is to select an image on the page (not a background image), right-click on it and choose “Move to New Box Background.” This will remove the <img> tag from the HTML, insert a <div> instead and creates a style with the same image but as a background image. You can even right-click on an image in the Asset Library panel and choose “Set as Background” for a selected object.

Converting an image to a background image in Reflow.37
Converting an image to a background image in Reflow. (View large version38)

Note: Currently, there is no mechanism for working with Retina images in Reflow.

Creating Forms

I wanted to add a section on working with forms, not to show how to insert them, but to discuss what they are and aren’t. The Form tools are found in the Tools panel. If you click and hold down the “Add a Button” button, you will see them all. By clicking or clicking and dragging, you can position and format each field pretty simply using the same properties as in the Layout and Styling panels.

The form tools in Reflow.39
The form tools in Reflow. (View large version40)

The form you create in Reflow will not submit data. That’s because the tools will create form tags like <input> and <select> but will not add an actual <form> element to the code, which means you can’t set typical options for the <form> tag in Reflow by default (such as method and action). A form in Reflow can be used only as a visualization or starting point, to be edited in another program later.

Below is an example of code generated for a simple form created in Reflow.

<label id="formgroup">
  <p id="text">Name</p>
  <input id="textinput" type="text" value="Name">
</label>
<label id="formgroup2">
  <p id="text2">Sign up?</p>
  <select id="select" type="select">
    <option>Choose one</option>
    <option>Yes</option>
    <option>No</option>
  </select>
</label>
<input id="input" type="button" value="Submit">

Edge Inspect Testing

Built in to Reflow is the ability to test on devices using Adobe Edge Inspect CC. Edge Inspect allows you to preview Edge Reflow content across multiple devices. Simply test the page, take screenshots from any connected device, and then see real-time results of changes to the design.

Using Edge Inspect in Reflow to inspect a design.41
Using Edge Inspect in Reflow to inspect a design. (View large version42)

Note: To preview Reflow content on a device, you’ll need to download Edge Inspect to your computer and then install the Edge Inspect CC app on an approved device (iOS, Android or Kindle Fire).

What Reflow Doesn’t Do

If you are using the program to create quick comps as a visual aid, then Reflow might work. But if you dig into the program and want to use the code that is generated, then be aware of what it can and can’t do. The things listed below are the major things it can’t do (as with any program, there are little things we each wish it could do, I know).

What About the Code It Generates?

The styling it generates is not very succinct, and IDs are used for just about everything. You can’t insert your favorite jQuery slideshow or other code in Reflow because code currently can’t be injected. Reflow does not really support much in the way of SEO content (who needs that anyway?), tables or lists. You can’t edit its CSS (the actual code) unless you make changes in the Styling panel. You also can’t add a blog or e-commerce functionality in Reflow (because code can’t be inserted).

Nick Halbakken’s good Q&A with the Adobe Reflow team43 answers some of these questions.

What Can You Do With the Design?

As you edit a design, you can preview in two WebKit-based browsers (Safari and Chrome) by choosing View → Preview In… The code is not optimized for non-WebKit browsers. When you preview a page, the HTML and CSS are generated (this is how we used to get at the code if we wanted to use what Reflow generates). In later builds of Reflow, you can export the code by selecting File → Export for Code Editor. Exporting the code removes a line from the code stating that it’s only meant to be used for previewing, and then a copy of the content is created in a new folder of your choosing, and an HTML file is dumped in, which you will use as a frame for the pages when previewing.

If the code is not suitable for your production environment, then you can copy and paste CSS snippets from within Edge Reflow (this is how I use it, if at all). When you select content, you can click the “< >” icon in the tag selector at the bottom of the document’s window (an arrow is pointing to it in the screenshot below). This will display the CSS associated with the selected object, even giving you the CSS for each media query that affects the selected object. Click the clipboard icon at the bottom of the menu to copy all of the CSS, or click the clipboard icon for the CSS that you hover over to select just that code.

Copy CSS from Reflow.44
Copy CSS from Reflow. (View large version45)

Final Notes

There you have it: a quick-ish tour of the features in Edge Reflow CC. I know that this program can be polarizing, especially for those of us who can code. But I do have a use for this program in some of my projects. Would I use the code? Most likely not. But that’s also because my themes and frameworks are dialed in to how I like to create websites. I find it useful for my designers to use for quick prototypes or wireframing, mostly when they start the design in Photoshop. I also like to use it to see those niggly little text formatting properties that designers pore over, like line-height.

The program has a long way to go before its code can be used as is in a production workflow. I can’t tell you the ultimate direction it’s headed in — will it eventually integrate with an existing framework as a building point, or will it let you inject code? Will it survive the crush of tools coming out today or be an experiment that gets scrapped? — it’s a risk we all take with tools these days. In my opinion, for it to be a one-stop shop tool to build sites in, it would have to come a long way from where it is now.

Where to go from here? Here are several resources to learn more about working with Edge Reflow CC:

(da, ml, al, og)

Footnotes

  1. 1 http://www.smashingmagazine.com/2014/05/23/next-generation-responsive-web-design-tools-webflow-edge-reflow-macaw/
  2. 2 http://www.smashingmagazine.com/wp-content/uploads/2014/10/01-reflow-workspace-opt.png
  3. 3 http://www.smashingmagazine.com/wp-content/uploads/2014/10/01-reflow-workspace-opt.png
  4. 4 http://www.smashingmagazine.com/wp-content/uploads/2014/10/02-photoshop-opt.png
  5. 5 http://www.smashingmagazine.com/wp-content/uploads/2014/10/02-photoshop-opt.png
  6. 6 http://www.smashingmagazine.com/wp-content/uploads/2014/10/03b-photoshop-name-layers-opt.jpg
  7. 7 http://www.smashingmagazine.com/wp-content/uploads/2014/10/05-reflow-missing-font-dialog-opt.png
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2014/10/05-reflow-missing-font-dialog-opt.png
  9. 9 http://www.smashingmagazine.com/wp-content/uploads/2014/10/06-reflow-element-panel-opt.png
  10. 10 http://www.smashingmagazine.com/wp-content/uploads/2014/10/06-reflow-element-panel-opt.png
  11. 11 http://www.smashingmagazine.com/wp-content/uploads/2014/10/07-reflow-asset-library-panel-opt.png
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/10/07-reflow-asset-library-panel-opt.png
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2014/10/08-reflow-connect-panel-opt.png
  14. 14 http://www.smashingmagazine.com/wp-content/uploads/2014/10/08-reflow-connect-panel-opt.png
  15. 15 http://www.smashingmagazine.com/wp-content/uploads/2014/10/09-reflow-update-photoshop-content-opt.png
  16. 16 http://www.smashingmagazine.com/wp-content/uploads/2014/10/09-reflow-update-photoshop-content-opt.png
  17. 17 http://www.smashingmagazine.com/wp-content/uploads/2014/10/10-reflow-editing-breakpoints.png
  18. 18 http://www.smashingmagazine.com/wp-content/uploads/2014/10/10-reflow-editing-breakpoints.png
  19. 19 http://www.smashingmagazine.com/wp-content/uploads/2014/10/11-reflow-resize-handle-opt.png
  20. 20 http://www.smashingmagazine.com/wp-content/uploads/2014/10/11-reflow-resize-handle-opt.png
  21. 21 http://www.smashingmagazine.com/wp-content/uploads/2014/10/12-reflow-layout-options-opt.png
  22. 22 http://www.smashingmagazine.com/wp-content/uploads/2014/10/12-reflow-layout-options-opt.png
  23. 23 http://www.smashingmagazine.com/wp-content/uploads/2014/10/13-reflow-font-formatting-opt.png
  24. 24 http://www.smashingmagazine.com/wp-content/uploads/2014/10/13-reflow-font-formatting-opt.png
  25. 25 http://www.smashingmagazine.com/wp-content/uploads/2014/10/14-reflow-grid-setting-opt.png
  26. 26 http://www.smashingmagazine.com/wp-content/uploads/2014/10/14-reflow-grid-setting-opt.png
  27. 27 http://www.smashingmagazine.com/wp-content/uploads/2014/10/15-reflow-editing-dom-opt.png
  28. 28 http://www.smashingmagazine.com/wp-content/uploads/2014/10/15-reflow-editing-dom-opt.png
  29. 29 http://www.smashingmagazine.com/wp-content/uploads/2014/10/16-reflow-selected-content-opt.png
  30. 30 http://www.smashingmagazine.com/wp-content/uploads/2014/10/16-reflow-selected-content-opt.png
  31. 31 http://www.smashingmagazine.com/wp-content/uploads/2014/10/17-reflow-duplicating-page-opt.png
  32. 32 http://www.smashingmagazine.com/wp-content/uploads/2014/10/17-reflow-duplicating-page-opt.png
  33. 33 http://www.smashingmagazine.com/wp-content/uploads/2014/10/18-reflow-project-generation-opt.png
  34. 34 http://www.smashingmagazine.com/wp-content/uploads/2014/10/18-reflow-project-generation-opt.png
  35. 35 http://www.smashingmagazine.com/wp-content/uploads/2014/10/19-reflow-css3-properties-opt.png
  36. 36 http://www.smashingmagazine.com/wp-content/uploads/2014/10/19-reflow-css3-properties-opt.png
  37. 37 http://www.smashingmagazine.com/wp-content/uploads/2014/10/20-reflow-convert-image-opt.png
  38. 38 http://www.smashingmagazine.com/wp-content/uploads/2014/10/20-reflow-convert-image-opt.png
  39. 39 http://www.smashingmagazine.com/wp-content/uploads/2014/10/21-reflow-form-tools.png
  40. 40 http://www.smashingmagazine.com/wp-content/uploads/2014/10/21-reflow-form-tools.png
  41. 41 http://www.smashingmagazine.com/wp-content/uploads/2014/10/22-reflow-edge-inspect.jpg
  42. 42 http://www.smashingmagazine.com/wp-content/uploads/2014/10/22-reflow-edge-inspect.jpg
  43. 43 http://blogs.adobe.com/edgereflow/2014/05/07/q-a-from-talk-to-the-team/
  44. 44 http://www.smashingmagazine.com/wp-content/uploads/2014/10/23-reflow-copy-css.png
  45. 45 http://www.smashingmagazine.com/wp-content/uploads/2014/10/23-reflow-copy-css.png
  46. 46 http://www.lynda.com
  47. 47 http://tv.adobe.com/watch/learn-edge-tools/what-is-edge-reflow/
  48. 48 https://www.youtube.com/user/askbrianwood

The post A Deep Dive Into Adobe Edge Reflow appeared first on Smashing Magazine.

Continued:  

A Deep Dive Into Adobe Edge Reflow

Thumbnail

Controlling The Cache: Using Edge Side Includes In Varnish

I’m a firm believer that the best way to optimize for fast-loading mobile sites is to optimize for everyone. We don’t know when someone is on a non-mobile device but tethered to their phone, or just on awful Wi-Fi.

In a previous article for Smashing Magazine1 I explained how you can speed up your websites by serving dynamic pages from a reverse proxy like Varnish. If you are new to Varnish then that article is the place to start as I’ll be diving straight into configuration details here.

In this article I’ll explain how you can benefit from using Varnish even when there are parts of your pages that can’t be cached for long periods, using Edge Side Includes.

The Problem With Caching

The bulk of most web pages is content that doesn’t change very often. Generally, when you publish some content it remains fairly static, and even if it is updated, taking a few minutes before the new version appears may not be a problem. If it is vital that the cache is invalidated on publish, you can use cache invalidation2 to clear that page from the cache. However, there might be some content that you do not want to cache at all, such as personalized content. There may also be content that you would like to cache but for shorter periods of time, perhaps a news widget that updates very frequently. When pages contain this type of content you might think they are uncachable. It is here, though, that Edge Side Includes (ESI) can save the day – and your site performance.

What Are Edge Side Includes?

ESI3 is a language specification for assembling fragments of web pages inside other web pages. The specification was submitted to the W3C in 2001, but remains a “W3C Note” made available for discussion and not endorsed by the W3C or updated by a Working Group.

ESI works in a similar way to other methods of including fragments in your pages, such as Server Side Includes (SSI) or PHP include statements, but it has been designed for reverse proxies like Varnish that sit in front of a web server and cache content.

How Does ESI Work With Varnish?

Varnish has implemented a subset of ESI features, three of the available seven statements. The supported statements are listed in the Varnish documentation4. This means that we can use ESI on our pages and tell Varnish to cache an include for a shorter time than the main document, or even not cache the include at all. If you are already up and running with Varnish, it’s really simple to get going with ESI and make a huge difference to your hit rate: the number of pages served from the cache.

An Example

If you want to follow along and don’t have a Varnish install to play with, you can download my Vagrant package from GitHub5 which will install a basic LAMP server and Varnish. Have a look at the README on GitHub to see how to configure that for your environment.

I have a layout using an open source Bootstrap template, which is a standard blog layout. In the sidebar I intend to place some content that will be frequently updated and I want to ensure that it is not cached for too long. The blog post and other content I want to be cached for several minutes, as it won’t change often.

Screenshot of the initial layout6
The layout I am working with as an example. (View large version7)

Make The Sidebar An Include

The first thing to do is make the sidebar a PHP include. I save the include as inc/sidebar.php and then add a PHP include to the main page to include it. My page looks the same but the content of the sidebar is now separated into an include.

In my main page and in my include I am outputting the current date and time. This just helps me see whether my cache is working. If I was doing no caching, each time I reload the page I would expect the time to change. With Varnish in a default state both times should be the same, and they will update only when the cache clears.

Screenshot with date and time8
The times change on page reload and should be the same. (View large version9)

Include The File Using ESI

I’m now going to use two ESI tags that are supported by Varnish:

esi:include
esi:remove

The esi:include tag is used to include the file via ESI. So I replace my PHP include with this:

<esi:include src="inc/sidebar.php"/>

Create A Fallback When ESI Are Not Available

Straight after the esi:include tag we add esi:remove tags, and inside those tags is the original PHP include. While testing I have also added the line “Not ESI!” so that I can see if the include is being added by PHP or by ESI.

<esi:include src="inc/sidebar.php"/>
<esi:remove>
  <?php include('inc/sidebar.php'); ?>
  <p>Not ESI!</p> 
</esi:remove>

If you now load the page on a server running Varnish that does not have ESI configured you should see the “Not ESI!” text. ESI isn’t running so the original PHP include will be loaded.

The esi:remove tags enable you to create a fallback for situations where Edge Side Includes are not available. This might be because Varnish hasn’t been configured to use them for that page, or you are serving the site directly through Apache, as might be the case in development.

Where ESI are available the entire <esi:remove></esi:remove> block is removed from the page when includes are parsed. The use of the esi:remove statement doesn’t stop the PHP code from being executed. It will still be executed each time the page is loaded if ESI is not available, and according to caching policy if it is.

An alternate option to using esi:remove is to use the third statement supported by Varnish, <!--esi … -->. You would use this if you want nothing to happen when ESI is not available.

<!--esi <esi:include src="inc/sidebar.php"/>  -->

In the above case, if ESI were unavailable the sidebar would not be loaded – the browser treats the statement as an HTML comment – so nothing would be visible to a site visitor. If processed by ESI, the comments would be removed and the include parsed.

Configure Varnish To Use ESI

We tell Varnish to use ESI in our VCL, within a vcl_backend_response subroutine.

sub vcl_backend_response  
  set beresp.do_esi = true;  

Note: in Varnish 3 you would put this inside sub vcl_fetch. See the other differences between Varnish 3 and 4 in these upgrading notes10.

If you restart Varnish and reload your page you should find that the “Not ESI!” text has gone, and if you View Source there is no trace of the includes but the sidebar is being included. Our times should remain the same, however, as we are still caching both parts of the page in the same way.

Tweak The TTL

I want my sidebar to only be cached for 30 seconds before it is refreshed, and my main content 120 seconds. Inside the vcl_backend_response subroutine add the following:

if (bereq.url ~ "sidebar.php")  
  set beresp.ttl = 30s;  else  
  set beresp.ttl = 120s; 

Here I am saying that if the URL matches the string sidebar.php cache only for 30 seconds, otherwise cache for 120 seconds.

Save the VCL and restart Varnish, then reload your page – both times should be the same. Wait 30 seconds and reload the page – the sidebar time should update but the main time remain the same. You are now caching these page components differently and assembling the page with ESI.

Screenshot after adding ESI11
The layout after adding ESI, page components being cached differently. (View large version12)

The value passed to bereq.url is a regular expression. Something you might like to do is put files that are uncachable or have a common TTL into one folder, then target that folder.

if (bereq.url ~ "^/inc")  
  set beresp.ttl = 30s;  else  
  set beresp.ttl = 120s; 

There are some more examples of simple expressions on the Fastly regular expression cheat sheet13.

Set Some Content To Never Cache

If there is an include that you never want to be cached (for example, if it contains some personalized content), you can selectively flag things as uncacheable and deliver them directly from the web server.

I have a folder named personalized and I want any includes inside that folder to be served from the web server directly, bypassing the cache. I can do this using a similar if statement to the one I used to set the TTL, again in vcl_backend_response.

if (bereq.url ~ "^/personalized") 
  set beresp.uncacheable = true; 
  return(deliver); 

The line return(deliver); means that the content bypasses the cache altogether and will always be served fresh, while the rest of the page gets served from the cache. You can test this by creating an include, again with a time on it, and placing it in the personalized folder.

<esi:include src="personalized/panel.php"/>  
<esi:remove>  
  <?php include('personalized/panel.php'); ?>
</esi:remove>

This content should always show an updated time as it is served from the cache.

The full VCL can be found on GitHub. You can try different combinations of ESI to meet your own caching requirements.

Further Reading

Edge Side Includes can be a powerful way to tweak the performance of Varnish. How you use them, though, is likely to be very specific to your own site. Hopefully this article has highlighted some of the possibilities. To finish, here are some links that I’ve looked at while writing this tutorial and some which detail implementation for various CMSs. Check carefully which version of Varnish the article refers to – there is a lot of Varnish 3 or even Varnish 2 information about and the syntax has changed significantly. However, converting from one to the other is generally straightforward.

(da, ml, og)

Footnotes

  1. 1 http://www.smashingmagazine.com/2013/12/04/speed-up-your-mobile-website-with-varnish/
  2. 2 http://www.smashingmagazine.com/2014/04/23/cache-invalidation-strategies-with-varnish-cache/
  3. 3 http://www.w3.org/TR/esi-lang
  4. 4 https://www.varnish-cache.org/docs/4.0/users-guide/esi.html
  5. 5 https://github.com/rachelandrew/varnish4-vagrant
  6. 6 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure1-opt.png
  7. 7 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure1-opt.png
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure2-opt.png
  9. 9 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure2-opt.png
  10. 10 https://www.varnish-cache.org/docs/trunk/whats-new/upgrading.html
  11. 11 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure3-opt.png
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/12/figure3-opt.png
  13. 13 https://docs.fastly.com/guides/vcl-faqs/vcl-regular-expression-cheat-sheet
  14. 14 http://blog.lavoie.sl/2013/08/varnish-esi-and-cookies.html
  15. 15 http://timbroder.com/2012/12/getting-started-with-varnish-edge-side-includes-and-wordpress.html
  16. 16 https://ellislab.com/blog/entry/making-sites-fly-with-varnish
  17. 17 https://www.drupal.org/project/esi
  18. 18 http://blog.redfin.com/devblog/2010/05/esi_and_caching_trickery_in_varnish.html#.VHyL8IeAYio

The post Controlling The Cache: Using Edge Side Includes In Varnish appeared first on Smashing Magazine.

Follow this link:  

Controlling The Cache: Using Edge Side Includes In Varnish

Thumbnail

Designers: Start Coding With uilang

Editor’s Note: Designers could learn how to code, and developers could learn how to design. Sometimes it might not be an option. In this article, the author makes a suggestion to designers without coding skills on how to start crafting code. You might want to take the suggested tool with a grain of salt (or not) but the idea might be worth looking into.

Designers have widely adopted HTML and CSS for a while now. They usually feel comfortable enough to implement their own designs, at least in a static form. However, they’re often intimidated by JavaScript — and rightly so! HTML and CSS are declarative and, I’d argue, closer to design than programming.

JavaScript, on the other hand, is “real” programming. This means you not only have to learn a whole new and complex syntax but also have to “learn how to think.” The barriers to entry are high and prevent many designers from taking the plunge. uilang1 tries to fix that.

This article will introduce you to uilang’s philosophy and syntax. We’ll start with a simple example to get you comfortable with the basics, before moving to something more exciting. At the end of this tutorial, you’ll (hopefully!) be able to code many typical interface widgets, such as popovers, tabs, overlays and much, much more.

The Bridge Between Designers And Developers

I strongly believe that designers should code the interfaces they design. They shouldn’t necessarily write production-ready code, but they should design the behaviors. Designers love these things. They could spend hours tweaking an animation delay or finding the right cubic-bezier curve. They usually just lack some technical skills to do so.

uilang tries to facilitate the communication between designers and developers by giving designers an extremely simple tool to prototype their interfaces. uilang reads like plain English, uses a one-line syntax declared right in the HTML and provides very few options in order to make its learning process and adoption as fast and easy as possible. We’ll cover the syntax in detail later, but here’s a sneak peek at it:

clicking on "button" toggles class "visible" on "div"

uilang is not exclusively a prototyping tool, though. It can safely be used on production websites to create, for example, tabs, photo galleries, popovers and more. Let’s see how it works!

Getting Started

uilang is based on a dead simple principle: manipulating classes on your elements. By just adding and removing classes when something is clicked, we can show, hide, transform and animate elements using CSS. This simple logic gives you endless possibilities. Let’s explore one of them by creating a simple notification banner like this:

See the Pen bNWaVz2 by Benjamin De Cock (@bdc3) on CodePen4.

We’ll start with the HTML markup, which is pretty straightforward:

<div id="notification">
  <p>You have 3 unread messages.</p>
  <button class="hide">Hide</button>
</div>

We’ll now use uilang to define a simple behavior: When the user clicks on an element that has a hide class, we’ll add a hidden class to the element that has a notification ID. The translation in actual uilang code looks almost the same as the explanation above:

clicking on ".hide" adds class "hidden" on "#notification"

This line of code should be written in a simple <code> element, right in the
HTML. uilang will automatically find the <code> element containing your
code and will ignore other <code> elements that you might have on the page.
Additionally, you’ll have to download and insert the uilang.js library5 (1 KB).

While both your <code> and <script> elements can
theoretically be inserted anywhere on the page, it’s recommended to place them at the very end of the document, just before the closing </body> tag:

<body>
  <!-- Your content -->

  <script src="uilang.js"></script>

  <code>
    <!-- Your uilang code -->
  </code>
</body>

By respecting that order, you’re making sure to reach the best rendering performance. Thereby, your final HTML markup for the notification banner will look like this:

<body>
  <div id="notification">
    <p>You have 3 unread messages.</p>
    <button class="hide">Hide</button>
  </div>

  <script src="uilang.js"></script>

  <code>
    clicking on ".hide" adds class "hidden" on "#notification"
  </code>
</body>

We’re almost done! Now that the behavior has been defined, we’ll rely on CSS to fade out that notification banner once the hidden class has been applied to it:

#notification 
  transition: .8s

#notification.hidden 
  opacity: 0

Congrats! You now know how to code! You might not realize it yet, but this simple logic will let you build a wide range of widgets and interactions. Let’s have a closer look at the options provided by the syntax.

Syntax

The syntax can be split into four parts:

clicking on ".hide"(1) adds(2) class "hidden"(3) on "#notification"(4)
  1. any CSS selector
  2. adds, removes or toggles
  3. any class name
  4. any CSS selector or the target keyword (which selects the clicked element)

That’s all you need to learn. Keep in mind that uilang is basically just HTML, so you can comment the code similarly:

<code>
  <!-- I'm a comment -->
  clicking on ".hide" adds class "hidden" on "#notification"

  <!-- I'm another comment -->
  clicking on "li a:first-child" toggles class "active" on "target"
</code>

Please note that uilang only supports click events. Hover effects can usually be achieved in CSS, and other events are simply beyond the scope of this language.

We’ve now covered the basics of uilang. It’s time to build a more advanced demo!

Apple-Like Explore Menu

We’ll create a collapsible, animated menu similar to the kind you can find on Apple’s website6. Check out the demo117 to see the result.

uilang demo: explore menu8
(See large version9)

HTML Markup

Nothing fancy, really, just a simple link to toggle the navigation, and the nav element containing our list of links:

<a class="explore" href="#">Explore</a>

<nav>
  <ul>
    <li>
      <a href="#"><img alt src="images/1.jpg">West Coast</a>
    <li>
      <a href="#"><img alt src="images/2.jpg">Venice</a>
    <li>
      <a href="#"><img alt src="images/3.jpg">Peyto Lake</a>
    <li>
      <a href="#"><img alt src="images/4.jpg">Iceland</a>
    <li>
      <a href="#"><img alt src="images/5.jpg">Golden Gate</a>
  </ul>
</nav>

Now, adding the toggling behavior with uilang will be extremely simple:

<code>
  clicking on ".explore" toggles class "open" on "nav"
</code>

We’ll then use this open class in our style sheet to show and hide the nav. Just before we do that, let’s add a few things to complete our HTML markup: a meta tag for mobile users, the link to our style sheet and, obviously, the uilang.js library! The whole HTML might now look like this:

<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1">
<title>Explore menu</title>
<link rel="stylesheet" href="style.css">

<a class="explore" href="#">Explore</a>

<nav>
  <ul>
    <li>
      <a href="#"><img alt src="images/1.jpg">West Coast</a>
    <li>
      <a href="#"><img alt src="images/2.jpg">Venice</a>
    <li>
      <a href="#"><img alt src="images/3.jpg">Peyto Lake</a>
    <li>
      <a href="#"><img alt src="images/4.jpg">Iceland</a>
    <li>
      <a href="#"><img alt src="images/5.jpg">Golden Gate</a>
  </ul>
</nav>

<script src="uilang.js"></script>

<code>
  clicking on ".explore" toggles class "open" on "nav"
</code>

Note: For those wondering about the brevety of the code, keep in mind HTML5 considers as optional the <html>, <head> and <body> tags. Feel free to adopt a different style if you have another preference!

CSS: Where The Magic Happens

As always with uilang, the interesting parts of the code are in the style sheet. uilang’s role is exclusively to define the behaviors, not to execute them.

Let’s start by styling and positioning our elements, so that our navigation is ready to be manipulated with uilang. I won’t go into much detail — I assume you’re already comfortable with basic, standard CSS — so I’ve only commented some parts of the code. Please note that irrelevant style declarations, such as for fonts and colors, have been omitted for clarity.

body 
  background: #f3f3f3;


.explore 
  /* Make sure the Explore link stays above the nav */
  position: absolute;
  z-index: 1;


nav 
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.15);


nav ul 
  /* Allow mobile-friendly horizontal scrolling when the browser isn't wide enough */
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  /* Force the thumbs to display in a row */
  white-space: nowrap;
  padding: 80px 40px 40px;


nav li 
  display: inline-block;

Onto the interesting part: coding the toggling behavior! We’ll need two things:

  1. By default, the nav and the thumbs should be hidden. This means we need to initially slide up the nav and make the nav and images transparent.
  2. When the open class defined in our uilang code is applied to the nav, we need to reverse the default state: slide down the nav and fade in everything.

Step 1 is pretty easy: We’ll use translateY(-100%) to slide the nav up, opacity: 0; to hide the nav and images, and transition to animate these elements when the class is applied.

nav, nav li 
  opacity: 0;


nav 
  -webkit-transform: translateY(-100%);
  transform: translateY(-100%);
  transition: .4s;


nav li 
  transition: .3s;

This is not immediately related to uilang but, because uilang does rely on CSS for transitions and animations, we should probably remember a few important principles:

  • You can safely and smoothly animate only two properties: opacity and transform. Force yourself to stick with them.
  • When only the duration is specified in the transition shorthand property, all properties that might change in future will be animated and will use ease as their timing function.
  • Keep your animations fast! Animations are important because they help users to understand the flow between two states, but they should never get in the way. A good transition-duration is usually between 200 and 800 milliseconds.
  • While standard easing keywords are sometimes acceptable (such as with this demo), custom cubic-bezier curves are often preferable. Many tools enable you to find the right curve, such as Matthew Lein’s Ceaser10.
  • The examples in this tutorial use CSS transitions, but feel free to use CSS animations instead when needed! The principle is exactly the same, and keyframes might provide a finer level of control.

Now that our default state has been set up, we can go to step 2 and code the “open” state, which basically means reverting step 1 to the default values for the open class:

nav.open, nav.open li 
  opacity: 1;
  -webkit-transform: none;
  transform: none;


nav.open li 
  /* Wait for the nav to slide down a bit before starting the animation on the thumbs */
  transition-delay: .3s;

Boom! You now have a fully functional animated navigation menu. A few things are missing that would make it truly great, though, starting with the scale animation on the images. If you look closely at the demo117, you’ll notice that the images not only fade in when they appear but also zoom in a little. Let’s add that behavior by making them slightly smaller by default:

nav li 
  -webkit-transform: scale(.8);
  transform: scale(.8);

We’ve already defined that nav.open li will reverse to transform: none; and that all properties will animate, so there’s nothing more to add.

Good! We’re almost done, but one important thing is missing: changing the icon on the “Explore” link when the nav is open or closed. To do that, we’ll need to define a new rule in our uilang code. We’re currently toggling an open class on the navigation to show and hide it; we’ll need to do something similar for the link itself.

<code>
  clicking on ".explore" toggles class "close" on "target"
  clicking on ".explore" toggles class "open" on "nav"
</code>

Here, target represents the clicked element. In this case, you could have just reused .explore instead of target. However, that wouldn’t be the same if you had multiple “Explore” links on the same page (.explore matches any “Explore” link, whereas target selects only the clicked “Explore” link).

Back to the CSS. We’re going to use pseudo-elements to display our icons. .explore::before will represent our grid icon (visible when the navigation is closed), and .explore::after will display the cross when the navigation is open. Both will benefit from the same transition-duration.

.explore::before, .explore::after 
  content: "";
  position: absolute;
  left: 0;
  transition: .25s;


.explore::before 
  background: url(grid.svg);


.explore::after 
  background: url(close.svg);
  /* Hidden and scaled up by default */
  opacity: 0;
  -webkit-transform: scale(1.8);
  transform: scale(1.8);

The grid icon is already visible; the close icon is hidden but correctly positioned, ready to fade in as soon as “Explore” is clicked. We just have to reverse the default state when the close class defined in our uilang code is applied to .explore:

/* When the nav is open, hide and rotate the grid icon… */
.explore.close::before 
  opacity: 0;
  -webkit-transform: rotate(45deg) scale(.8);
  transform: rotate(45deg) scale(.8);


/* … and display the close icon */
.explore.close::after 
  opacity: 1;
  -webkit-transform: none;
  transform: none;

That’s it! We’ve achieved this pretty cool effect with just two lines of uilang and a few CSS declarations. Note that, while the uilang code might not be used in production by the developers you collaborate with, your CSS is production-ready. Most of the prototyping tools out there force you to build mockups outside of the actual HTML and CSS, which forces developers to reimplement your animations, delays, easings and so on. Details get lost all the time. With uilang, developers can just reuse your CSS and focus exclusively on reimplementing the logic in JavaScript.

Icing On The Cake

As a bonus, let’s end this tutorial by having some fun with CSS! The grid and close icons that we’re using on the “Explore” link are actually pretty simple, and using images for them (as we’re doing) would be a shame when we could just draw them in CSS. Let’s do this!

The grid icon is the most interesting one. While it might initially seem counterintuitive, we’re going to use gradients to draw it. The idea is that each of the nine squares will be drawn as a gradient from black to black. When you create a CSS gradient, you’re basically generating an image on the fly. This (background) image can then be sized and positioned anywhere.

12
(See large version13)

Here’s the translation in CSS (available on CodePen14):

.explore::before 
  width: 13px;
  height: 13px;
  background-image: linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000),
                    linear-gradient(#000, #000);
  background-position: 0 0, 50% 0, 100% 0,
                       0 50%, 50% 50%, 100% 50%,
                       0 100%, 50% 100%, 100% 100%;
  background-repeat: no-repeat;
  background-size: 3px 3px;

It’s verbose and arguably crazy, but keep in mind that, while we’re essentially doing it for fun, this technique comes with real advantages, the most important one being undoubtedly the HTTP request you save from not requesting a file.

The close icon is much simpler but still requires some tricks to make it look great. We’ll use a similar technique: drawing a gradient from black to black for each bar of the cross in order to form a plus sign, then rotating the plus to make it look like a cross. To prevent the lines from looking jagged because of the 45-degree rotation, we’ll scale up the icon a little using the transform property, which provides us with decent antialiasing.

.explore::after 
  width: 11px;
  height: 11px;
  background-image: linear-gradient(#000, #000),
                    linear-gradient(#000, #000);
  background-position: 50% 0, 0 50%;
  background-repeat: no-repeat;
  background-size: 1px 100%, 100% 1px;
  -webkit-transform: rotate(45deg) scale(1.4);
  transform: rotate(45deg) scale(1.4);

Go Create!

CSS is powerful, performant yet remarkably easy to use. uilang wants to stay invisible in your workflow and act as a gateway to using CSS to code interactions. After all, CSS might be the best “user interface” for creating prototypes.

Resources

(ds, il, al)

Footnotes

  1. 1 http://uilang.com
  2. 2 ‘http://codepen.io/bdc/pen/bNWaVz/’
  3. 3 ‘http://codepen.io/bdc’
  4. 4 ‘http://codepen.io’
  5. 5 http://uilang.com/lib/production/uilang.js
  6. 6 http://apple.com
  7. 7 http://demos.uilang.com/explore-menu/
  8. 8 http://demos.uilang.com/explore-menu/
  9. 9 http://www.smashingmagazine.com/wp-content/uploads/2015/01/demo-uilang-large-preview-opt.jpg
  10. 10 http://matthewlein.com/ceaser/
  11. 11 http://demos.uilang.com/explore-menu/
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2015/01/grid-icon-info-large-preview-opt.jpg
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2015/01/grid-icon-info-large-preview-opt.jpg
  14. 14 http://codepen.io/bdc/pen/emYpGJ
  15. 15 http://uilang.com/
  16. 16 https://github.com/bendc/uilang
  17. 17 https://medium.com/@bdc/the-educational-side-of-uilang-92d39da94c13
  18. 18 http://transpiler.uilang.com
  19. 19 https://medium.com/@zackcote_/sublime-text-snippet-for-uilang-efb05fbed0d

The post Designers: Start Coding With uilang appeared first on Smashing Magazine.

More here:  

Designers: Start Coding With uilang

Thumbnail

Redefining Lazy Loading With Lazy Load XT

Lazy loading is a common software design pattern that defers the initialization of objects until they are needed. Lazy loading images started to become popular on the web back in 2007, when Mika Tuupola drew inspiration from the YUI ImageLoader utility and released a jQuery plugin1. Since then, it’s become a popular technique to optimize page loading and the user experience. In this article I will discuss why we should and shouldn’t use Lazy Load, and how to implement it.

Why Lazy Load?

Images make up over 60% of an average page’s size, according to HTTP Archive2. Images on a web page would be rendered once they are available. Without lazy loading, this could lead to a lot of data traffic that is not immediately necessary (such as images outside of the viewport) and longer waiting times. The problem? Visitors are not patient at all. By lazy loading, images outside of the viewport are loaded only when they would be visible to the user, thus saving valuable data and time.

Lazy loading is not limited to images. It can be used on pages with complex JavaScript, iframes and third-party widgets, delaying the loading of these resources until the user actually needs them.

Why Not Lazy Load?

Lazy loading is not a silver bullet, and it is known to affect performance. For example, most lazy-loading implementations either don’t have a src attribute in the <img> tags (which is invalid syntax, according to the HTML5 standard) or point to a blank image (hello, spacer.gif). This approach requires duplicate <img> tags wrapped in <noscript> tags for browsers with JavaScript disabled (or with the NoScript plugin installed):

<img data-src="path" attributes /><noscript><img src="path" attributes /></noscript>

Fortunately, this duplication doesn’t increase the page’s size significantly when you enable Gzip compression. However, some search engines might not index your images correctly, because the <noscript> tag is not indexed within content, and the <img> tag outside of <noscript> is referring to a blank image. Currently, Google seems to eventually index lazy-loaded images, but other search engines are less likely to.

How Is Lazy Loading Implemented?

You might be overwhelmed by the number of lazy-load plugins out there. You might also think that implementing one is easy: Just monitor page scrolling (or resizing), and then set the src attribute when an image is visible. If only it were that easy. Many things come into play when building a solid solution that works on both desktop and mobile. So, how do you separate the signal from the noise?

  • Throttling
    Checking the visibility of images after every interaction (even a tiny bit of scrolling) could compromise the page’s responsiveness. To ease that, implement some sort of throttling mechanism.
  • All your mobile are belong to us
    There is no scroll event in the Opera Mini browser and some old feature phones. If you receive traffic from those devices, you should monitor and load all images directly.
  • Lazy load or automatic pagination?
    Some implementations check only whether an image is above the fold. If the page is scrolled down to the very bottom via an anchor (or the scrollTo method in JavaScript), then all images below the fold will begin to download, instead of only the images within the viewport. This is more a matter of automatic pagination because users will have to wait for the remaining images to load after an interaction.
  • Dynamic image insertion
    Many websites use AJAX navigation nowadays. This requires a lazy-load plugin to support the dynamic insertion of images. To prevent a memory leak, any references to images that are not in the DOM (for example, ones that appear after an AJAX-based replacement of content) should also be removed automatically.

This list is certainly not comprehensive. We have many more issues to consider, such as the lack of getBoundingClientRect in old browsers, a change in orientation without an ensuing resize event on the iPhone, or the particular handling requirements of the jQuery Mobile framework.

Unfortunately, most plugins do not handle all of the above.

Lazy Load XT

We’ve been optimizing web performance on numerous screens for almost a decade now. Our project Mobile Joomla3 has been applied to over a quarter billion web pages and is still one of the most popular ways to optimize Joomla websites for mobile. Thanks to this, we’ve been lucky to witness the evolution of the web from desktop to mobile and observe trends and changing needs.

With our latest project, RESS.io4, we’ve been working on an easy solution to automatically improve responsive design performance on all devices. Lazy loading became an integral part of the project, but we came to realize that current lazy-load implementations are insufficient for the growing needs of the modern web. After all, it’s not just about desktop, mobile and images anymore, but is more and more about other media as well, especially video (oh, and did I hear someone say “social media widgets”?).

We concluded that the modern web could use a mobile-oriented, fast, extensible and jQuery-based solution. That is why we developed one and called it Lazy Load XT315.

Here are its main principles, which consider both current and future applications:

  • It should support jQuery Mobile6 out of the box.
  • It should support the jQuery7, Zepto8 and DOMtastic9 libraries. Of course, writing the solution in native JavaScript is possible, but jQuery is a rather common JavaScript extension nowadays, and one of our aims was to simplify the transition from the original Lazy Load to Lazy Load XT. This makes jQuery an adequate choice. However, if you don’t want to use jQuery at all, read the “Requirements” section below for details on reducing the size of dependent libraries.
  • It must be easy to start. The default settings should work most of the time. Prepare the HTML, include the JavaScript, et voilà!

Include

Lazy Load XT requires jQuery 1.7+, Zepto 1.0+ or DOMtastic 0.7.2+. Including the plugin is easy and as expected:

<script src="jquery.min.js"></script>
<script src="jquery.lazyloadxt.min.js"></script>

<script>$.lazyLoadXT.extend(edgeY: 200);</script>

<style>img.lazy display:none</style>

Use

By default, the plugin processes all images on the page and obtains an image’s actual source path from the data-src attribute. So, the recommended snippet to place an image on the page is this:

<img class="lazy" data-src="path" [attributes] /><noscript><img src="path" [attributes] /></noscript>

From this snippet, it is clear why we’ve set img.lazy above to display: none: Hiding the image is necessary in case there is no JavaScript, or else both the original image and the placeholder would be displayed. If the src attribute of the <img> tag is not set, then the plugin will set it to be a transparent GIF using the data-uri attribute.

If you’re not worried about users who have disabled JavaScript (or about valid HTML5 code), then just load jquery.lazyloadxt.min.js and replace the src attribute in the images with data-src:

<script src="jquery.min.js"></script>
<script src="jquery.lazyloadxt.min.js"></script>
<img data-src="path" [attributes] />

Video

Lazy Load XT is available in two versions: jquery.lazyloadxt.js and jquery.lazyloadxt.extra.js. The latter includes better support of video elements, both <video> tags and ones embedded in <iframe> (such as YouTube and Vimeo).

Markup changes are similar to the above, and replacing the src attributes with data-src and post with data-poster is sufficient if you’re using them in a <video> element.

<script src="jquery.lazyloadxt.extra.js"></script>
<iframe data-src="//www.youtube.com/embed/[videocode]?rel=0" width="320" height="240"></iframe>
<video data-poster="/path/to/poster.jpg" width="320" height="240" controls>
   <source data-src="/path/to/video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
   <source data-src="/path/to/video.ogv" type='video/ogg; codecs="theora, vorbis"'>
</video>
<video data-src="/path/to/video2.mp4" width="320" height="240" controls>

Size

The size of the jquery.lazyloadxt.min.js file is 2.3 KB (or 1.3 KB Gzip’ed), and the size of jquery.lazyloadxt.extra.min.js is 2.7 KB (or 1.4 KB Gzip’ed). That’s small enough, especially compared to jQuery and Zepto.

Requirements

Even though Lazy Load XT requires jQuery, Zepto or DOMtastic, loading the full versions of any of them is not necessary. For example, DOMtastic requires only a minimal set of modules (attr, class, data, event, selector, type) for you to get a 7.9 KB file (or 2.7 KB Gzip’ed), bringing the total size of both DOMtastic and Lazy Load XT to just 4 KB (Gzip’ed).

Compatibility

We’ve tested Lazy Load XT in the following browsers:

  • Internet Explorer 6 – 11
  • Chrome 1 – 37
  • Firefox 1.5 – 32.0
  • Safari 3 – 7
  • Opera 10.6 – 24.0
  • iOS 5 – 7 (stock browsers)
  • Android 2.3 – 4.4 (stock browsers)
  • Amazon Kindle Fire 2 and HD 8.9 (stock browsers)
  • Opera Mini 7

Performance

We have tested Lazy Load XT’s performance on a page with one thousand images and are happy with the results: Scrolling works well even on old Android 2.3 devices.

We also successfully tested various iterations of Lazy Load XT on over one thousand websites for several months in our jQuery Mobile-based Elegance and Flat templates10.

Options

The plugin’s default settings may be modified with the $.lazyLoadXT object:

$.lazyLoadXT.edgeY = 200;
$.lazyLoadXT.srcAttr = 'data-src';

Note that you may change this object at any time: before loading the plugin, between loading and when the document is ready, and after the event is ready. (Note that the last option doesn’t affect initialized images.)

Lazy Load XT supports a lot of options and events, enabling you to integrate other plugins or implement new features. For the full list and details, see Lazy Load XT’s GitHub page11.

AJAX Support

If you use jQuery Mobile with built-in AJAX page loading, then the Lazy Load XT plugin will do all of the magic for you in the pageshow event. In general, you should run the code below to initialize images inside a container with AJAX-loaded content.

$(window).lazyLoadXT();

Or run this:

$('#ajaxContainer').lazyLoadXT();

Extending Lazy Load XT

Lazy Load XT can be extended easily using the oninit, onshow, onload and onerror handlers or the related lazyinit, lazyshow, lazyload and lazyerror events. In this way, you can create amazing add-ons.

Some examples can be found on the GitHub page12, along with usage instructions13. We’ll highlight just a few of them here.

Loading Animation

Customizing the image-loading animation is easy. By default, Lazy Load XT includes spinner14 and fade-in15 animations, but you can use any effects from the Animate.css16 project or any other.

Responsive Images

Lazy Load XT has two add-ons for responsive images17. One is “srcset,” to polyfill the srcset attribute (and that should be renamed data-srcset):

<img data-srcset="image-hd.jpg 2x, image-phone.jpg 360w, image-phone-hd.jpg 360w 2x">

The second is “picture,” a polyfill for the <picture> tag:

<picture width="640" height="480">
   <br data-src="small320.jpg">
   <br media="(min-width: 321px)" data-src="medium480.jpg">
   <br media="(min-width: 481px)" data-src="large640.jpg">
   <noscript><img src="large640.jpg"></noscript>
   <p>Image caption</p>
</picture>

Page Widgets

Lazy Load XT makes it possible to lazy-load page widgets18 (such as Facebook, Twitter or whatever widget you like). Insert any HTML code in the page using the “widget” add-on when an element becomes visible. Wrap the code in an HTML comment inside of a <div> with an ID attribute, and give the element a data-lazy-widget attribute with the value of that ID:

<!-- Google +1 Button -->
<div data-lazy-widget="gplus" class="g-plusone" data-annotation="inline" data-width="300"></div>
<div id="gplus"> <!--
   
   (function() 
      var po = document.createElement('script'),
      s = document.getElementsByTagName('script')[0];
      po.type = 'text/javascript'; po.async = true;
      po.src = 'https://apis.google.com/js/platform.js';
      s.parentNode.insertBefore(po, s);
   )();
   
--></div>

If the data-lazy-widget attribute has an empty value, then the element itself will be used as a wrapper:

<div data-lazy-widget><!--
   
--></div>

Many other add-ons are available, too. They include infinite scrolling, support for background images, loading all images before displaying them (if the browser supports it), and deferring the autoloading of all images.

Is There A Silver Bullet?

Lazy loading images is not a standard browser feature today. Also, no third-party browser extensions exist for such functionality.

One might assume that the lazyload attribute in the “Resource Priorities19” draft specification by Microsoft and Google would do it. However, it has another purpose: to set the background priority for a corresponding resource element (image, video, script, etc.). Thus, if your aim is to load JavaScript or CSS before images, that’s your choice. There is another killer attribute, postpone, which prevents any resource from loading until you set the CSS display property to a value other than none. The good news is that support for the lazyload attribute is in Internet Explorer 11. The bad news is that the postpone attribute has not been implemented yet.

We do not know when or if the draft specification above will ever be fully supported by the major browsers. So, let’s look at the solutions we have now.

Some people have attempted to solve the duplication of the <img> tag in <noscript> tags by keeping only the <noscript> part and processing it with JavaScript. Unfortunately, <noscript> has no content in Internet Explorer, and it is not included in the DOM at all in Android’s stock browser (other browsers may behave similarly).

An alternative would be to use the <script> tag, instead of <noscript>, like so:

<script>function Z()document.write('<br ');</script>
<script>Z();</script><img src="path" attributes />

So, <img> would be an attribute of the <br> tag and would transform <br> tags into <img data-src> at the document.ready event. But this method requires document.write and is not compatible with AJAX-based navigation. We have implemented this method in the script add-on for Lazy Load XT, but the standard way using data-attributes seems to be clearer.

Finally, Mobify has an elegant Capturing API20 (see the recent review on Smashing Magazine21) that transforms HTML into plain text using the following code and then processes it with JavaScript:

document.write('<plaintext style="display:none">');

Unfortunately, this solution has drawbacks of its own: It is quite slow, and the browser might treat it as a JavaScript-based HTML parser. Also, combining this solution with AJAX navigation is not clear, and it is not guaranteed to work correctly in all browsers because the <plaintext> tag was deprecated in HTML 2. It actually doesn’t work in W3C’s Amaya browser and on some feature phones (such as Nokia E70). Nevertheless, these are edge cases, and you may use Mobify.js and Lazy Load XT simultaneously, although that is beyond the scope of this article.

Comparing Lazy Load Solutions

Both Lazy Load XT and the original Lazy Load are not the only solutions around. Below we compare most of the major existing solutions:

Feature LazyLoad for jQuery22 Lazy Load XT3023 Unveil24 Lazy25 (by Eisbehr) Responsive Lazy Loader26 bLazy27 Lazyload28 (by VVO) Echo29
Current version 1.9.3 1.0.5 1.3.0 0.3.7 0.1.7 1.2.2 2.1.3 1.5.0
Dependencies jQuery jQuery, Zepto or DOMtastic jQuery or Zepto jQuery jQuery
Size (Gzip’ed) 1.19 KB 1.31 KB (or 1.45 KB with extras) 338 B 1.45 B 1.23 KB 1.24 KB 1.01 KB 481 B
Skips images above the fold yes yes yes no yes yes no yes
Loading effects yes yes yes (with custom code) yes yes (with custom code) yes (with custom code) no no
Responsive images no yes (via plugin) yes no yes yes yes (with custom code) no
Supports scroll containers yes yes no yes yes no yes no
Supports horizontal scrolling yes yes no no yes yes yes yes
Throttling no yes no yes no yes yes yes
Lazy background images yes yes (via plugin) no yes no no no no
Lazy <video> tag no yes no no no no no no
Lazy iframes no yes no no no no no no
Supports Opera Mini no yes no no no no no no

Conclusion

The total size of media elements on the average web page is increasing constantly. Yet, especially on mobile devices, performance bottlenecks remain, which stem from bandwidth issues, widely varying network latency, and limitations on memory and the CPU. We need solutions for better and faster browsing experiences that work across all devices and browsers.

While no single lazy-load standard exists so far, we welcome you to try Lazy Load XT, especially if lazy-loaded video or other media is an important part of your website’s functionality.

Download and Contribute

Bug reports, patches and feature requests are welcome.

(al, ml)

Footnotes

  1. 1 http://www.appelsiini.net/projects/lazyload
  2. 2 http://httparchive.org/interesting.php
  3. 3 http://www.mobilejoomla.com/
  4. 4 http://ress.io/
  5. 5 https://github.com/ressio/lazy-load-xt
  6. 6 http://jquerymobile.com/
  7. 7 http://jquery.com/
  8. 8 http://zeptojs.com/
  9. 9 http://webpro.github.io/DOMtastic/
  10. 10 http://www.mobilejoomla.com/templates.html
  11. 11 https://github.com/ressio/lazy-load-xt#options”
  12. 12 http://ressio.github.io/lazy-load-xt
  13. 13 https://github.com/ressio/lazy-load-xt/#extendability
  14. 14 https://github.com/ressio/lazy-load-xt/#spinner
  15. 15 https://github.com/ressio/lazy-load-xt/#fade-in-animation
  16. 16 https://github.com/daneden/animate.css
  17. 17 https://github.com/ressio/lazy-load-xt/#responsive-images
  18. 18 https://github.com/ressio/lazy-load-xt/#widgets
  19. 19 https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/ResourcePriorities/Overview.html
  20. 20 https://hacks.mozilla.org/2013/03/capturing-improving-performance-of-the-adaptive-web/
  21. 21 http://www.smashingmagazine.com/2013/10/24/automate-your-responsive-images-with-mobify-js/
  22. 22 http://www.appelsiini.net/projects/lazyload
  23. 23 http://ressio.github.io/lazy-load-xt/
  24. 24 http://luis-almeida.github.io/unveil/
  25. 25 http://jquery.eisbehr.de/lazy/
  26. 26 https://github.com/jetmartin/responsive-lazy-loader
  27. 27 http://dinbror.dk/blazy/
  28. 28 http://vvo.github.io/lazyload/
  29. 29 http://toddmotto.com/echo-js-simple-javascript-image-lazy-loading/
  30. 30 http://ressio.github.io/lazy-load-xt/
  31. 31 https://github.com/ressio/lazy-load-xt
  32. 32 https://raw.github.com/ressio/lazy-load-xt/master/dist/jquery.lazyloadxt.min.js
  33. 33 https://raw.github.com/ressio/lazy-load-xt/master/dist/jquery.lazyloadxt.extra.min.js
  34. 34 http://ressio.github.io/lazy-load-xt/demo/

The post Redefining Lazy Loading With Lazy Load XT appeared first on Smashing Magazine.

More here: 

Redefining Lazy Loading With Lazy Load XT

Thumbnail

Make your VWO Graphs more Meaningful with Annotations

Ever found yourself puzzled with a sudden spike or drop in test results? Did it finally take you hours of brainstorming and discussions to figure out what caused the change? Now you can avoid all that hassle by simply adding notes to your graphs.

VWO allows you to annotate your graph reports with relevant notes to make your analysis more meaningful. Think of these as sticky notes on your graph reports. You can use these annotations to add comments, mark important events and even add relevant links to your graphs.

annotations walkthrough

Let’s say you are the optimization expert with a large software product company. To get more users for your product, you are running a campaign on your ‘sign-up’ page with a goal to improve conversions. Meanwhile, your marketing team decides to launch a well-targeted newsletter campaign that directs visitors to the sign-up page. The awesome campaign results in a sudden spike in conversions on your sign-up page, right on the date when the newsletter was sent.

A few months down the line, when you analyze the results of your campaign, it would be hard for you to identify what caused the sudden spike in conversions. This is where annotations come to your rescue. Annotations allow you to add context to your results by including notes for other activities/events happening during the test duration. The moment you see the comment with newsletter campaign in your graph, you know what to attribute the spike to.

The annotations are visible to all users in your account so that everyone can have similar context for interpreting results. It also comes with the added advantage of viewing who added the annotation so that any further discussions can flow seamlessly.

Check out this article in our knowledge base to get a step by step view of how to use annotations for your account.

And There’s More…
1. Now you can make changes to the iframe tag on your website. The iframe editor allows you to edit iframe URL, change style and placement, and so on. Simply load the webpage containing the iframe content into the campaign builder and you are ready to go!

iframe

2. The select parent option expands to allow you to select the largest parent from any element on the page. If you are making changes to an element on your page, use this option to go up to the largest parent of the element.

select parent

Let us know about your experience with this month’s updates in the comments section. And we would love to hear if you have anything to share with us about VWO!

The post Make your VWO Graphs more Meaningful with Annotations appeared first on VWO Blog.

Source: 

Make your VWO Graphs more Meaningful with Annotations