Tuesday, 27 September 2016

An Introduction To SVG Filters - Vanseo Design

An Introduction To SVG Filters - Vanseo Design


An Introduction To SVG Filters

Posted: 27 Sep 2016 05:30 AM PDT

If I asked you to blur an image or make color adjustments to it, you'd probably reach for your favorite image or graphic editing program and rightly so. Effects like these have been created in image editors for years. However, some can now be created without the editor and through code alone.

By code I'm referring to filters in CSS and SVG. At the moment CSS lags a little behind SVG in terms of which browsers support the different filters. As you might have already guessed, I want to start a new series today about SVG filters.

My plan is to talk about the basics of SVG filters over the next few weeks and then spend time looking in more detail at some of the different things you can do with SVG filters. At the end of the series I'll talk a little about CSS filters as well.

Be prepared. This is going to be a long series. The basics won't take too long to cover, but the details of the specific filter primitives will. The series will easily take up most of the rest of this year and continue into 2017. Because it will take awhile to get to the end, I'll probably break the series somewhere in the middle, and talk about something else for a bit before coming back and finishing this one.

How SVG Filters Work

I'm sure you've added a filter to an image before. I don't mean things like Instagram filters, which are really specific combinations of more general filters. I mean the basic underlying filters like adding a Gaussian blur to an image or embossing another. You've probably placed one image on top of another and used your graphics program to blend them using a multiply or darken blend mode.

The basic idea behind SVG filter effects is you start with a source image or SVG graphic and then modify the source with one or more filters before outputting the modified image to the screen. Filters are nice because they can be added in nondestructive ways. Remove the filters and the original source is displayed again.

SVG filters are defined in one place and then referenced in another. The basic form usually looks like this.

1  2  3  4  5  
<filter id="my-filter">    <filter primitive />  </filter>    <circle filter="url(#my-filter)">

I've left out the details in the code above to focus on the general idea that you define your filters using one or more filter primitives inside a <filter> element. The filter element gets an an id, which is then referenced by the source graphic.

Note the syntax on the circle element. There's a filter property, which takes as its value a url() that references the specific filter you want to add.

If you've followed some of my previous SVG posts or are generally familiar with SVG, you'll notice this set up is similar to many other elements which are defined in one place and referenced in another.

Each filter primitive performs a single graphic operation. One might blur the image. Another might change it's color. A third might offset its location. While each filter primitive performs a single operation, you can have multiple filter primitives inside a single filter element so your filter could both blur and offset an image or blend one image with another and then add a lighting effect.

Filters can be applied to an original source graphic or they can be applied to the result of another filter. In other words you can add a one filter effect to an image and then use the result of that effect as the source for another filter effect.

You can also apply a filter to container elements like <g> and have the filter apply to the entire group as opposed to a single element inside the group. You can even add a filter to an empty container and through a <use> element call the filter which produces the entire graphic for output to the screen.

Again, I'm leaving out the details in this introduction, though I promise to fill them in through the rest of the series. For the remainder of this post I'd like to show you a simple example and talk through it to drive home the basic concepts.

A Simple Example Applying a Gaussian Blur Filter

To illustrate how filters work let's start with a couple of unfiltered shapes. Here are two identical squares placed inside the SVG canvas.

1  2  3  4  
<svg width="100%" height="220" style="outline: 1px solid red">   <rect x="10" y="10" width="100" height="100" fill="#00f" />   <rect x="115" y="10" width="100" height="100" fill="#00" />  </svg>

Hopefully this isn't anything new. I created two shapes using the <rect> element and set both to have equal width and height. I placed them next to each other with a few pixels in between.

I'm going to work with a Gaussian blur filter as its effects are easily seen and because it's a simple filter to understand and demonstrate. The filter primitive to add a Gaussian blur is <feGaussianBlur>, which I'll cover in more detail later in the series. Let's add the filter to the example.

1  2  3  4  5  6  7  8  9  10  
<svg width="100%" height="220" style="outline: 1px solid red">   <defs>     <filter id="blur">       <feGaussianBlur stdDeviation="3" />     </filter>   </defs>     <rect x="10" y="10" width="100" height="100" fill="#00f" />   <rect x="115" y="10" width="100" height="100" fill="#00f" filter="url(#blur)" />  </svg>

