10 Design tips by Jason Zhu

When HP first hired designers in the founding years of the Silicon Valley, their attitude was to hire people who weren’t smart enough to be engineers but were smart enough to do technical drawings and out the logo on the box.
Yes, graphic design is centuries old but respect was not really paid to technology companies until Steve Jobs. It was the attitude of many technology companies years ago to bring in designers at the end of the cycle to make things look nicer, lipstick on a pig, it’s only been recently that designers have been core from the early stages.
I don’t think the author meant any offense. If anything he’s commenting on how design wasn’t given its proper due in years past.

5 Web Design Trends for 2021

This sponsored article was created by our content partner, BAW Media. Thank you for supporting the partners who make SitePoint possible.For almost everyone, 2020 was a bummer. Many businesses were forced to take creative measures just to survive. Consumers had to make adjustments as well, and even the Web has had to make some changes. 
Some of “yesterday’s” design trends had to make way for new ones too.
What, then, can we expect to see in the way of new design trends in 2021?
We’ll show you some examples of websites that have incorporated some of these new trends, along with a selection of BeTheme pre-built websites that are also putting them to good use.
Whether you’ll be creating sites for new clients or reworking existing sites to align with the newest trends, the following five design approaches should give you some valuable insight.
1. Use Soothing, Reassuring Color Palettes
Recent design trends have favored strong, bold colors. Various gradient schemes have also been both popular and effective. Why? Because these distinctive trends had a strong tendency to capture a visitor’s attention.
2020 gave us more than our fair share of worry, stress, and drama. We eagerly look forward to a return to a time in which we’ll once again feel more comfortable in our surroundings.
We don’t want people shouting at us, or websites shouting at us either, for that matter. Hence, the change to calmer, more toned-down color palettes.
The Bellroy website offers a good example of this toned-down look, with a calming color scheme that fits right in with its line of useful everyday products.

Note that when a brightly-colored product is displayed against a natural color palette it will still stand out, but without getting in your face. The BeSpa pre-built website, with its soothing color scheme, is another example of sending a message that’s calm and inspiring.

Calm and comfortable doesn’t need to be boring. Far from it. An image like this encourages a visitor to live for the moment, and the safety and security that goes with it.

2. Strive to Creatively Blend Physical Experience with Digital Imagery
For the first time in their lives, many people found themselves stuck at home in 2020, with little to do but look at their screens — which in some cases involved remote work, and in other cases playing digital games.
Some web designers have picked up on this by blending real-world images with illustrations and/or special effects.
A case in point is seen on designer Constance Burke’s website.

Instead of showing hand-drawn fashion sketches, or real models wearing real products, her portfolio creatively blends the two.
The BeSki pre-built site also blends the digital with the physical, but in a vastly different way.

The home page starts with a physical image of a skier. Notice how the snow in the hero section blends in with the next section, a section comprised of digital imagery. That section then blends into another real image, which blends back into a digital design.

2020 saw more people shopping online — often out of necessity. This created a situation that encouraged website designers to provide visitors with more efficient pathways to conversion.
Since many of these visitors were newly acquainted with online shopping, it was important that their experience would be as effortless as possible — that they could get in and out as quickly as they normally would in a brick-and-mortar store.
This can be accomplished by more concise product descriptions, improved product search capabilities, add-to-cart shortcuts, and the like.
Walgreens’ product page design sets a good example for 2021 eCommerce website design.

The product’s applicable details as well as picking and shipping options, customer ratings, and discounts or special offers are clearly presented and are all above the fold. Customers can either scroll for other relevant information or take their next step.

BePestControl’s pre-built site takes a similar approach.

