Friday, April 17, 2015

Today we'd like to share a simple animated grid layout with you. The responsive layout has a sidebar and grid items that animate to a larger content area when clicked. In the first demo the content area fills the grid (inspired by a concept by Virgil Pana) and in the second demo, the whole layout moves to the left while the grid item is expanding (inspired by this Dribbble shot by Sam Thibault).

The expanding element (which is a dummy element and not the grid item itself) is not animating in width and height but instead its original dimensions are already of the expanded size and we simply scale it down initially. By setting classes, we control the transitions of all the elements: the grid item elements' disappearance and the content elements' appearance (and vice versa when we close an opened content panel).

The layout is responsive down to mobile using a media query technique that involves setting the breakpoints based on the grid item size and the sidebar. For this we use Sass, which allows us to set these kind of variables easily. The approach we are using here is mainly mobile-first, but we also do some specific restructuring for small screens.

* Please note that this layout uses some modern techniques that involve viewport units, transitions, flexbox and other properties that will only work in modern browsers.

The second demo is a bit more experimental and it might not behave as expected in all browsers. Internet Explorer seems to have some issues with transitions on transforms that use calc().

This layout is focused on the expansion effect of the grid item and many elements are simple dummies (the loader, the filter in the top bar and the "load more" in the footer of the grid).

The main markup looks as follows:

The Sass files of this project are divided into a main style file and two partials, one for the base styles and one for the media queries. Each of the demos will have a unique style Sass file (style1.scss and style2.scss) where we initiate some variable and redefine some styles if necessary (as in demo 2). There are many ways of organizing your project in Sass; this was one convenient way to do it for these two demos. If you'd like to use one of them, make sure to refactor your style declarations. If you are not familiar with Sass, you can simply use and adjust the generated CSS files.

This technique can come in handy when dealing with grid layouts. Optimally, we'd not have that last media query at all if we want to strictly follow a mobile-first approach. But since these styles are exclusively valid only for small screens, we don't want to be redefining and overwriting styles for larger screens.

Have a look at the layout and the effect and dig into the source, we really hope you find this template useful and inspiring!

Tuesday, April 14, 2015

One of the things that drives me crazy in our "modern development" world is our fetish of over-complicating things. We build solutions, and then we add layers and layers of complexity for the sake of "making them easier to maintain". In many cases, this is a fool's errand as the layers of complexity and with them the necessary documentation make people not use our solutions. Instead, in many cases, people build their own, simpler, versions of the same thing and call it superior. Until this solution gets disputed and the whole dance happens once again.

In this article I want to approach the creation of a carousel differently: by keeping it as simple as possible whilst not breaking backwards compatibility or have any dependencies. Things break on the web.JavaScript might not be loaded, CSS capabilities vary from browser to browser. It is not up to us to tell the visitor what browser to use. And as good developers we shouldn't create interfaces that look interactive but do nothing when you click them.

The main thing here is to position the carousel box relatively, allowing us to position the list items absolutely inside it. This is how we'll achieve the effect. The hidden overflow ensures that later on only the current item of the carousel will be shown. As there is no height set on the carousel and the items aren't positioned yet, we now see all the items.

The carousel visuals in CSS

A lot of carousel scripts you can find will loop through all the items, or expect classes on each of them. They then hide all and show the current one on every interaction. This seems overkill, if you think about it. All we need is two classes:

We need a class on the container element that triggers the functional display of our carousel. This one gets applied with JavaScript as this means the look and feel only changes when the browser is capable of showing the effect.

We need a class on the currently visible carousel element. This is the odd one out. All the others don't need any classes.

We can hard-code these for now:

1

2

3

4

All we need to show and hide the different carousel items is to change the height of the carousel container and position all but the current one outside this height:

Interaction with Javascript

To make the carousel work, we need controls. And we also need some JavaScript. Whenever you need a control that triggers functionality that only works when JavaScript is executed, a button is the thing to use. These magical things were meant for exactly this use case and they are keyboard, mouse, touch and pen accessible. Everybody wins.

In this case, I added the following controls in our HTML:

1

2

3

4