You'll notice I placed the filter element inside a <defs> element since we're defining a filter in one location and referencing it in another. It's not necessary, but it's standard practice. The filter has an id of "blur" and inside the filter element is a single <feGaussianBlur> filter primitive.

Don't worry too much about the stdDevdiation property on the filter primitive for now. All you need to know is the greater the value of the stdDeviation, the more blur there will be on the resulting graphic.

The last thing to notice is I added a filter property to the second rectangle and refer to the blur filter using the filter property and a value of url(#blur).

Here's the result.

As you can see the second rectangle is blurry. It has fuzzy edges and even the center isn't as solid blue as the original. It's blurry throughout. Best of all I used exactly zero bitmapped images so we can get the original rectangle back any time we want by removing the filter.

You probably don't want to blur most elements that appear on a webpage, but you might want to blur the shadow behind something and later in the series I'll show you how to create a drop shadow with SVG by combining this filter primitive with another one.

Closing Thoughts

There is a lot more to SVG filters than what I've showed here and I'll dig into the details in the coming weeks. Hopefully you can see it's relatively easy to add a filter to an SVG graphic, which is the main thing I wanted to show you today.

If you've followed along with some of my previous SVG series, the basics of filters should look familiar. You define your filters in one location and refer to them on the graphic or container to which you want to apply the filter.

There are also many more filter primitives besides feGaussianBlur. SVG offers primitives to add lighting effects, blend two images, adjust colors, and all sorts of other things.

I'll get to all the filter primitives in a few weeks, but first I want to go into more detail about how filters work. I'll pick things up next time by talking more about the filter element and the different attributes that help you define the filter.

Download a free sample from my book Design Fundamentals.

Join me as I share my creative process and journey as a writer.

This posting includes an audio/video/photo media file: Download Now

Tuesday, 13 September 2016

How To Write Your Own Custom Sass Functions - Vanseo Design

How To Write Your Own Custom Sass Functions - Vanseo Design


How To Write Your Own Custom Sass Functions

Posted: 13 Sep 2016 05:30 AM PDT

If you've built more than a handful of websites, you've probably noticed you can easily repeat code in a project and across multiple projects. Repeating the same code over and over wastes your time and increases the possibility of introducing errors. In a previous series on Sass, I said mixins were one option for reusing styles and writing DRYer code. Functions are another way to do the same.

Qwerty Keyboard
Qwerty Keyboard by Mysid

For the last couple of months I've been talking about data types, operators, and functions in Sass. I walked you through numbers, strings, colors, colors again, lists, lists again, and maps. The last couple of weeks I talked about control directives. Today marks the last post in this series and I want to close the series talking about the @function directive and how to write your own custom functions.

How to Create and Use Custom Functions

Functions are blocks of code that return a single value of any Sass data type. To create a custom function you need two Sass directives, @function and @return. The first creates the function and the second signals the value the function will return.

1  2  3  
@function function-name($args) {     @return value-to-be-returned;    }

The arguments passed to the function are optional, though you'll use them more often than not. Typically a Sass function will run some calculation(s) using the arguments that have been passed to it and possibly some global variables, which all functions can access.

For historical reasons function names can use either a dash or an underscore interchangeably so function-name and function_name are the same function and you can use either the dash or the underscore to refer to the function regardless of which one was used when naming it.

In the code above I show only a single line of code to return a value, but most functions will do more and then the @return directive will be included as the last line of the function.

Keep in mind that while only a single value is returned that value can be of any data type so you could return the number 9, the string "I am a string." or a data structure like a list or map that includes as many values as you'd like.

To use a function you supply the function name and any arguments in place where you want the returned value to appear.

1  2  3  4  5  6  7  
p {     font-size: function-name($args);    }    p {     font-size: function_name($args);    }

Again these would both be calls to the same function. Presumably this function would calculate a value in px or em and return that value so it would become the font-size of the paragraph.

As I said, functions can access any globally defined variable. In this next example I created two global variables, $total and $col. The first might represent the total number of columns in a grid and the second might represent a grid field that's 3 columns wide.

1  2  3  4  5  6  
$total: 8;    $col: 3    @function column-width() {     @return percentage($col/$total);    }

The function takes no arguments. It divides the size of the field ($col) by the total number of columns ($total) and it uses the built-in percentage function to turn the result into a percentage before it returns the value.

We can call the function by adding the function name where we want the returned value to appear. Since this function doesn't take arguments, none are passed with the function call.

1  2  3  
.col-3 {     width: column-width();    }

The function will do the math and the code will be compiled to:

1  2  3  
.col-3 {     width: 37.5%;    }

The function as written isn't very useful as I had to hard code the total number of columns and the size of the grid field as global variables. A more useful scenario would be to pass these as arguments so let's rewrite the function.

1  2  3  
@function column-width($col, $total) {     @return percentage($col/$total);    }

Because the function now accepts arguments we have to pass them during the function call, though we can reuse the function and call it with different arguments

1  2  3  4  5  6  7  
.col-3 {     width: column-width(3, 8);    }    .col-5 {     width: column-width(5, 8);    }

which would compile to:

1  2  3  4  5  6  7  
.col-3 {     width: 37.5%;    }    .col-5 {     width: 62.5%;    }

Keyword Arguments

You might have noticed that in the previous example I passed the arguments in the order they're listed in the function. That's necessary unless you use keywords.

You can pass a key/value pair using the form key: value.

1  2  3  
.col-3 {     width: column-width($col: 3, $total: 8);    }

If you include the key name, you don't have to list them in the same order they're listed in the function.

1  2  3  
.col-3 {     width: column-width($total: 8, $col: 3);    }

Even though the function lists $col first and $total second, by using the keywords before each value the function knows which is which.

You can also declare defaults on the arguments when creating the function. Here I've modified the function so the default number of total columns is 8.

1  2  3  4  5  6  7  
@function column-width($col, $total:8) {     @return percentage($col/$total);    }    .col-3 {     width: column-width(3);    }

In the code above I only passed a single value to the function. The function then uses the default for the argument that I didn't pass and still compiles to:

1  2  3  
.col-3 {     width: 37.5%;    }

You can always override the default by passing the argument with or without the keyword.

1  2  3  4  5  6  7  
.col-3 {     width: column-width(3, 9);    }    .col-4 {     width: column-width($col:3, $total:12);    }

A More Practical Example

So far none of the examples have been all that practical. I've written them as I have to explain how something works. Let's write some code that's a little more practical.

Here I set the global variable $total as 8. Then I rewrote the function from the previous examples to use the global variable instead of having to pass the total number of columns as a parameter.

Finally I used a for loop to run from 1 to the value of $total. Inside the loop, the counter $i becomes part of the class name and the width of the class generated by passing the value of $i to the function.

1  2  3  4  5  6  7  8  9  
$total: 8;    @function column-width($col) {     @return percentage($col/$total);    }    @for $i from 1 through $total {     .col-#/{$i/} { width: column-width($i) };    }

The Sass compiles to:

1  2  3  4  5  6  7  8  
.col-1 { width: 12.5%; }    .col-2 { width: 25%; }    .col-3 { width: 37.5%; }    .col-4 { width: 50%; }    .col-5 { width: 62.5%; }    .col-6 { width: 75%; }    .col-7 { width: 87.5%; }    .col-8 { width: 100%; }

If instead of an 8-column layout, you decide on to use 12 columns or 9 or 4, all you'd have to do is change the value of $total. The custom function and @for loop will do the rest.

Variable Arguments

Like mixins, functions can take variable arguments by using 3 dots (not an ellipses) after the argument name. The function will create a list from the variable arguments passed to it.

In the following example I created a function that takes an argument named $index and a variable argument named $widths…

1  2  3  
@function column-width($index, $widths...){      @return nth($widths, $index);    }

The function will use the built-in nth function to find the value inside $widths at index $index. When I call the function, I pass it a value for the index and a series of percentage widths.

1  2  3  
.col-3 {      width: column-width(3, 25%, 50%, 75%, 100%);    }

Since 75% is the value at index 3, the code compiles to:

1  2  3  
.col-3 {      width: 75%;    }

Quite honestly this isn't a particularly useful function as it would have been easier to simply set the width instead of calling the function. While variable arguments are useful in mixins to add something like multiple box shadows, I have a hard time thinking how they would be useful in a function. Still it's something you can do and I thought worth showing.

Prefix Your Function Names

One thing I should mention is that it's a good idea to give your function names a prefix to avoid naming conflicts with built-in functions or functions from a library you might be using.

It isn't hard to imagine someone else having created a column-width function that would conflict with the function names I've used in my examples. A better name might be vanseo-column-width, since it's not likely that a 3rd party function would use the same prefix.

Function or Mixin

Because Sass functions and Sass mixins are similar you might wonder why you would use one over the other. While similar they do have one important difference, which suggests when it's best to use each.

The main difference between the two is that mixins output lines of Sass code that will compile directly into CSS styles, while functions return a value that can then become the value for a CSS property or become something that might be passed to another another function or mixin.

To be honest you could probably rewrite every function to be a mixin and vice versa, but there are clear uses cases for each.

Use a mixin when you want to directly output styles and use functions when you want to perform calculations that returns a value. For example the formula to determine the percent width of a responsive container might look familiar

1  
target / context = result

Because this is a calculation you'd likely perform multiple times in a stylesheet it's ripe for a function where you pass the target and context and get the resulting width in return.

Closing Thoughts

Functions are one way to move reusable code into a separate package. They're similar to mixins and they differ mainly in their output. Functions return a value where mixins output code. If you know how to work with one, it shouldn't be too difficult to work with the other.

That brings us to the end of this series on Sass data types, operators, and functions. Hopefully now that we've reached the end of the series, you can see why I spent time talking about each of the different data types. Outside of colors, the other data types become more useful when used in functions or mixins.

Next up I want to return to SVG and a series about filter effects, which allow you to do things like blur an image, add lighting effects, or blend two images together.

Download a free sample from my book Design Fundamentals.

Join me as I share my creative process and journey as a writer.

This posting includes an audio/video/photo media file: Download Now

Wednesday, 7 September 2016

Loop Through Sass Code Using Control Directives - Vanseo Design

Loop Through Sass Code Using Control Directives - Vanseo Design


Loop Through Sass Code Using Control Directives

Posted: 06 Sep 2016 05:30 AM PDT

Control directives give you a way to add conditional logic to your Sass code. They allow you to branch your code in different directions based on different conditions and they allow you to loop through code until certain conditions are true or they stop being true.

Public Address Booth Controls

Last week I started talking about control directives as part of a longer series about Sass data types, operators, and functions. I've now covered numbers, strings, colors twice, lists and list functions, and maps along with their associated operators and functions. Today I'll finish up control directives and then we can move on to writing our own custom functions.

I've already covered the @if directive, the if() function and the @for directive. There are a couple more control directives to talk about, @each and @while.

The @each Directive

Like the @for directive we saw last week, the @each directive allows you to run code until certain conditions change. The difference is where a @for loop uses a counter, an @each loop loops the values in a list or map.

The @each directive is used to loop through the items in a list or map and continue to run the code you set until there are no more items left.

In the following code I created a list called $items and filled it with values of item-1, item-2 and so on up to item-10.

1  2  3  4  5  6  7  8  9  10  
@items: (     item-1,     item-2,     &hellip;   item-10    );    @each $item in $items {     code to run here    }

The @each directive says to look at the list $items and then for each value inside the list (or map) run the code. Each time through the loop, the next value inside the list (or map) becomes the variable $item and the code runs again. When there are no more items left, the program exists the block of code

For example you might have a set of buttons for your social profiles and each needs a different background image to distinguish it from the others. You could set up a list of sites and use the @each directive to create the proper class name and image name for the background-image.

1  2  3  4  5  6  7  8  9  10  11  
$buttons: (     facebook,     twitter,     linkedin    );    @each $button in $buttons {      .#{$button}-button {        background-image: url('/images/#{$button}}.png');      }  }

which compiles to:

1  2  3  4  5  6  7  8  9  10  11  
.facebook-button {     background-image: url('/images/facebook.png');    }    .twitter-button {     background-image: url('/images/twitter.png');    }    .linkedin-button {     background-image: url('/images/linkedin');    }

Adding more buttons would be a matter of adding the site name to the initial list, assuming of course you've created and named the images and placed them in the directory structure the loop expects.

Multiple Assignments

The @each directive isn't limited to a single variable. You can loop through multiple values instead. Here's a modified version of the previous example.

I created a nested list for the different buttons that includes the name of the social site and a color, which we'll use to output the border color.

1  2  3  4  5  6  7  8  9  10  11  12  
$buttons: (     (facebook red),     (twitter green),     (linkedin blue)    );    @each $site, $color in $buttons {      .#{$site}-button {        background-image: url('/images/#{$site}}.png');        border: 1px solid $color;      }  }

Note the use of the two variables in the directive, $site for the name of each site and $color for the color that go with the site. Each time through the loop the value of $site is used to name the class and the name of the image, while $color is used to set the border color of the button.

The Sass compiles to:

1  2  3  4  5  6  7  8  9  10  11  12  13  14  
.facebook-button {     background-image: url('/images/facebook.png');     border: 1px solid red;    }    .twitter-button {     background-image: url('/images/twitter.png');     border: 1px solid green;    }    .linkedin-button {     background-image: url('/images/linkedin');     border: 1px solid blue;    }

Multiple assignments are useful in maps as each map pair is like a nested list. I borrowed and modified this example from the Sass documentation. First I created a map named $headings, which contains key names of h1, h2, and h3 and setting each to a different font-size.

1  2  3  4  5  6  7  8  9  10  11  
$headings (     h1: 3em,     h2: 2em,     h3: 1em    );    @each $heading, $size in $headings {      #{$heading} {        font-size: $size;      }  }

Similar to the previous example the @each directive loops though both the key and value in each pair. It takes the value in each pair and sets it as the font-size of the key in the same pair.

The Sass compiles to:

1  2  3  4  5  6  7  8  9  10  11  
h1 {     font-size: 3em;    }    h2 {      font-size: 3em;    }    h3 {      font-size: 1em;    }

Look over this example a few times. It's simple, but hopefully it shows how maps can be useful as well as how the @each directive with multiple assignments works.

The @while Directive

The @while directive is similar to the @for directive in that it sets a condition and the code inside the loop runs until the condition is no longer true. However, unlike the @for directive there's no automatic counter. You have to set it inside the loop, which does allow you to do more complex things.

Here I set the variable $i to 10 and set a condition that the styles should be output while $i remains greater than 0. At the end of the loop I decreased the value of $i by 1 so the next time through the loop $i will equal 9 and so on until it's been reduced to 0 and the styles inside the loop are no longer output.

1  2  3  4  5  6  7  
$i: 10;    @while $i > 0 {      styles here;      $i: $i - 1;    }

If you remember last week I used a @for loop to create the widths for an eight column grid. Here's the example rewritten to use a @while loop instead. I set two variables, one for $i which we'll increment inside the loop and one for $cols, which represents the number of columns in our grid.

1  2  3  4  5  6  7  8  9  
$i: 1;    $cols: 8;    @while $i <= $cols  {     $width: percentage($i/8);     .col-#{$i} { width: $width; }     $i: $i + 1;    }

The condition is @while $i <= $cols so as long as $i is less than or equal to the value of $cols the code will continue to run.

The code that calculates the $width and sets a width for each column is the same as in the @for directive example from last week, but now we have to increment $i on our own so the last line in the loop adds 1 to the current value of $i.

The output is the same as it was in the @for example:

1  2  3  4  5  6  7  8  
.col-1 { width: 12.5%; }    .col-2 { width: 25%; }    .col-3 { width: 37.5%; }    .col-4 { width: 50%; }    .col-5 { width: 62.5%; }    .col-6 { width: 75%; }    .col-7 { width: 87.5%; }    .col-8 { width: 100%; }

You'll find that @for and @while directives can often be rewritten as the other and which is best to use will depend on the specifics of what you're trying to do.

Closing Thoughts

Control structures come in handy when you want to either branch in different directions based on certain conditions or to output similar styles with slight variations. The @if directive (or if() function) is useful for branching and the remaining directives can be used for the case of outputting slight variations.

The @for and @while directives loop through code as long as the condition you set remains true. The @each directive will loop through your code as long as there are still items in the list or map.

Again if you've done any programming, this has probably been a simple review of control structures. If you're new to programming, I hope some of the examples here and in last week's post give you an idea of what you can do with these control directives and how they can be useful.

Next week we'll get to the last topic in this series. I'll show you how to write your own custom functions.

Download a free sample from my book Design Fundamentals.

Join me as I share my creative process and journey as a writer.

This posting includes an audio/video/photo media file: Download Now