Pertinent information is kept short and sweet. The customer can either add the item to the cart or read the additional information beneath the button.
Well-designed navigation aids and product description options combine to make the shopping experience a gratifying one.
4. Place Greater Emphasis on User-controlled Video Content
Once upon a time, video was ”the thing” on websites. While no longer new, video remains an effective method of providing highly useful content, but its popularity has taken a hit.
The reason? A lack of user control on too many websites. Videos are fine, but only when visitors feel a need to view them.
Thanks in part to Zoom connecting friends in 2020, more people have become accustomed to what video can offer. And if they’re given a choice as to what to view and what not to view, you can expect videos to make a comeback in 2021 — sans autoplay or embedded versions.
See how Payoneer has incorporated a Watch Video button in their design.

It’s not big and bold, but you can’t miss the way the white button stands out against the darker background. As you might expect, a visitor will appreciate having the option of watching or not having to watch the testimonial.
The BeOptics pre-built website takes a similar approach.

In this case, the Play button acts as a gateway to additional site or product information. The way the button transforms upon hover makes visitors aware that they have an opportunity to learn more by watching the video.

5. Spend More Time Displaying Trust Builders
Trust builders are indispensable website elements. Brick-and-mortar store shoppers may take several minutes to size up a business and decide if they want to patronize it. Online shoppers will do the same in far less time.
Web designers can choose from a variety of trust-building approaches. For example: 
employing charts, statistic callouts, counters, or other data visualization methods
using logos to help to solidify the brand
providing client testimonials, customer reviews, or user ratings
case studies
portfolios
security seals — such as Better Business Bureau (BBB) or TRUSTe
secure checkout and payment — such as PayPal checkout
proof of community service or social good
Consider which of the above would best convince visitors to become valued customers. Or, choose all of the above (although probably not for a one-page site).
Omaze has taken the approach of giving its visitors opportunities to win prizes when they’ve made donations. This website goes a step further by highlighting the good things its donors have enabled it to accomplish.

It has also set aside a space for highlighting reputable publications that have featured Omaze. This serves to bring added legitimacy to the organization.

It also uses data visualization and testimonials to provide an element of trust-building transparency as to how donations are processed and put to use.

No matter the size of the organization or enterprise you’re designing a site for, there’s always room for one or more impressive trust builders.
BePortfolio shows how this could apply to a portfolio site.  

The home page has dedicated a lot of space to several of the trust builders cited earlier: 
counts of satisfied customers
client testimonials
case studies
samples from the portfolio
an impressive display of client logos
It’s simply a matter of giving people more than enough reasons to trust your brand.
Have You Taken Up these New Web Design Trends Yet?
Out with the old and in with the new? Not exactly. Some trends may never go out of fashion — minimalism and bold headline typography to name a couple. But 2020 changed the way we look at some things, and as a result, some design trends need to be discarded and replaced with others to adjust to the new normal.
Whether you want to update and upgrade existing sites or implement these new trends in your new website designs, BeTheme’s 600+ pre-built websites will steer you in the right direction.

25+ Startup & Business Proposal PowerPoint Templates 2021

Presenting a project proposal or startup idea in a slideshow can be a daunting task. But it gets easier when you have the right PowerPoint proposal template at your side. PowerPoint proposal templates allow you to design more attractive and persuasive slideshows to present your various business proposals, ideas, and projects in your meetings. In…

Creating Directionally Lit 3D Buttons with CSS

Creating Directionally Lit 3D Buttons with CSS – SitePointSkip to main contentFree JavaScript Book!Write powerful, clean and maintainable JavaScript.RRP $11.95 I’m not too sure how I stumbled into this one. But something led me to this tweet:

Has anyone done this directional lighting cursor interaction with CSS? pic.twitter.com/zLL7Sk6kW5
— Jed Bridges (@JedBridges) July 1, 2020

And, to me, that’s a challenge.
The button design is neat. But I didn’t want to do a direct copy. Instead, we decided to make a “Twitter” button. The idea is that we create an almost transparent button with a social icon on it. And then that social icon casts a shadow below. Moving our mouse across the button shines a light over it. Pressing the button pushes it onto the surface. Here’s the final result:

Directional Lighting 3D CSS Twitter Button 🐦
👉 https://t.co/qpfzEwUMey via @CodePen pic.twitter.com/zWfwtPaixo
— Jhey 🐻🛠 (@jh3yy) January 30, 2021