Now, here is where the hard-liners of semantic markup could chime in and chide me for writing HTML that is dependent on JavaScript instead of creating the HTML using JavaScript. And they'd be correct to do so. There is nothing that stops me from wrapping this chunk of HTML in a DOM call or innerHTML write-out. However, as buttons are meant to trigger JS functionality, I think it is easier to just keep that in the HTML and allow us thus to style them with much less hassle. As a security precaution, we hide them in the non-active state and show them when the "active" class has been applied:

As you can see, by relying on CSS and its built-in crawling of the DOM, there is no need for any loop whatsover. Here's what's going on in this script:

We grab all the HTML elements we need with querySelector.

We set the counter to 0 – this is the variable that keeps track of which item of the carousel is currently shown.

We read the amount of items in the carousel and store them in a variable – this allows us to loop the carousel.

We set the current item as the first one in the carousel. The current variable will contain a reference to the element currently visible. All we do when the carousel state changes is remove the CSS class from it and shift it to the other one.

We add the class of active to the container element to change its styling and trigger the CSS functionality explained earlier.

The navigate method takes a parameter called direction which defines if we should go backwards (negative values) or forwards in the carousel. It starts by removing the current class from the current carousel item, thus hiding it. We then modify the counter and make sure it doesn't go beyond the amount of items available or below 0. In each case we move to the other extreme, thus making the carousel an endless rotating one. We define the new current item and add the class to show it.

We apply event handlers to the buttons to navigate forwards and backwards.

We show the first carousel item by calling navigate with 0 as the value.

Pretty simple, isn't it? By allowing CSS to do what it is good at, our JavaScript more or less is only about keeping state and shifting classes around.

Getting fancy

The showing and hiding of the items by positioning them in a container with overflow hidden should work in any browser in use these days – even the ones who should be retired. And as all we do is add and remove CSS classes, we can now tap into the beautiful features browsers have these days. Using transition, opacity and transformation, we can add a pretty effect with a few lines of CSS:

The beauty of this is that the performance handling, the timing (in case you click too fast) is handled by the browser for us. No need to count FPS or juggle timeouts. As CSS is a one-off state, this also means that browsers that do not support these features simply don't show them instead of throwing an error.

Bullet-proofing our Javascript

When a browser in use doesn't support some JavaScript feature we use, things get trickier. We get an error and things break. Thus, it makes sense to test for the things we use and move on only when there is support for them. In this code, we rely on classList and querySelector, so let's just check for this:

We could get much more paranoid and ensure that all the DOM elements are available before proceeding but this is overkill. If a maintainer forgets to add the carouselbox class to the main element, the error thrown is pretty obvious.

Bonus round: stacking with CSS

One last trick to mention is that if you were to stack all the elements of the carousel visually and only use opacity to blend them then there is a problem with links. You'd always get the link of the first item, no matter which one is shown.

The trick to work around that is user pointer-events: none in your CSS:

Where to go now

The natural drive as a developer now is to enhance this to allow users to define a different starting element to show, to define lots of preset effects that can be chosen with the data attribute, to allow for non-looping carousels and to define an API to allow other components on the page to interact with the carousel. And an API to create and remove and shuffle items of the carousel. And, and and... All of these are great exercises, but let's ask ourselves: who do we do that for?

We have such amazing functionality built into the platform of the web now. Maybe it is time to stop writing the perfect generic re-usable widget and just stick with simple things and let people extend them when they need to? Who knows, by not doing the work for them, people might learn to be better coders themselves.

Tuesday, April 14, 2015

In this article, we'll take a deeper look at variables and variable scope in Sass. The scope of a variable describes the context within which it's defined and therefore where it's available to use.

To start, I'll cover which scopes Sass supports. Then, I'll explain two useful flags we can use to customize the value of a variable. Finally, I'll briefly present the available functions for checking whether a variable exists or not.

Sass Variable Scope

Sass supports two types of variables: local variables and global variables.

By default, all variables defined outside of any selector are considered global variables. That means they can be accessed from anywhere in our stylesheets. For instance, here's a global variable:

$bg-color: green;

On the other hand, local variables are those which are declared inside a selector. Later, we'll examine how we can customize that behavior. But for now, let's see our first example.

