When the Russian ruble’s exchange rate slumped two years ago, it drove us to think of cutting hardware and hosting costs for the Mail.Ru email service. First, we had to take a look at what email consists of. Indexes and bodies account for only 15% of the storage size, whereas 85% is taken up by files. So, optimization of files (that is, attachments) is worth exploring in more detail.
At the time, we didn’t have file deduplication in place, but we estimated that it could shrink the total storage size by 36%, because many users receive the same messages, such as price lists from online stores and newsletters from social networks that contain images and so on. In this article, I’ll describe how we implemented a deduplication system under the guidance of PSIAlt.
Add a Fullscreen Menu to your Adobe Muse Website. No Coding Skills Required.
A big part of a website is the navigation menu. Well designed menus can make navigating a website easier and more interesting. One of the first things I look for when looking at a website is where the menu is located and how it functions. Since the inception of web development menus keep evolving and getting more creative. I personally love menus that animate from different directions when you click on the menu button, and menus that cover the entire screen.
One of my first widgets was the BIG Menu Widget. It consists of 11 fullscreen menus that cover the entire website when clicking on the menu button. I have recently updated it to allow for custom open and close buttons. You can also rotate the open and close button on hover. There is now the ability to close the menu when clicking on the links as well which is very useful on a one page scrolling website. In the video tutorial above I go over the new features and updates to the BIG Menu Widget.
Here are the steps to add the BIG Menu Widget:
1. Install the widget by double clicking on the .mulib file. The widget will then install into the Adobe Muse library panel. If you do not see the library panel go to Window > Library.
2. From the library panel you will be able to select from 11 different fullscreen menus. To find the BIG Menu widgets quickly type in “BGMNU” in the library panel search bar.
3. Drag and drop a menu onto your Adobe Muse website. At first you will just say a 50×50 box with an exclamation point. This is because an open button image has not been added.
4. Add a custom open button image in the “Open Menu” section. You can change the size of the open button as well as enable rotation on hover. Within the widget folder there are icons to help you get started if you do not have your own custom icons.
5. Add a custom close button in the “Close Menu” section. You can change the size of the close button as well as enable rotation on hover.
6. In the “Menu Styling” section you can select the color for the menu overlay as well as style the text for the links.
7. To change the font for the menu select the widget and use the built-in Adobe Muse “Text” option in the upper toolbar. From here you can select any web font from the fonts menu.
8. Select the amount of menu items for the menu in the “Menu Items” section. Here you can also set the text for the menu items and the links. You can link to an anchor point, internal page, or external page. There is a “Linking – More Info” section for reference on how to link the menu items.
9. Go to File > Preview Page in Browser to see how the menu looks.
10. Done!
For more video tutorials and widgets for Adobe Muse visit http://museforyoushop.com.
Can it be done with CSS? Do I need JavaScript? I know a lot of us ask these question when looking at designs and interactions. Recently I decided to dig into CSS and learn all of the properties. I spent a lot of time reading reference material, writing code, and finding new solutions to old problems with my newfound knowledge.
Through my journey, I thought I would document and showcase 50 of the most interesting properties and values I found. I created use-cases for many of them, with simplified code samples you can look at, reference, and play with. I also included a number of properties that are still experimental, but will likely be usable soon. I also included several well-known properties but with lesser-known values, so you can deepen your knowledge of them even if you’ve already heard of them. There are also some browser-specific things in here.
The all property resets every other property (apart from unicode-bidi and direction) properties to their initial or inherited state. It accepts these values:
initial: changes all the properties of the element or the element’s parent their initial value inherit: changes all the properties of the element or the element’s parent to their parent value unset: changes all the properties of the element or the element’s parent to their parent value if they are inheritable or to their own value if not
Angles can be valid CSS values for some properties. We often use something like transform: rotate(180deg), but “deg” isn’t the only possible unit here. You can also use grad, rad and turn as well. Our transform: rotate(180deg), for example, could be written as transform: rotate(0.5turn) as well. Say you want to rotate an element 4 times, it might be the easiest choice to write rotate(4turn).
I tested it in Chrome 54, Opera 41, Firefox 50 and Safari 10.
This property specifies what styles are applied to the element when the animation is not playing. Imagine a @keyframe animation that fades an element out (from opacity: 1; to opacity 0;). By default, after the animation is complete, it will jump back to its initial state.
none: (default) element gets its initial styling when the animation is not executing forwards: animation will apply the values set by the last keyframe executed. Note, that it may not be the state of the “100%” or “to” keyframe. If you set animation-iteration-count to 1.5, the last keyframe will be the 50% keyframe. Or, if the animation-direction set to reverse, the last keyframe will be the “0%” or “from” keyframe backwards: will apply the property values defined in the keyframe at the beginning of the animation both: the animation will follow the rules of both forwards and backwards initial: sets animation-fill-mode to it’s default value inherit: element inherits animation-fill-mode value from its parent
You can see in the popular library Animate.css, the .animated class uses animation-fill-mode: both.
animation-iteration-count
This property defines the number of times a @keyframe animation repeats. It can also be a non-integer value, like animation-iteration-count: 1.5, which will play one full animation cycle plus half of the cycle.
This property specifies whether the “back” side of the element is visible when the element is rotated. It is used with 3D transforms. Accepts the following values:
visible: (default) back side of element will be visible, when rotated hidden: back side of element is not visible initial: sets the property to its default (visible) value inherit: get the property value from its parent
This property specifies if the background-image stays fixed within the viewport when you scroll the page or scrolls along with the page.
Scroll: (default) background is fixed to the element and does not scroll with the contents Fixed: the background stays fixed when you scroll the page (or element) Local: scrolls along with the elements contents, if the element is scrollable
This property specifies how element’s background images, gradients, and colors blend with each other. For example, you could add a background-image and background-color, then set the blend-mode to “lighten”. You can also specify several blend modes, one per background.
The background-clip property defines the area of the element where the background is applied. You can make the background go underneath its border or fill only the area of its contents.
border-box: (default) allows background extent to the outer edge of the border content-box: the background is clipped to the content box of the element padding-box: the background is clipped to the outer edge of the element’s padding, so it’s applied to the content and the padding, but not underneath the border text: the background is clipped to the foreground text.
This property defines if the background is applied to only the element’s content area, or padding and border areas as well. The difference between this and background-clip is that background-clip crops the background, and background-origin resizes it.
box-decoration-break
This property specifies how the element’s background, padding, border, box-shadow, margin, and clip are applied when it’s wrapped onto multiple lines. If we have text wrapped on multiple lines, it would normally increase the element’s height, however, box-decoration-break can apply the styling to each line separately, instead of the whole element.
clone: every fragment of the element receives styling, box shadows and padding are applied to each fragment individually slice: the element is rendered as if the element is not fragmented
Note: you can only use box-decoration-break on inline elements. According to MDN you can only use it on Firefox and Chrome inline elements, but I tested it and current browsers show different results. It works on Firefox and Chrome 54, Opera 41 and Safari 10 with the -webkit- prefix.
The calc() function can be used to create values. For example: width: calc(100% - 32px) will make element full width minus 32 pixels. It can be very useful for setting a column width and subtracting the margins. No need for nesting two elements and giving padding to the parent element to achieve the same result.
It accepts an expression with addition, subtraction, multiplication and division operators. Operands can be any syntax length values. You can even do something like calc(var(--someValue) / 2 - 2em)
A fallback would be like this, for browsers that don’t support it:
width: 98%; /* fallback for browsers without support for calc() */
width: calc(100% - 1em);
column-count
The column-count property specifies the number of columns an element has. column-count: 3 will spread the elements text (or inline-* elements) into 3 columns. You can apply it to inline-block and block elements. This will not work on an element with display: table, but will work on display: table-cell.
There are a number of other column-* properties:
column-gap: property specifies the size of gap between the columns column-rule: is a vertical line drawn between the column visually separating them. It’s a shorthand for setting this 3 properties (it is very much like border-*) column-rule-color: specifies the color of the line. The value can be a named color (red, green, transparent), hex, rgb/rgba, hsl/hsla color values column-rule-style: specifies the style of the line. It accepts the following values: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset column-rule-width: specifies the width of the line and accepts named values (thin, medium, thick), px, em, initial, inherit and unset
The content property is used in conjunction with pseudo elements like ::before and ::after. Here’s one trick you can do with them. It’s a neat way to create a comma-separated
.
ul > li:not(:last-child):after {
content: ", ";
}
counters
Counters let us give numbers (indexes) to elements. For example, you have an article, with several topics, each topic has an
heading in the beginning, and you have subheadings. You can automatically number them!
There are four properties to work with counters:
counter-reset: resets or creates a counter. the value of this property is the name of the counter that you define counter-increment: increments the counter. the value is of this property is the name of the counter that you want to increment content() use :before pseudo class and content() to add the index to the elements counter() function to retrieve the value of the counter
body {
counter-reset: heading; /* init the counter for headings (you can give it any other name) */
}
h2 {
counter-increment: heading; /* increments the counter on every <h1> tag */
counter-reset: subheading; /* here we init or reset the subheading */
/* so that we get 1.1, 1.2, 1.3, then after new heading it will go 2.1, 2.2, 2.3 */
}
h2:before {
content: counter(heading) " - "; /* using :before selector and counter() function we can add the index to the heading */
}
h3 {
counter-increment: subheading; /* increment the subheading counter on every <h2> tag */
}
h3:before {
content: counter(heading) "." counter(subheading) " - ";
}
The filter property applies visual effects to elements. It comes with predefined functions like blur, brightness, contrast, sepia; and you can also apply custom SVG filters.
Here’s a trick: you can convert base color into an entirely differnet color using filters. You do it by manipulating Hue, Saturation, and Lightness. For doing so, you have to convert colors from RGB to HSL, then subtract the H, S, and L values. I’ve created a simple calculator, that generates a filter that converting base color into approximately the given target color:
The flex property is a shorthand property as part of flexbox layout. The most common usage of it is flex: 1; which pushes an element to take up as much room as it can, or balances how much space it is using with other elements also using the flex property. The default value for flex is 0 1 auto.
flex-flow
The flex-flow property is a CSS shorthand for flex-direction and flex-wrap. It accepts the values of flex-direction (row, row-reverse, column, column-reverse), values of flex-wrap (nowrap, wrap, wrap-reverse). But you can also use it like flex-flow: row nowrap;
flex-basis
The flex-basis property defines the initial size of a flex element (a bit like width, in a horizontal flexbox layout). It accepts width values like px, em, and auto. It also accepts intrinsic sizing keywords: fill, max-content, min-content and fit-content, but those work only in Edge right now.
font-kerning
The font-kerning property specifies if the browser shall use kerning information stored in the font or disable it. It accepts the following values:
auto: the browser decides whether to use kerning information stored in font or not normal: kerning is applied none: prevent browser from using kerning information
You don’t actually use this property to kern type. Instead, you’d use letter-spacing for specifying the space between letters.
font-smoothing
The font-smoothing property controls how anti-aliasing is applied to the font. The problem is that after the standard browser anti-aliasing your font may look slightly different from what you see in design software. Here’s the situation between Webkit and Firefox:
-webkit-font-smoothing:
none: turn off anti-aliasing, display fonts with sharp edges antialiased: smooth the font on a pixel level, this make light text look lighter on dark backgrounds subpixel-antialiased: smooth the font on a subpixel level for a better look on non-retina displays
-moz-osx-font-smoothing:
auto: let browser choose the smoothing method grayscale: render text with grayscale antialiasing. this gives similar output as “antialiased” on webkit, and makes light text look lighter on dark backgrounds.
The value small-caps for font-variant will let us display the text in small capital letters. This can be useful when used together with the CSS ::first-line selector
Grid layout in CSS lets us create two-dimensional grids without the problems we used to have with tables and floats. It’s a good idea to learn now as widespread support is coming soon.
A grid consists of the container and the items inside it. Then you have to specify how the space is distributed between rows and columns. The values represent column sizes and you can also give names to them.
Note in the “grid-template-columns” the first and fifth columns have 40px width, the second and fourth columns 50px width, and the column in the middle will get the rest of the space. Let’s see how to position item inside the container. We have to actually set the starting and ending points to the element. The item would have the following CSS applied to it:
.item {
grid-column-start: 2; // will start at the point where the second column starts
grid-column-end: 5; // will end at the point where the second column starts
grid-row-start: 1; // will start at the point where the first row starts
grid-row-end: 3; // will end at the point where the third row starts
}
hyphens
The hyphens property specifies how the browser hyphenates the text.
none: no hyphens applied, the text will overflow the container auto: browser will automatically hyphenate the text manual: manually specify potential break points
There are two line break characters you can use:
&shy; – will let the browser know that it’s a place in text where the hyphenation may be performed if necessary &hyphen; – will render the hyphen even if the line is not broken
The image-rendering property specifies how the image is rendered when it’s scaled. Browsers automatically apply aliasing to resized images, and you can control that with these properties:
auto: (default) the browser automatically applies aliasing crisp-edges: the contrast and edges are preserved, so that they are not smoothed or blurred when scaled pixelated: this value is applied only to the upsized images and makes the image appear pixelated
While most of the time we use list-style-type: none; on the
and then apply background on the , you can still consider applying list-style-image property to the
element to use an image as a marker in the list.
ul {
list-style-image: url('square.gif');
}
list-style-position
The list-style-position property specifies where shall the list marker appear. It accepts two values:
inside: markers appear inside the list item content box outside: markers appear outside the list item content box
object-fit
The object-fit property specifies how an image () element is fitted into the box established by its height and width. By default, and image will squish or stretch (if it has to) to fit the dimensions of the image box. But with this property, you can choose other options to have it scale while maintaining its proportions internally.
fill: (default) the contents of the element are size to fill the entire content box (without maintaining the aspect ration) contain: the contents of the element are fitted inside content box maintaining the aspect ratio cover: the contents of the element are fitted inside content box maintaining the aspect ratio, but fill the entire space none: the contents are not resized but cropped using the given height and width scale-down: automatically chooses between contain and none, selecting the option what would cause the smallest object size
Be warned it doesn’t work on IE11 and Edge 14 and 15. Opera Mini supports it with the prefix -o-. On the rest of the browsers it works great without any prefixes.
orphans
This property helps you control how line breaks in text appear. It accepts a numerical value, that indicates the minimum number of lines of the block container (e.g. paragraph) that shall be left at the bottom of the page if the whole container doesn’t fit on the page or in the column.
The order property specifies the items within a flex container. the value is a number, which can be negative as well, or “inherit”, “initial”, “unset”.
This code will display the items in the 2, 3, 1 order.
overflow-wrap
This property specifies if a line break shall occur in long words if they do not fit in the container as one word.
normal: break words at normal break points break-word: break normally unbreakable words, if there is no space
It also accepts all the normal global values: inherit, initial, unset.
page-break-*
There are three CSS properties that allow you adjust page breaks:
page-break-before: controls page breaks before the element page-break-after: controls page breaks after the element page-break-inside: controls page breaks inside of the element
These are useful when trying to control how pages print. These are the possible values for them:
auto: automatically break pages always: always insert a page break before or after the element (even if there’s a lot of space) avoid: avoid page break before/after/inside of the element if possible left: insert page break so that the next page is formatted as a left page right: insert page break so that the next page is formatted as a right page recto: acts as right if page goes left-to-right, and left if right-to-left verso: acts as left if page goes left-to-right, and right it right-to-left
There are several things you should know:
The recto and verso values are still experimental
The page-break-* property is going to be replaced by more generic break-* property in the near future
Most browsers support only page-break-inside (not page-break-before or page-break-after)
All browsers except Opera Mini, IE and Edge treat “left” and “right” values like “always”,
so it’s a good idea to check if you can use it first.
percentage
Percentage values are like width: 10%. In that example, the element it is applied to would be 10% the width of the parent. But there are other properties that are based on the with the parent as well. For example, padding. If we have a container that is 400px wide 300px tall and has padding-top: 10% and padding-left: 10%, padding on both will be 40px (not 40px and 30px)!
perspective
The perspective CSS property gives an element perspective in 3D (it’s only relevant on 3D transformed elements). Its value is the distance from the viewport to the elements z plane. The value is length, that can be represented in px or em, or the “none” keyword.
The property has to be applied to the parent element (the container) or the element that you want the perspective to be applied on.
This property specifies how elements react to mouse events.
auto: the element behaves normally none: ignores all clicks, selects, dragging, etc.
It also has special values that are unique to SVG elements:
visiblePainted: the filled and stroked part of the element are a target. The visibility has to be set to visible and stroke value to other than none. visibleFill: only the filled part of the element is a target. The visibility has to be set to visible. visibleStroke: only the stroked part of the element is a target. The stroke value has to be other than none. visible: the filled and stroked part of the element are a target when the visibility of the element is set to visible. painted: the filled and stroked part of the element are a target. The visibility of the element does not affect event processing. fill: only the filled part of the element are a target. The visibility of the element does not affect event processing. stroke: only the stroked part of the element are a target. The visibility of the element does not affect event processing. all: the whole element is a target. The fill, stroke, and visibility properties of the element do not affect event processing.
position
You’re probably familiar with position values like static, relative, absolute, and fixed. There is another interesting value: fixed.
The elements that have position: sticky are treated as relative, until they get to the certain point, then they become fixed. Think: iPhone contacts list letter bookmarks or scroll-then-fix navigation. This is normally something we’d have to use JavaScript for, but now is doable in pure CSS.
The resize property defines whether the element can be resized by user. You can make an element resizeable vertically, horizontally or both.
none: element is not resizable. This is the default value for most elements, except textarea which is “both” by default both: resizeable both directions horizontal: resizeable horizontally vertical: resizeable vertically
Important: in order to make an element resizeable, its visibility has to be set to something other than visible.
shape-outside
The shape-outside property lets us wrap text in a shape around a floated element. Maybe it’s a round image and you want text to wrap around that circle. The property will be applied to the element which you want to wrap the content around. It accepts the following values:
You can also pass a URL to an image around which the content will wrap, and it accepts the global initial, inherit, and unset values.
If you choose to use an image, the shape-image-threshold property will define the alpha channel threshold to separate the shape from the image. Firefox and IE still don’t have support for this property, and Safari supports it with the -webkit- prefix.
@supports (display: grid) and ((image-rendering: crisp-edges) or (image-rendering: pixelated)) {
}
var()
The var() property is part of using CSS custom properties.
CSS variables are defined by authors and represent specific values the can be used multiple times in the document. The var() function can be used as the value of any property, but cannot be used as a property or selector. The first value of the function is the name of the custom property; the second is an optional fallback value, which is used if the first argument is invalid.
Let’s take a look at the syntax:
:root {
--primary-color: #cccccc;
}
body {
color: var(--primary-color);
}
With a fallback value:
body {
color: var(--primary-color, #cccccc);
}
In Sass, that would be just like:
$primary-color: #ccc;
body {
color: $primary-color;
}
The text-transform property can change the case of text to lowercase or uppercase. You can also capitalize the first letter of each word with capitalize.
One thing to consider: is it more-correct to use ALL CAPS type right in the HTML, or use normally cased type and use text-transform: uppercase in CSS to change it? It’s probably better to use CSS. For example, Contact us vs CONTACT US. A screen reader might read “contact U.S.” with uppercase in the HTML, instead of “Contact Us”.
transition-timing-function
The transition-timing-function property specifies the speed curve of the transition effect, like ease-in or ease-out. Here are two lesser-known known values:
steps(n, start|end): instead of specifying smooth transiting with such timing functions as ease, this completes the animation in number of steps you define. The second parameter is optional and specifies at which point within the interval shall the change occur. The default values for the second parameter is end. You can also use the shorthand functions step-start(n) and step-end(n). cubic-bezier(n, n, n, n): your own cubic bezier function.
Use this tool to create cubic bezier timing functions.
You can also use Chrome dev tools to modify the bezier curve.
vh, vw, vmin, vmax
These values are used for sizing things relative to the viewport size. While width is alwasys relative to the parent container, vh or vw always use viewport size as a basis.
vh: 1 vh is equal to 1/100 of viewport height vw: 1 vw is equal to 1/100 of viewport width vmin: it is the least value of vh and vw vmax: is the largest value of those two
For a browser window that has a viewport 1280x655px, 1vh is equal to 6.55 pixels, 1vw is equal to 12.8pixels, vmin is 6.55 pixels (smallest of the two values), and vmax is 12.8 pixels (largest of the two values).
white-space
This property defines how the white space inside the element is handled.
normal: collapse new lines, collapse spaces and tabs, text wrap nowrap: collapse new lines, collapse spaces and tabs, text nowrap pre: preserve new lines, preserve spaces and tabs, text nowrap pre-wrap: preserve new lines, preserve spaces and tabs, text wrap pre-line: preserve new lines, collapse spaces and tabs, text wrap
The equivalent of letter-spacing, but for words! You can increase (or decrease) the amount of space between words. The standard value for this property isnormal, whiuch uses the default whitespace: 0.25em.
will-change
The will-change property lets authors tell browsers what changes to expect on an element. Changes, as in, changes to property values, likely as part of an animation. The idea is to give the browser a heads up on animations you intended to perform, as the browser can’t always predict this. When you give a hint, it can optimize for performance.
normal: perform standard optimizations scroll-position: prepare the browser for scroll position changes content: the contents of the element will change
You can also set specific properties that you will be changing, like this:
.will-be-animated {
will-change: top, left;
}
Before the introduction of this property, we used to use tricks like this to trick the browser into animating certain elements with better performance (by “forcing” the element “onto the GPU”):
This article is a good deep-dive into the subject.
writing-mode
The writing-mode property defines whether the text is laid out horizontally or vertically also the direction.
horizontal-tb: content flows from left to right, from top to bottom vertical-rl: content flows from top to bottom, from right to left vertical-lr: content flows from top to bottom, from left to right
This CSS pseudo-class matches input elements that have been autofilled by the browser. This gives you a chance to change that style. In Chrome, for example, they have yellow background by default.
-webkit-overflow-scrolling
This property lets us the the iOS momentum scrolling on elements on touch devices. There are two values:
auto: use normal scrolling, where the scrolling stops the moment when you remove your finger from screen touch: use momentum scrolling
-webkit-touch-callout
This property lets us hide the default callout on iOS devices. When you touch and hold the target a menu appears with information controls.
none: disables the callout default: callout is displayed
-webkit-scrollbar
There’s a way to hide scrollbar on an element
#container::-webkit-scrollbar {
display: none;
}
There’s also a way to autohide scrollbars on IE10+ and Edge.
html {
-ms-overflow-style: ms-autohiding-scrollbar;
}
Rachel Andrew with a clear (get it?!) explanation of display: flow-root;, including demos comparing old and new techniques. Apparently the name is still a little bit still up in the air.
The whole point of it is getting rid of clearfix, or using a different/unintended property for float clearning. Every time this is brought up, there is always a well actually about how overflow: hidden; does the same. Like we mentioned before, overflow has consquences totally unrelated to float clearning, like hiding shadows.
In the simplest terms that I can think of. To me, programming workflow (if you look at it in a broad sense) is very similar to a game most of you have played once in your life.
I know it is probably not the same one you have played when you were a kid, but bare with me. So with this game, you have a beginning point. to. You have to navigate through the different options (or pipe placement) to reach the outcome you want, the purpose. With this you can can navigate to the same end point in a few different ways, but all reach the same conclusion. Or they will navigate away from the expected output to a defined end point, where you have to either start over, or travel to a different outcome. As a programmer you have to be able to envision all possible outcomes from a single start point and what conditions need to be met to retrieve the outcome you want to meet to proceed.
Conditionals are one of the foundations of programming. If “something” is met, then do “something” else, and travel through the possible outcomes to reach the user’s goal.
Ruby conditional’s control the flow of the program that you are building. This includes if, else, and elsif.
This workflow looks something like this:
If (condition to be met)
code to run if condition is met
else
code to run if condition is not met
end
You can also add an elsif statement, which creating more conditional statements that could possibly be met. You can add as many elsif statements as you would like.
The control flow structure is a language feature which disrupts the normal progression to the next statement and conditionally or unconditionally branches to another location in your source code. This is controlled through if, elsif, and else returning true or false.
So far with the school I feel I have made some real progress. The school has been very enjoyable so far and I am learning and grown as a programmer immensely. When I started, I thought this would be very similar to other web courses I have gone through, which I am very grateful that is not the case. The Flatiron School really pushes you to think, and allows the student to write many different options for an acceptable correct answer.
Each lesson is setup with its own test suite, that basically checks that the output of your methods are correct but leaves it up to you to figure out the best possible way to retrieve and display that value. I have a long way to go, but I am amazed by the progress I have made so far and really looking forward to the other sections I will be dealing with soon.
Color is arguably the second most important aspect of your app, after functionality. The human to computer interaction is heavily based on interacting with graphical UI elements, and color plays a critical role in this interaction.
It helps users see and interpret your app’s content, interact with the correct elements, and understand actions. Every app has a color scheme, and it uses the primary colors for its main areas.
As UX designers, the most valuable tool we have is knowledge of how users are interacting with our products. It’s impossible to design a valuable, and successful site without a deep understanding of how users experience it in the real world.
One tool for developing a comprehensive understanding of how your users experience your site, from first scrolls, via rage clicks, and all the way through to your sales funnel, is FullStory. FullStory is a pixel-perfect playback tool that’s being embraced by designers across the globe. FullStory records every click, swipe, hover, scroll, and keypress from user sessions so you can dive right into your user’s experiences. It’s the next best thing to actually peering over their shoulder—actually, scratch that, it’s better, because these aren’t lab tests, they’re real analytics from real customers.
That all sounds amazing right? Well, it only gets better. Because now, for the first time, FullStory is launching a Free Edition. Now you can get all of these pro-studio insights, on a freelance budget.
FullStory is built for teams, and all of your recordings can be annotated and shared. Seen a confused user looking for button? Send it to your UI designer. Spotted a dropped cart? Pass it on to your content team to improve your sales pitch. FullStory helps you design the site your users really want.
A brand new tool that has just been introduced—exactly the kind of deep-insight utility that makes FullStory so useful—is OmniSearch, which powers FullStory’s extensive searches. You can run queries like “checkout” or “Atlanta”, and FullStory will return all of the sessions related to those terms. You can even filter the search results based on key values like device, or whether the user completed a purchase. This useful tool is part of the new Free Edition, and is provided free forever!
FullStory’s founding engineering team came straight from Google, and brought with them an appreciation of how search functions as a tool. Up until now, analytics platforms have amassed an unmanageable amount of data; you can view a session, but how do you know it’s a useful session? Monitoring analytics as they come in is a full time job. The leap that FullStory has taken with OmniSearch means you can pin-point the data you need, drawn from all of your records. With a simple search, you can retrieve data about a type of user, a particular process, even combine searches to find, for example: high-value customers, using mobile devices, in the Detroit area. Not only that, but OmniSearch is intelligent enough to suggest searches for you; simply start typing your key terms, and the platform will point you in the right direction.
Understanding customers, and gaining actionable insights into how they experience your product, helps you deliver a better user experience. With FullStory’s new OmniSearch feature, you can discover more than ever before. With a setup time of around five minutes, and the launch of the brand new Free Plan, FullStory makes professional-grade analytics available to all designers.
[— This is a sponsored post on behalf of FullStory —]
Small agencies are jacks of all trades, but masters of none. Usually, there is no specialization, because it’s just not worth it. Are these statements even true, and if they are, how do these generalists survive?
The question of survival as a small, or the smallest, agency is asked on multiple levels. In a beautiful infographic, Laura Müller and Luis Masallera deal with the human, and social aspects of this question. I definitely don’t want to withhold it from you:
The recommendations are the following:
Fight for a proper fee, but stay realistic.
Work hard, but also do some small talk.
Be friendly, but don’t crawl up anyone’s ass.
Take off the blinkers so that you can recognize miracles.
Don’t forget to go home.
Stand by your mistakes.
Keep yourself healthy.
Ask for help.
Learn to say “no.”
Take time for your passion.
I assume that no freelancer would disagree with this advice. We could probably call it a core set of advice for a balanced life as a freelancer. Now, if two or more of these freelancers got together, and founded an agency with this mindset, we wouldn’t have to worry about the sanitary basics, neither in physical nor in psychological aspects.
Fast Times, Fast Agencies: The Advantage of “Small.”
Now, it’s time to take care of the business components of small agencies. Those remaining from the nineties, like me, know that we had to keep on learning new things to survive in the business of the web, and graphic design. However, with decent effort, this was still doable back then.
Today, unifying the entire knowledge on everything related to web development, and other design-related topics in one person is simply impossible. Thus, it seems logical for an agency to take care of certain areas only, meaning to specialize itself. But in reality, there are only a few large agencies. Because of that, the path in this direction will probably block itself, even if you wanted to take it.
In my opinion, this shouldn’t be your goal either way, since large agencies are barely any different from other large businesses. You’ll always have that one guy sitting there, ruining your day. It might seem cool when you see the relaxation areas, and football table rooms of modern agencies, and other digitally working businesses. But the truth is, that even these companies also put on their trousers one leg at a time. All of these conveniences have to be earned, nobody else puts money into that. And who makes the money? Right. You, the employee. So don’t be jealous of those that have to put some of their earnings into free latte macchiato or squash arenas.
I would never join a large agency. I’m way too particular, and I have never liked Management by Champignon. My customer care is much more direct, much more personal, and adjusted much more accurately to their needs than it could ever be at any large agency.
Take a look for yourself to see, what happens with big business that is too sluggish to change quickly. Just take Blackberry, Nokia, or Kodak. Former market leaders are shadows of their former selves. Why is that? For one, companies with increasing size become increasingly sluggish, preventing them from acting fast where it’s needed. But a certain size also always comes with some kind of institutional conceit. The human factor becomes relevant. Intrigues are schemed, battles for power are fought. The customer is pushed into the background and turns into a number in the sales statistics.
The smaller the business, the more flexible, the faster it is. These days, speed is an undisputed advantage over the competition. Inflated structures remove the actual service from the client. Take the German Telekom for example. If you have a technical problem, try to get through to a real expert that will fix your problem in the end.
Of course, the state of “too small” is also a thing. When approaching a customer that needs an entire website, telling them that you can only deliver the pixels, but not the code, won’t get you anywhere either. You have to be able to come up with a defined project size from one hand.
There are two ways to do that. You either build up a cooperation network with people whose abilities you know, who you trust, and that wouldn’t rip you off. When it works, this is the best variant. Unfortunately, the human factor broaches way too often, destroying such loose structures faster than they were built.
The second option is founding a small agency. You define your target group and make a qualified assessment of its size. Then, you look at which project dimensions typically occur, and divide them into their components. Here, you’ll find out what percentages of pixels, CSS, JavaScript, CMS, and so forth have to be provided.
Once done, it’s rather easy to calculate a number of people. You need x frontend developers, x designers, x backend developers, x SEO strategists, and x others. Writing the business plan can be done pretty quickly after that. Your small agency eliminates the risks of loose cooperation networks but comes with a turnover risk that is not insignificant.
How to Position Your Small Agency
Let’s assume you already own a small agency, and you are generally aware of the advantages. However, large agencies give you a tough time, since their money doesn’t grow on trees anymore, making them step down to small, and midsize customers. Some even undercut your prices, just to pay for their juggernaut of employees. I like to call this money exchange. But for you, this is life-threatening. No theoretical advantages regarding agility or flexibility can help you here. You need something more tangible. You have to communicate.
This is How You Could Approach Customers:
Define Your Target Group
If you have specialized in a certain branch, you have to communicate clearly to this target group. Don’t leave any doubts that, with you and your agency, the person you approached is in the best possible hands. Especially in web design, there are tons of examples of former pastry chefs that now create websites for the craft of baking, or the medical technological assistant bringing doctors into the web of webs.
Set Yourself Apart From Large Agencies
Make clear that the customer will get a counterpart that supervises the entire project, instead of the client being handed from department to department. Highlight your flexibility, and the ability to stay responsive even during the work on the project. Make sure your customer knows that your pool of experts from different disciplines always takes part in every project, allowing for the most innovative solutions to be made up.
It’s not prohibited to hand over the savings from not having to pay for a feel-good manager, a private gym, and a free employee canteen, to your customer, and mention it.
Highlight the Customer Proximity
Big agencies are in big cities, so are big customers. What you want are the small and medium-sized enterprises that can be anywhere. I once randomly found a company with 400 workers in a secluded forest in the middle of nowhere.
Proper supervision is important to these customers. This is possible if you are close to them, and not have to travel all the way from a large city. Another advantage is that you know the region if this were to be a factor in marketing. The aspect that you can drive over to the customer is huge. Don’t underestimate the psychological effects of good client supervision.
Of course, it’s tempting when the internet allows you to work for any customer in the world, no matter where he is. But it’s a fact that people don’t work like that. Humans do business with humans. Don’t waste your time casting your net so far that you won’t catch anything in the wide meshes in the end.
Focus on Quality
This sounds profane, doesn’t it? However, when I look at what some large companies produce, I can only shake my head. Quality does not seem to be a factor there. I can actually understand this.
In the large agencies that I know, the commission is done once it has been placed. What’s that supposed to mean? Well, there is a lot more attention on the acquisition. In at least weekly meetings, the leads are being talked about, and the liquidity is being complained about. Once the commission has been placed, the customer becomes a part of the turnover list, and, tragically, his commission has to be completed on top of that. Shoot, but hurry up. So that we don’t have to put too much money into it.
You should do this very differently, with the old manufacture concept in mind. In the end, the result will be the best one possible. Your focus is not on the placement of the commission, but on its completion.
These are my tips from 25 years of experience in a fast-paced branch. What do you think about the topic? Are you a freelancer, or an employee of a small, or large agency?
Six years ago I started working furiously on this little side project about package management for Windows. It started to grow and over time it became clear that it was going to be something important. A community flourished and there was a tremendous uptake for this little tool.
Fast forward to present, starting soon I will be focused solely on Chocolatey as the Founder of Chocolatey Software, Inc*! It’s an exciting opportunity to really see where we can take this Windows software management thing!
I also could not have had the opportunity to move forward without the support of a tremendous community, who has contributed to Chocolatey’s success in many ways. Your support does not go unnoticed – we will continue to make open source improvements, along with ensuring that organizations can take Chocolatey to the next level with Chocolatey for Business.
It’s a bit bittersweet as I’ve had the opportunity work with a lot of fantastic folks at Puppet and do some really awesome things for furthering automation on Windows. In many ways Puppet has been an amazing place to work (I highly recommend it, they have the remote employee situation handled). However, an opportunity to follow my first love, Chocolatey, is a dream I won’t pass up.
Not everyone gets the opportunity to follow their dreams, so when you get a chance it can be both a thrilling and scary experience! Here’s to the future of Chocolatey and Windows automation!
* – For those keeping track – Chocolatey Software was formed in November 2016 as a spin off of RealDimensions Software, LLC