In this article, we’re going to look at how you can make it too. The cool thing is, you can swap the icon out to whatever you want.
The Markup
My first-take approach for creating something like this is to scaffold the markup. Upon first inspection, we’ll need to duplicate the social icon used. And a neat way to do this is to use Pug and leverage mixins:
mixin icon()
svg.button__icon(role=’img’ xmlns=’http://www.w3.org/2000/svg’ viewbox=’0 0 24 24′)
title Twitter icon
path(d=’M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z’)

Here, we’ve created a mixin for rendering an SVG of the Twitter icon. This would render the Twitter icon if we invoke it like so:
+icon()

Doing that will give us a big Twitter icon.

See the Pen 1. Render An Icon by SitePoint (@SitePoint)on CodePen.

Because social icon sets tend to use the same “0 0 24 24” viewBox, we could make the title and path arguments:
mixin icon(title, path)
svg.button__icon(role=’img’ xmlns=’http://www.w3.org/2000/svg’ viewbox=’0 0 24 24′)
title= title
path(d=path)

Then our Twitter icon becomes
+icon(‘Twitter Icon’, ‘M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z’)

But, we could pass it a key — and then have the paths stored in an object if we have many icons we wanted to use or repeat:
mixin icon(key)

const PATH_MAP = {
Twitter: “M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z”
}
svg.button__icon(role=’img’ xmlns=’http://www.w3.org/2000/svg’ viewbox=’0 0 24 24′)
title= `${key} Icon`
path(d=PATH_MAP[key])

+icon(‘Twitter’)

This can be a neat way to create an icon mixin to reuse. It’s a little overkill for our example, but worth noting.
Now, we need some markup for our button.
.scene
button.button
span.button__shadow
+icon(‘Twitter’)
span.button__content
+icon(‘Twitter’)
span.button__shine

It’s always good to be mindful of accessibility. We can check what our button gives off by checking the Accessibility panel in your browser’s developer tools.

It might be a good idea to put a span in for our button text and hide the icons with aria-hidden. We can hide the span text too whilst making it available to screen readers:
.scene
button.button
span.button__shadow
+icon(‘Twitter’)
span.button__content
span.button__text Twitter
+icon(‘Twitter’)
span.button__shine

We’ve got different options for applying those aria-hidden attributes. The one we’ll use is changing the mixin code to apply aria-hidden:
mixin icon(key)

const PATH_MAP = {
Twitter: “…path code”
}
svg.button__icon(role=’img’ aria-hidden=”true” xmlns=’http://www.w3.org/2000/svg’ viewbox=’0 0 24 24′)
title= `${key} Icon`
path(d=PATH_MAP[key])

Another neat way with Pug is to pass through all attributes to a mixin. This is useful in scenarios where we only want to pass some attributes through:
mixin icon(key)

const PATH_MAP = {
Twitter: “…path code”
}
svg.button__icon(role=’img’ xmlns=’http://www.w3.org/2000/svg’ viewbox=’0 0 24 24′)&attributes(attributes)
title= `${key} Icon`
path(d=PATH_MAP[key])

If we check the Accessibility panel again, our button only reads “Twitter”. And that’s what we want!
The Styles
Here’s the part you came for — how we style the thing. To start, we’ve dropped this in:
* {
transform-style: preserve-3d;
}

That allows us to create the 3D transforms we need for our button. Try switching that off in the final demo and you’ll see that everything breaks.
Let’s hide the span text from our eyes. We can do this in many ways. One recommended way to hide an element from our eyes, but not those of the screenreader, is to use these styles:
.button__text {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}

Before we start working on our button, we’re going to tilt the scene. We can do this using a transform. Here we chain the transform to get it into the position we want. I spent a bit of time tinkering with values here on live stream to get it close to the original:
.scene {
height: var(–size);
position: relative;
width: var(–size);
transform: rotateX(-40deg) rotateY(18deg) rotateX(90deg);
}

You’ll notice a size variable there too. We’re going to drive certain things for our button with CSS variables. This will make it handy for tinkering with values and the effect. Usually, we’d put these under the scope they’re required in. But, for demos like this, putting them under the :root at the top of our file makes it easier for us to play with.
:root {
–blur: 8px;
–shine-blur: calc(var(–blur) * 4);
–size: 25vmin;
–transition: 0.1s;
–depth: 3vmin;
–icon-size: 75%;
–radius: 24%;
–shine: rgba(255,255,255,0.85);
–button-bg: rgba(0,0,0,0.025);
–shadow-bg: rgba(0,0,0,0.115);
–shadow-icon: rgba(0,0,0,0.35);
–bg: #e8f4fd;
}

These are the variables we’re working with, and they’ll make sense as we build up our button.
The Button
Let’s move on to the button! The button element is going to fill the scene element. We could have applied the sizing and transforms directly on the button. But if we were to introduce other buttons and elements, we’d have to transform and size them all. This is something to be mindful of with CSS in general. Try to make your container elements dictate the layout:
.button {
appearance: none;
background: none;
border: 0;
cursor: pointer;
height: 100%;
outline: transparent;
position: absolute;
width: 100%;
}

Here we strip the button styles. And that gives us this.

See the Pen 9. Strip Button Styles by SitePoint (@SitePoint)on CodePen.

Next, we need to create a common starting point for the button content and the shadow. We can do this by giving each element absolute positioning. The content will have a 3D translate based on the depth variable we defined before:
.button__content,
.button__shadow {
border-radius: var(–radius);
display: grid;
height: 100%;
place-items: center;
position: absolute;
width: 100%;
}
.button__content {
transform: translate3d(0, 0, var(–depth));
}

Note how we’re also making use of the –radius variable too.

See the Pen 10. Give The Button Depth by SitePoint (@SitePoint)on CodePen.

It’s hard to distinguish between the two icons at this stage. And now’s a good time to style them. We can apply some basic icon styling and use a scoped fill for each SVG icon:
.button__content {
–fill: var(–icon-fill);
}
.button__shadow {
–fill: var(–shadow-fill);
}

.button__icon {
height: var(–icon-size);
fill: var(–fill);
width: var(–icon-size);
}

It’s getting there! The icons aren’t the same size at the moment, though. We’ll get to that.

See the Pen 11. Apply Scoped Fill by SitePoint (@SitePoint)on CodePen.

Let’s get the button press in place. This part is really quick to integrate:
.button__content {
transition: transform var(–transition);
}
.button:active {
–depth: 0;
}

That’s it! Using scoped CSS variables, we’re saying remove the z-axis translation on :active. Adding the transition to the transform stops it from being so instant.

See the Pen 12. Press on :active by SitePoint (@SitePoint)on CodePen.

All that’s left to do is style the button layers and the shine. Let’s start with the shadow:
.button__shadow {
background: var(–bg-shadow);
filter: blur(var(–blur));
transition: filter var(–transition);
}
.button:active {
–blur: 0;
}

Another scoped style here. We’re saying that when we press the button, the shadow is no longer blurred. And to blur the shadow, we use the CSS filter property with a blur filter — the value of which we defined in our CSS variables. Have a play with the –blur variable and see what happens.

See the Pen 13. Reduce Blur on Hover by SitePoint (@SitePoint)on CodePen.

For the content layer, we’re going to use a background color and then apply a backdrop filter. Much like filter, backdrop-filter is a way for us to apply visual effects to elements. A common use case currently is to use blur for “Glassmorphism”:
.button__content {
backdrop-filter: blur(calc(var(–blur) * 0.25));
background: var(–button-bg);
overflow: hidden;
transition: transform var(–transition), backdrop-filter var(–transition);
}

We use the value of –blur and apply a transition for backdrop-filter. Because of the way we scoped our –blur variable on :active, we get the transition almost for free. Why the overflow: hidden? We’re anticipating that shine element that will move around the button. We don’t want it wandering off outside, though.

See the Pen 14. Styling Content Layer by SitePoint (@SitePoint)on CodePen.

And now, the last piece of the puzzle— that light shine. This is what’s been causing the icons to be a different size. Because it has no styles, it’s affecting the layout. Let’s give it some styles:
.button__shine {
–shine-size: calc(var(–size) * 0.5);
background: var(–shine);
border-radius: 50%;
height: var(–shine-size);
filter: blur(var(–shine-blur)) brightness(1.25);
position: absolute;
transform: translate3d(0, 0, 1vmin);
width: var(–shine-size);
}

That absolute positioning will sort out the icon sizing. Applying a border radius will make the spotlight round. And we use filter again to give the blurry spot light effect. You’ll notice we’ve chained a brightness filter on the end there to brighten things up a bit after they’re blurred.

See the Pen 15. Styling Shine by SitePoint (@SitePoint)on CodePen.

Using the 3D translation ensures that the shine sits above the button, which it would do. This way, there’s no chance of it getting cut by z-fighting with other elements.
That’s all we need for the styles for now. Now it’s time for some scripts.
Script
We’re going to use GreenSock here for convenience. They have some neat utilities for what we want. But, we could achieve the same result with vanilla JavaScript. Because we’re using scripts with type “module”, we can take advantage of SkyPack.
import gsap from ‘https://cdn.skypack.dev/gsap’

And now we’re ready to start tinkering. We want our button to respond to pointer movement. The first thing we want is to translate the shine as if it follows our pointer. The second is to shift the button depending on where our pointer is.
Let’s grab the elements we need and set up some basic event listeners on the document:
import gsap from ‘https://cdn.skypack.dev/gsap’

const BUTTON = document.querySelector(‘.button’)
const CONTENT = document.querySelector(‘.button__content’)
const SHINE = document.querySelector(‘.button__shine’)

const UPDATE = ({x, y}) = > console.info({x, y})

document.addEventListener(‘pointermove’, UPDATE)
document.addEventListener(‘pointerdown’, UPDATE)

Try moving your pointer around in this demo to see the valuables we get returned for x and y:

See the Pen 16. Grabbing Elements and Creating Event Listeners by SitePoint (@SitePoint)on CodePen.

This is the trickiest bit. We need some math to work out the shine position. We’re going to translate the shine after its initial reset. We need to first update the shine styles to accommodate this. We’re using the scoped CSS variables –x and –y. We give them a fallback of -150 so they’ll be out of shot when the demo loads:
.button__shine {
top: 0;
left: 0;
transform: translate3d(-50%, -50%, 1vmin) translate(calc(var(–x, -150) * 1%), calc(var(–y, -150) * 1%));
}

Then, in our update function we calculate the new position for the shine. We’re basing this on a percentage of the button size. We can calculate this by subtracting the button position from our pointer position. Then we divide that by the position. To finish, multiply by 200 to get a percentage:
const BOUNDS = CONTENT.getBoundingClientRect()
const POS_X = ((x – BOUNDS.x) / BOUNDS.width) * 200
const POS_Y = ((y – BOUNDS.y) / BOUNDS.height) * 200

For example, POS_X:
Grab pointer position x.
Subtract button position x.
Divide by button width.
Multiply by 200.
We multiply by 200 because the shine is half the size of the button. This particular part is tricky because we’re trying to track the pointer and map it into 3D space.
To apply that to the button, we can set those CSS variables using gsap.set. That’s a GSAP method that works as a zero second tween. It’s particularly useful for setting values on elements:
gsap.set(SHINE, {
‘–x’: POS_X,
‘–y’: POS_Y
})

But, if we want to take it one step further, we can use a quickSetter from GSAP, which would be better for performance in real-world scenarios where we’re making lots of updates:
const xySet = gsap.quickSetter(SHINE, ‘css’)

xySet({
‘–x’: POS_X,
‘–y’: POS_Y
})

That makes our update function look something like this:
const UPDATE = ({x, y}) = > {
const BOUNDS = CONTENT.getBoundingClientRect()
const POS_X = ((x – BOUNDS.x) / BOUNDS.width) * 200
const POS_Y = ((y – BOUNDS.y) / BOUNDS.height) * 200
xySet({
‘–x’: POS_X,
‘–y’: POS_Y
})
}

The accuracy of following the pointer would need more calculations to be precise. Have a play with this demo where the overflow on the button is visible and the shine is more prominent. You can see how the shine element loses its tracking.

See the Pen 17. Translating the Shine Playground by SitePoint (@SitePoint)on CodePen.

This demo puts everything where it should be.

See the Pen 18. Translating the Shine by SitePoint (@SitePoint)on CodePen.

Last feature. Let’s shift the button for an added touch. Here, we’re going to base the shift of the button on pointer position. But, we’re going to limit its movement. To do this, we can use another GSAP utility. We’re going to use mapRange. This allows us to map one set of values to another. We can then pass a value in and get a mapped value back out.
First, we’ll define a limit for movement. This will be a percentage of the button size:
const LIMIT = 10

Now, in our update function we can calculate the percentage of shift. We do this by mapping the window width against the limit. And we input our pointer position to get the mapped percentage back:
const xPercent = gsap.utils.mapRange(
0,
window.innerWidth,
-LIMIT,
LIMIT,
x
)

In this block we’re mapping the range of 0 to window.innerWidth against -10 to 10. Passing pointer position x will give us a value between -10 and 10. And then we can apply that percentage shift to our button. We do the same for vertical shift and this gives us an update function like the following:
const buttonSet = gsap.quickSetter(BUTTON, ‘css’)
const xySet = gsap.quickSetter(SHINE, ‘css’)
const LIMIT = 10

const UPDATE = ({x, y}) = > {
const BOUNDS = CONTENT.getBoundingClientRect()
const POS_X = ((x – BOUNDS.x) / BOUNDS.width) * 200
const POS_Y = ((y – BOUNDS.y) / BOUNDS.height) * 200
xySet({
‘–x’: POS_X,
‘–y’: POS_Y
})
const xPercent = gsap.utils.mapRange(
0,
window.innerWidth,
-LIMIT,
LIMIT,
x
)
const yPercent = gsap.utils.mapRange(
0,
window.innerHeight,
-LIMIT,
LIMIT,
y
)
buttonSet({
xPercent,
yPercent,
})
}

That’s it!
That’s how you create a directional lit 3D button with CSS and a little scripting. The cool thing is that we can make changes with relative ease.
For the final demo, I’ve added some extra details and changed the icon. You might recognize it.

See the Pen 20. SitePoint Button by SitePoint (@SitePoint)on CodePen.

As always, thanks for reading. Wanna see more? Come find me on Twitter or check out the the live stream!

Jhey makes awesome things for awesome people! He’s a web developer with almost 10 years of experience. Working with and for names such as Eurostar, Uber, NearForm, Barclaycard, ATG, O2, and M&C Saatchi.

Jhey thrives on bringing ideas to life. He takes pride in crafting innovative solutions with polished user experiences. This whilst possessing a keen eye for design, accessibility, and well-structured code.

He’s a CodePen advocate and shares attention-catching demos over on Twitter. New books out now!Get practical advice to start your career in programming!Master complex transitions, transformations and animations in CSS! Latest Remote JobsDevOpsPingthings, Inc.kubernetesdocker

What Saul Bass Can Teach Us About Web Design

Web design exists at a lovely intersection of different disciplines. In previous articles, I’ve written about the lessons to be learned from newspapers and from ancient Roman architects. This time we’ll be looking at one of the all-time great graphic designers — Saul Bass. Saul Bass is a graphic design legend. Responsible for title sequences…

My Client Made Me Do It: True Tales from the Grumpy Designer

Designers often like to critique other designers. It’s just a natural side effect of being creative. We see a website or app and immediately start looking at how it all fits together. What challenges might have our brethren faced along the way? Would we have done anything differently? Of course, no designer is perfect. We…