Here we define a mixin and then the btn-bg-color variable within it. This is a local variable, and is therefore visible only to the code inside that mixin:

If we try to compile this, we'll get the same error discussed before. Again, that happens because we can't access the text-color variable. It isn't directly defined within the parent selector, but inside the function that our selector calls.

Variable Names

Global and local variables can have the same names. To demonstrate that behavior, we'll work on a fourth example:

Notice the difference in the background color of the .wrap selector. This happens because according to the earlier Sass versions (same for LibSass), if we locally redefine the value of a global variable (e.g. text-color), this will be the variable's new (global) value. So, in our example the compiled styles depend on the order we declare the variable and the mixins.

The default flag

This flag allows us to set the value of a variable in case it hasn't already been set or its current value is null (treated as unassigned). To better explain how we can take advantage of it in a real scenario, let's suppose that we have a project with the following structure:

So, our buttons come with default styles. But let's suppose that we want to have the option to overwrite them by applying our custom values. To do this, we can reassign the desired (default) variables in the config.scss partial file:

$btn-bg-color: chocolate;
// more variables

Setting the value of this variable to chocolate will result in ignoring the corresponding value (lightblue) that has received the default flag. Therefore, the generated CSS changes as we can see below:

Note: in case we haven't added the default flag to the btn-bg-color variable, our CSS would be, due to the cascading nature of CSS, as follows:

button { color: lightblue; }
// hover styles

The global flag

This second flag helps us change the scope of a local variable.

Do you remember the error we saw in our first example? Well, that happened because we tried to use the btn-bg-color variable in the .wrap selector. Let's modify our example to include this new flag. Here are the new styles:

As you can see below, thanks to this flag, the CSS compiles without any errors:

button { color: lightblue; }
.wrap { background: lightblue; }

The global flag is useful, but bear in mind that it's not always good practice to change a variable's scope.

Checking if a Variable Exists

Sass provides two introspection functions for testing whether a variable exists or not. We can use the variable-exists and/or global-variable-exists functions to check if our local and/or global variables exist respectively.

For example, here's a common use case where we define a variable containing the absolute path to a Google Font. Then, we choose to import that font in our stylesheets, but only if the relevant variable has been instantiated.

Conclusion

In this article, I introduced you to the concept of variable scope in Sass. To make things clearer we looked at different examples, so hopefully you now have a good understanding of how scope works. You can find all the examples of this article in this SassMeister gist.

Tuesday, April 07, 2015

JavaScript uses a different approach than C# or C++ to create an object-oriented language. It is a prototype-based language. The concept of prototyping implies that behavior can be reused by cloning existing objects that serve as prototypes. Every object in JavaScript decends from a prototype which defines a set of functions and members that the object can use. There is no class. Just objects. Every object can then be used as a prototype for another object.

This concept is extremely flexible and we can use it to simulate some concepts from OOP like inheritance.

Implementing Inheritance

Let's visualize what we want to create with this hierarchy using JavaScript:

First of all, we can create ClassA easily. Because there are no explicit classes, we can define a set of behavior (A class so…) by just creating a function like this:

Tuesday, April 07, 2015

The CSS multi-column layout uses new CSS properties which allow designers to break a layout into blocks. The two main properties which control the number of columns are: column-count and column-width.

Related Properties

column-width

column-count

column-gap

column-rule

column-rule-width

column-rule-style

column-rule-color

column-span

column-fill

columns

Degradation

Column properties are ignored by browsers which don't support them. To deal with that issue, create a single column layout for unsupported browsers and multiple columns with browsers that support them.

Note: To make sure you can use multiple columns, each property needs to be written three times: Once with the -moz prefix, once with the -webkit prefix, and once without the prefix.

Syntax

Here are some examples of how you would use the multi-column properties:

You use the column-width property to set the smallest column width. If you don't set the column-count, the browser will take over and create as many columns as necessary to fit the width. Here's the code:

Height Balancing

With the CSS3 Column specification the browser automatically sets the column height so the content in each column are similar. That said, you might want to set the height manually using the CSS height or max-height properties and then build your layout accordingly.