Developer News

Why CSS Needs its Own Survey

Css Tricks - Fri, 03/01/2019 - 6:45am

2016 was only three years ago, but that’s almost a whole other era in web development terms. The JavaScript landscape was in turmoil, with up-and-comer React — as well as a little-known framework called Vue — fighting to dethrone Angular.

Like many other developers, I felt lost. I needed some clarity, and I figured the best way to get it was simply to ask fellow coders what they used, and more importantly, what they enjoyed using. The result was the first ever edition of the now annual State of JavaScript survey.

The State of JavaScript 2018

Things have stabilized in the JavaScript world since then. Turns out you can’t really go wrong with any one of the big three frameworks, and even less mainstream options, like Ember, have managed to build up passionate communities and show no sign of going anywhere.

But while all our attention was fixated on JavaScript, trouble was brewing in CSS land. For years, my impression of CSS’s evolution was slow, incremental progress. Back then, I was pretty sure border-radius support represented the crowning, final achievement of web browser technology.

But all of a sudden, things started picking up. Flexbox came out, representing the first new and widely adopted layout method in over a decade. And Grid came shortly after that, sweeping away years of hacky grid frameworks into the gutter of bad CSS practices.

Something even crazier happened: now that the JavaScript people had stopped creating a new framework every two weeks, they decided to use all their extra free time trying to make CSS even better! And thus CSS-in-JS was born.

And now it’s 2019, and the Flexbox Cheatsheet tab I’ve kept open for the past two years has now been joined by a Grid Cheatsheet, because no matter how many times I use them, I still need to double-check the syntax. And despite writing a popular introduction to CSS-in-JS, I still lazily default to familiar Sass for new projects, promising myself that I’ll "do things properly" the next time.

All this to say that I feel just as lost and confused about CSS in 2019 as I did about JavaScript in 2016. It’s high time CSS got a survey of its own.

Starting from scratch

Coming up with the idea for a CSS survey was easy, but deciding on the questions themselves was far from straightforward. Like I said, I didn’t feel confident in my own CSS knowledge, and simply asking about Sass vs. Less for the 37th time felt like a missed opportunity…

Thankfully, the CSS Gods decided to smile down upon me: while attending the DotJS conference in France I discovered that, not only did fellow speaker Florian Rivoal live in Kyoto, Japan, just like me; but that he was a member of the CSS Working Group! In other words, one of the people who knows the most about CSS on the planet was living a few train stops away from me!

Florian was a huge help in coming up with the overall structure and content of the survey. And he also helped me realize how little I really knew about CSS.

Kyoto, Japan: a hotbed of CSS activity (Photo by Jisu Han) You don’t know CSS

I’m not only talking about obscure CSS properties here, or even new up-and-coming ones, but about how CSS itself is developed. For example, did you know that the development of the CSS Grid spec was sponsored by Bloomberg, because they needed a way to port the layout of their famous terminal to the web?

Did you ever stop to wonder what top: 30px is supposed to mean on a circular screen, such as the one on a smartwatch? Or did you know that some people are laying out entire printed books in CSS, effectively replacing software like InDesign?

Talking with Florian really expanded my mind to how broad and interesting CSS truly is, and convinced me doing the survey was worth it.

"What do you mean, ‘Make the <table> circular’?" Photo by Artur ?uczka About that divide...

The idea of a CSS survey became all the more important as my new-found admiration for CSS seemed to coincide with a general sentiment that HTML and CSS mastery were becoming under-appreciated skills in the face of JavaScript hegemony.

Myself, personally, I’ve always enjoyed being a generalist in the sense that I happily hop from one side of the great divide to another whenever I feel like it. At the same time, I’m also wholly convinced that the world needs specialists like Florian; people who dedicate their lives to championing and improving a single aspect of the web.

Devaluing the work the work of generalists is not only unfair, but it’s also counter-productive — after all, HTML and CSS are the foundation on which all modern JavaScript frameworks are built; and on the other hand, new patterns and approaches pioneered by CSS-in-JS libraries will hopefully find their way back into vanilla CSS sooner or later.

Thankfully, I feel like a minority of developers hold those views, and those who do generally hold them do so out of ignorance for what the "other side" really stands for more than any well-informed opinion.

So that’s where the survey comes in: I’m not saying I can fill up the divide, but maybe I can throw a couple walkways across, or distribute some jetpacks — you know, whatever works. &#x1f680;

If that sounds good, then the first step is — you guessed it — taking the survey!

Take Survey

The post Why CSS Needs its Own Survey appeared first on CSS-Tricks.

Recreating the Facebook Messenger Gradient Effect with CSS

Css Tricks - Fri, 03/01/2019 - 6:01am

One Sunday morning, I woke up a little earlier than I would’ve liked to, thanks to the persistent buzzing of my phone. I reached out, tapped into Facebook Messenger, and joined the conversation. Pretty soon my attention went from the actual conversations to the funky gradient effect of the message bubbles containing them. Let me show you what I mean:

This is a new feature of Messenger, which allows you to choose a gradient instead of a plain color for the background of the chat messages. It’s currently available on the mobile application as well as Facebook’s site, but not yet on Messenger’s site. The gradient appears “fixed" so that chat bubbles appear to change background color as they scroll vertically.

I thought this looked like something that could be done in CSS, so… challenge accepted!

Let’s walk through my thought process as I attempted to recreate it and explain the CSS features that were used to make it work. Also, we’ll see how Facebook actually implemented it (spoiler alert: not the way I did) and how the two approaches compare.

Getting our hands dirty

First, let’s look at the example again to see what exactly it is that we’re trying to achieve here.

In general, we have a pretty standard messaging layout: messages are divided into bubbles going from top to bottom, ours on the right and the other people in the chat on the left. The ones on the left all have a gray background color, but the ones on the right look like they’re sharing the same fixed background gradient. That’s pretty much it!

Step 1: Set up the layout

This part is pretty simple: let’s arrange the messages in an ordered list and apply some basic CSS to make it look more like an actual messaging application:

<ol class="messages"> <li class="ours">Hi, babe!</li> <li class="ours">I have something for you.</li> <li>What is it?</li> <li class="ours">Just a little something.</li> <li>Johnny, it’s beautiful. Thank you. Can I try it on now?</li> <li class="ours">Sure, it’s yours.</li> <li>Wait right here.</li> <li>I’ll try it on right now.</li> </ol>

When it comes to dividing the messages to the left and the right, my knee-jerk reaction was to use floats. We could use float: left for messages on the left and float: right for messages on the right to have them stick to different edges. Then, we’d apply clear: both to on each message so they stack. But there’s a much more modern approach — flexbox!

We can use flexbox to stack the list items vertically with flex-direction: column and tell all the children to stick to the left edge (or “align the cross-start margin edges of the flex children with cross-start margin edges of the lines," if you prefer the technical terms) with align-items: flex-start. Then, we can overwrite the align-items value for individual flex items by setting align-self: flex-end on them.

What, you mean you couldn’t visualize the code based on that? Fine, here’s how that looks:

.messages { /* Flexbox-specific styles */ display: flex; flex-direction: column; align-items: flex-start; /* General styling */ font: 16px/1.3 sans-serif; height: 300px; list-style-type: none; margin: 0 auto; padding: 8px; overflow: auto; width: 200px; } /* Default styles for chat bubbles */ .messages li { background: #eee; border-radius: 8px; padding: 8px; margin: 2px 8px 2px 0; } /* Styles specific to our chat bubbles */ .messages li.ours { align-self: flex-end; /* Stick to the right side, please! */ margin: 2px 0 2px 8px; }

Some padding and colors here and there and this already looks similar enough to move on to the fun part.

Step 2: Let’s color things in!

The initial idea for the gradient actually came to me from this tweet by Matthias Ott (that Chris recreated in another post):

This is a nasty hack with a pseudo-element on top of the text and mix-blend-mode doesn't work in IE / Edge, but: Yes, this is possible to do with CSS! &#x1f605;https://t.co/FLKGvd1YoI

— Matthias Ott (@m_ott) December 3, 2018

The key clue here is mix-blend-mode, which is a CSS property that allows us to control how the content of an element blends in with what’s behind it. It’s a feature that has been present in Photoshop and other similar tools for a while, but is fairly new to the web. There’s an almanac entry for the property that explains all of its many possible values.

One of the values is screen: it takes the values of the pixels of the background and foreground, inverts them, multiplies them, and inverts them once more. This results in a color that is brighter than the original background color.

The description can seem a little confusing, but what it essentially means is that if the background is monochrome, wherever the background is black, the foreground pixels are shown fully and wherever it is white, white remains.

With mix-blend-mode: screen; on the foreground, we'll see more of the foreground as the background is darker.

So, for our purposes, the background will be the chat window itself and the foreground will contain an element with the desired gradient set as the background that’s positioned over the background. Then, we apply the appropriate blend mode to the foreground element and restyle the background. We want the background to be black in places where we want the gradient to be shown and white in other places, so we’ll style the bubbles by giving them a plain black background and white text. Oh, and let’s remember to add pointer-events: none to the foreground element so the user can interact with the underlying text.

At this point, I also changed the original HTML a little. The entire chat is a wrapper in an additional container that allows the gradient to stay “fixed" over the scrollable part of the chat:

.messages-container:after { content: ''; background: linear-gradient(rgb(255, 143, 178) 0%, rgb(167, 151, 255) 50%, rgb(0, 229, 255) 100%); position: absolute; left: 0; top: 0; height: 100%; width: 100%; mix-blend-mode: screen; pointer-events: none; } .messages li { background: black; color: white; /* rest of styles */ }

The result looks something like this:

The gradient applied to the chat bubbles Step 3: Exclude some messages from the gradient

Now the gradient is being shown where the text bubbles are under it! However, we only want it to be shown over our bubbles — the ones along the right edge. A hint to how that can be achieved is hidden in MDN’s description of the mix-blend-mode property:

The mix-blend-mode CSS property sets how an element's content should blend with the content of the element's parent and the element's background.

That’s right! The background. Of course, the effect only takes into account the HTML elements that are behind the current element and have a lower stack order. Fortunately, the stacking order of elements can easily be changed with the z-index property. So all we have to do is to give the chat bubbles on the left a higher z-index than that of the foreground element and they will be raised above it, outside of the influence of mix-blend-mode! Then we can style them however we want.

The gradient applied to the chat bubbles. Let’s talk browser support

At the time of writing, mix-blend-mode is not supported at all in Internet Explorer and Edge. In those browsers, the gradient is laid over the whole chat and others’ bubbles appear on top of it, which is not an ideal solution.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari412932NoNoTPMobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox12.246No677164

So, this is what we get in unsupported browsers:

How browsers that don’t support mix-blend-mode render the chat.

Fortunately, all the browsers that support mix-blend-mode also support CSS Feature Queries. Using them allows us to write fallback styles for unsupported browsers first and include the fancy effects for the browsers that support them. This way, even if a user can’t see the full effect, they can still see the whole chat and interact with it:

A simplified UI for older browsers, falling back to a plain cyan background color.

Here’s the final Pen with the full effect and fallback styles:

See the Pen
Facebook Messenger-like gradient coloring in CSS
by Stepan Bolotnikov (@Stopa)
on CodePen.

Now let’s see how Facebook did it

Turns out that Facebook’s solution is almost the opposite of what we’ve covered here. Instead of laying the gradient over the chat and cutting holes in it, they apply the gradient as a fixed background image to the whole chat. The chat itself is filled with a whole bunch of empty elements with white backgrounds and borders, except where the gradient should be visible.

The final HTML rendered by the Facebook Messenger React app is pretty verbose and hard to navigate, so I recreated a minimal example to demonstrate it. A lot of the empty HTML elements can be switched for pseudo-elements instead:

See the Pen
Facebook Messenger-like gradient coloring in CSS: The Facebook Way
by Stepan Bolotnikov (@Stopa)
on CodePen.

As you can see, the end result looks similar to the mix-blend-mode solution, but with a little bit of extra markup. Additionally, their approach provides more flexibility for rich content, like images and emojis . The mix-blend-mode approach doesn’t really work if the background is anything but monochrome and I haven’t been able to come up with a way to “raise" inner content above the gradient or get around this limitation in another way.

Because of this limitation, it’s wiser to use Facebook’s approach in an actual chat application. Still, our solution using mix-blend-mode showcases an interesting way to use one of the most under-appreciated CSS properties in modern web design and hopefully it has given you some ideas on what you could do with it!

The post Recreating the Facebook Messenger Gradient Effect with CSS appeared first on CSS-Tricks.

I Spun up a Scalable WordPress Server Environment with Trellis, and You Can, Too

Css Tricks - Thu, 02/28/2019 - 5:21am

A few years back, my fledgling website design agency was starting to take shape; however, we had one problem: managing clients' web servers and code deployments. We were unable to build a streamlined process of provisioning servers and maintaining operating system security patches. We had the development cycle down pat, but server management became the bane of our work. We also needed tight control over each server depending on a site’s specific needs. Also, no, shared hosting was not the long term solution.

I began looking for a prebuilt solution that could solve this problem but came up with no particular success. At first, I manually provisioned servers. This process quickly proved to be both monotonous and prone to errors. I eventually learned Ansible and created a homegrown conglomeration of custom Ansible roles, bash scripts and Ansible Galaxy roles that further simplified the process — but, again, there were still many manual steps needed to take before the server was 100%.

I’m not a server guy (nor do I pretend to be one), and at this point, it became apparent that going down this path was not going to end well in the long run. I was taking on new clients and needed a solution, or else I would risk our ability to be sustainable, let alone grow. I was spending gobs of time typing arbitrary sudo apt-get update commands into a shell when I should have been managing clients or writing code. That's not to mention I was also handling ongoing security updates for the underlying operating system and its applications.

Tell me if any of this sounds familiar.

Serendipitously, at this time, the team at Roots had released Trellis for server provisioning; after testing it out, things seemed to fall into place. A bonus is that Trellis also handles complex code deployments, which turned out to be something else I needed as most of the client sites and web applications that we built have a relatively sophisticated build process for WordPress using Composer, npm, webpack, and more. Better yet, it takes just minutes to jumpstart a new project. After spending hundreds of hours perfecting my provisioning process with Trellis, I hope to pass what I’ve learned onto you and save you all the hours of research, trials, and manual work that I wound up spending.

A note about Bedrock

We're going to assume that your WordPress project is using Bedrock as its foundation. Bedrock is maintained by the same folks who maintain Trellis and is a "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure." This post does not explicitly explain how to manage Bedrock, but it is pretty simple to set up, which you can read about in its documentation. Trellis is natively designed to deploy Bedrock projects.

A note about what should go into the repo of a WordPress site

One thing that this entire project has taught me is that WordPress applications are typically just the theme (or the child theme in the parent/child theme relationship). Everything else, including plugins, libraries, parent themes and even WordPress itself are just dependencies. That means that our version control systems should typically include the theme alone and that we can use Composer to manage all of the dependencies. In short, any code that is managed elsewhere should never be versioned. We should have a way for Composer to pull it in during the deployment process. Trellis gives us a simple and straightforward way to accomplish this.

Getting started

Here are some things I’m assuming going forward:

  • The code for the new site in the directory ~/Sites/newsite
  • The staging URL is going to be https://newsite.statenweb.com
  • The production URL is going to be https://newsite.com
  • Bedrock serves as the foundation for your WordPress application
  • Git is used for version control and GitHub is used for storing code. The repository for the site is: git@github.com:statenweb/newsite.git

I am a little old school in my local development environment, so I’m foregoing Vagrant for local development in favor of MAMP. We won’t go over setting up the local environment in this article.

I set up a quick start bash script for MacOS to automate this even further.

The two main projects we are going to need are Trellis and Bedrock. If you haven't done so already, create a directory for the site (mkdir ~/Sites/newsite) and clone both projects from there. I clone Trellis into a /trellis directory and Bedrock into the /site directory:

cd ~/Sites/newsite git clone git@github.com:roots/trellis.git git clone git@github.com:roots/bedrock.git site cd trellis rm -rf .git cd ../site rm -rf .git

The last four lines enable us to version everything correctly. When you version your project, the repo should contain everything in ~/Sites/newsite.

Now, go into trellis and make the following changes:

First, open ~/Sites/newsite/trellis/ansible.cfg and add these lines to the bottom of the [defaults] key:

vault_password_file = .vault_pass host_key_checking = False

The first line allows us to use a .vault_pass file to encrypt all of our vault.yml files which are going to store our passwords, sensitive data, and salts.

The second host_key_checking = False can be omitted for security as it could be considered somewhat dangerous. That said, it’s still helpful in that we do not have to manage host key checking (i.e., typing yes when prompted).

Ansible vault password Photo by Micah Williams on Unsplash

Next, let’s create the file ~/Sites/newsite/trellis/.vault_pass and enter a random hash of 64 characters in it. We can use a hash generator to create that (see here for example). This file is explicitly ignored in the default .gitignore, so it will (or should!) not make it up to the source control. I save this password somewhere extremely secure. Be sure to run chmod 600 .vault_pass to restrict access to this file.

The reason we do this is so we can store encrypted passwords in the version control system and not have to worry about exposing any of the server's secrets. The main thing to call out is that the .vault_pass file is (and should not be) not committed to the repo and that the vault.yml file is properly encrypted; more on this in the “Encrypting the Secret Variables" section below.

Setting up target hosts Photo by N. on Unsplash

Next, we need to set up our target hosts. The target host is the web address where Trellis will deploy our code. For this tutorial, we are going to be configuring newsite.com as our production target host and newsite.statenweb.com as our staging target host. To do this, let’s first update the production servers address in the production host file, stored in ~/Sites/newsite/trellis/hosts/production to:

[production] newsite.com [web] newsite.com

Next, we can update the staging server address in the staging host file, which is stored in ~/Sites/newsite/trellis/hosts/staging to:

[staging] newsite.statenweb.com [web] newsite.statenweb.com Setting up GitHub SSH Keys

For deployments to be successful, SSH keys need to be working. Trellis takes advantage of how GitHub' exposes all public (SSH) keys so that you do not need to add keys manually. To set this up go into the group_vars/all/users.yml and update both the web_user and the admin_user object's keys value to include your GitHub username. For example:

users: - name: '{{ web_user }}' groups: - '{{ web_group }}' keys: - https://github.com/matgargano.keys - name: '{{ admin_user }}' groups: - sudo keys: - https://github.com/matgargano.keys

Of course, all of this assumes that you have a GitHub account with all of your necessary public keys associated with it.

Site Meta

We store essential site information in:

  • ~/Sites/newsite/trellis/group_vars/production/wordpress_sites.yml for production
  • ~/Sites/newsite/trellis/group_vars/staging/wordpress_sites.yml for staging.

Let's update the following information for our staging wordpress_sites.yml:

wordpress_sites: newsite.statenweb.com: site_hosts: - canonical: newsite.statenweb.com local_path: ../site repo: git@github.com:statenweb/newsite.git repo_subtree_path: site branch: staging multisite: enabled: false ssl: enabled: true provider: letsencrypt cache: enabled: false

This file is saying that we:

  • removed the site hosts redirects as they are not needed for staging
  • set the canonical site URL (newsite.statenweb.com) for the site key (newsite.statenweb.com)
  • defined the URL for the repository
  • the git repo branch that gets deployed to this target is staging, i.e., we are using a separate branch named staging for our staging site
  • enabled SSL (set to true), which will also install an SSL certificate when the box provisions

Let's update the following information for our production wordpress_sites.yml:

wordpress_sites: newsite.com: site_hosts: - canonical: newsite.com redirects: - www.newsite.com local_path: ../site # path targeting local Bedrock site directory (relative to Ansible root) repo: git@github.com:statenweb/newsite.git repo_subtree_path: site branch: master multisite: enabled: false ssl: enabled: true provider: letsencrypt cache: enabled: false

Again, what this translates to is that we:

  • set the canonical site URL (newsite.com) for the site key (newsite.com)
  • set a redirect for www.newsite.com
  • defined the URL for the repository
  • the git repo branch that gets deployed to this target is master, i.e., we are using a separate branch named master for our production site
  • enabled SSL (set to true), which will install an SSL certificate when you provision the box

In the wordpress_sites.yml you can further configure your server with caching, which is beyond the scope of this guide. See Trellis' documentation on FastCGI Caching for more information.

Secret Variables Photo by Kristina Flour on Unsplash

There are going to be several secret pieces of information for both our staging and production site including the root user password, MySQL root password, site salts, and more. As referenced previously, Ansible Vault and using .vault_pass file makes this a breeze.

We store this secret site information in:

  • ~/Sites/newsite/trellis/group_vars/production/vault.yml for production
  • ~/Sites/newsite/trellis/group_vars/staging/vault.yml for staging

Let's update the following information for our staging vault.yml:

vault_mysql_root_password: pK3ygadfPHcLCAVHWMX vault_users: - name: "{{ admin_user }}" password: QvtZ7tdasdfzUmJxWr8DCs salt: "heFijJasdfQbN8bA3A" vault_wordpress_sites: newsite.statenweb.com: env: auth_key: "Ab$YTlX%:Qt8ij/99LUadfl1:U]m0ds@N<3@x0LHawBsO$(gdrJQm]@alkr@/sUo.O" secure_auth_key: "+>Pbsd:|aiadf50;1Gz;.Z{nt%Qvx.5m0]4n:L:h9AaexLR{1B6.HeMH[w4$>H_" logged_in_key: "c3]7HixBkSC%}-fadsfK0yq{HF)D#1S@Rsa`i5aW^jW+W`8`e=&PABU(s&JH5oPE" nonce_key: "5$vig.yGqWl3G-.^yXD5.ddf/BsHx|i]>h=mSy;99ex*Saj<@lh;3)85D;#|RC=" auth_salt: "Wv)[t.xcPsA}&/]rhxldafM;h(FSmvR]+D9gN9c6{*hFiZ{]{,#b%4Um.QzAW+aLz" secure_auth_salt: "e4dz}_x)DDg(si/8Ye&U.p@pB}NzHdfQccJSAh;?W)>JZ=8:,i?;j$bwSG)L!JIG" logged_in_salt: "DET>c?m1uMAt%hj3`8%_emsz}EDM7R@44c0HpAK(pSnRuzJ*WTQzWnCFTcp;,:44" nonce_salt: "oHB]MD%RBla*#x>[UhoE{hm{7j#0MaRA#fdQcdfKe]Y#M0kQ0F/0xe{cb|g,h.-m"

Now, let's update the following information for our production vault.yml:

vault_mysql_root_password: nzUMN4zBoMZXJDJis3WC vault_users: - name: "{{ admin_user }}" password: tFxea6ULFM8CBejagwiU salt: "9LgzE8phVmNdrdtMDdvR" vault_wordpress_sites: newsite.com: env: db_password: eFKYefM4hafxCFy3cash # Generate your keys here: https://roots.io/salts.html auth_key: "|4xA-:Pa=-rT]&!-(%*uKAcd</+m>ix_Uv,`/(7dk1+;b|ql]42gh&HPFdDZ@&of" secure_auth_key: "171KFFX1ztl+1I/P$bJrxi*s;}.>S:{^-=@*2LN9UfalAFX2Nx1/Q&i&LIrI(BQ[" logged_in_key: "5)F+gFFe}}0;2G:k/S>CI2M*rjCD-mFX?Pw!1o.@>;?85JGu}#(0#)^l}&/W;K&D" nonce_key: "5/[Zf[yXFFgsc#`4r[kGgduxVfbn::<+F<$jw!WX,lAi41#D-Dsaho@PVUe=8@iH" auth_salt: "388p$c=GFFq&hw6zj+T(rJro|V@S2To&dD|Q9J`wqdWM&j8.KN]y?WZZj$T-PTBa" secure_auth_salt: "%Rp09[iM0.n[ozB(t;0vk55QDFuMp1-=+F=f%/Xv&7`_oPur1ma%TytFFy[RTI,j" logged_in_salt: "dOcGR-m:%4NpEeSj>?A8%x50(d0=[cvV!2x`.vB|^#G!_D-4Q>.+1K!6FFw8Da7G" nonce_salt: "rRIHVyNKD{LQb$uOhZLhz5QX}P)QUUo!Yw]+@!u7WB:INFFYI|Ta5@G,j(-]F.@4"

The essential lines for both are that:

  • The site key must match the key in wordpress_sites.yml we are using newsite.statenweb.com: for staging and newsite.com: for production
  • I randomly generated vault_mysql_root_password, password, salt, db_password, and db_password. I used Roots' helper to generate the salts.

I typically use Gmail's SMTP servers using the Post SMTP plugin, so there’s no need for me to edit the ~/Sites/newsite/group_vars/all/vault.yml.

Encrypting the Secret Variables Photo by Markus Spiske on Unsplash

As previously mentioned we use Ansible Vault to encrypt our vault.yml files. Here’s how to encrypt the files and make them ready to be stored in our version control system:

cd ~/Sites/newsite/trellis ansible-vault encrypt group_vars/staging/vault.yml group_vars/production/vault.yml

Now, if we open either ~/Sites/newsite/trellis/group_vars/staging/vault.yml or ~/Sites/newsite/trellis/group_vars/production/vault.yml, all we’ll get is garbled text. This is safe to be stored in a repository as the only way to decrypt it is to use the .vault_pass. It goes without saying to make extra sure that the .vault_pass itself does not get committed to the repository.

A note about compiling, transpiling, etc.

Another thing that’s out of scope is setting up Trellis deployments to handle a build process using build tools such as npm and webpack. This is example code to handle a custom build that could be included in ~/Sites/newsite/trellis/deploy-hooks/build-before.yml:

--- - args: chdir: "{{ project.local_path }}/web/app/themes/newsite" command: "npm install" connection: local name: "Run npm install" - args: chdir: "{{ project.local_path }}/web/app/themes/newsite" command: "npm run build" connection: local name: "Compile assets for production" - name: "Copy Assets" synchronize: dest: "{{ deploy_helper.new_release_path }}/web/app/themes/newsite/dist/" group: no owner: no rsync_opts: "--chmod=Du=rwx,--chmod=Dg=rx,--chmod=Do=rx,--chmod=Fu=rw,--chmod=Fg=r,--chmod=Fo=r" src: "{{ project.local_path }}/web/app/themes/newsite/dist/"

These are instructions that build assets and moves them into a directory that I explicitly decided not to version. I hope to write a follow-up guide that dives specifically into that.

Provision Photo by Bill Jelen on Unsplash

I am not going to go in great detail about setting up the servers themselves, but I typically would go into DigitalOcean and spin up a new droplet. As of this writing, Trellis is written on Ubuntu 18.04 LTS (Bionic Beaver) which acts as the production server. In that droplet, I would add a public key that is also included in my GitHub account. For simplicity, I can use the same server as my staging server. This scenario is likely not what you would be using; maybe you use a single server for all of your staging sites. If that is the case, then you may want to pay attention to the passwords configured in ~/Sites/newsite/trellis/group_vars/staging/vault.yml.

At the DNS level, I would map the naked A record for newsite.com to the IP address of the newly created droplet. Then I’d map the CNAME www to @. Additionally, the A record for newsite.statenweb.com would be mapped to the IP address of the droplet (or, alternately, a CNAME record could be created for newsite.statenweb.com to newsite.com since they are both on the same box in this example).

After the DNS propagates, which can take some time, the staging box can be provisioned by running the following commands.

First off, it;’s possible you may need to run this before anything else:

ansible-galaxy install -r requirements.yml

Then, install the required Ansible Galaxy roles before proceeding:

cd ~/Sites/newsite/trellis ansible-playbook server.yml -e env=staging

Next up, provision the production box:

cd ~/Sites/newsite/trellis ansible-playbook server.yml -e env=production Deploy

If all is set up correctly to deploy to staging, we can run these commands:

cd ~/Sites/newsite/trellis ansible-playbook deploy.yml -e "site=newsite.statenweb.com env=staging" -i hosts/staging

And, once this is complete, hit https://newsite.statenweb.com. That should bring up the WordPress installation prompt that provides the next steps to complete the site setup.

If staging is good to go, then we can issue the following commands to deploy to production:

cd ~/Sites/newsite/trellis ansible-playbook deploy.yml -e "site=newsite.com env=production" -i hosts/production

And, like staging, this should also prompt installation steps to complete when hitting https://newsite.com.

Go forth and deploy!

Hopefully, this gives you an answer to a question I had to wrestle with personally and saves you a ton of time and headache in the process. Having stable, secure and scalable server environments that take relatively little effort to spin up has made a world of difference in the way our team works and how we’re able to accommodate our clients’ needs.

While we’re technically done at this point, there are still further steps to take to wrap up your environment fully:

  • Add dependencies like plugins, libraries and parent themes to ~/Sites/newsite/composer.json and run composer update to grab the latest manifest versions.
  • Place the theme to ~/Sites/newsite/site/themes/. (Note that any WordPress theme can be used.)
  • Include any build processes you’d need (e.g. transpiling ES6, compiling SCSS, etc.) in one of the deployment hooks. (See the documentation for Trellis Hooks).

I have also been able to dive into enterprise-level continuous integration and continuous delivery, as well as how to handle premium plugins with Composer by running a custom Composer server, among other things, while incurring no additional cost. Hopefully, those are areas I can touch on in future posts.

Trellis provides a dead simple way to provision WordPress servers. Thanks to Trellis, long gone are the days of manually creating, patching and maintaining servers!

The post I Spun up a Scalable WordPress Server Environment with Trellis, and You Can, Too appeared first on CSS-Tricks.

Keen makes it a breeze to build and ship customer-facing metrics

Css Tricks - Thu, 02/28/2019 - 5:12am

(This is a sponsored post.)

Keen is an analytics tool that makes it wonderfully easy to collect data. But Keen is unique in that it is designed not just to help you look at that data, but to share that data with your own customers! Customer-facing metrics, as it were.

Keen works just the way you would hope: it's super easy to install, has great docs, makes it very easy to customize to collect exactly what you need, and crucially, it is just as easy to query it and get the data you want to build the visualizations you need. As I'm sure you well know: you only improve what you measure, and what you measure is unique to your business and your customers.

Doesn't it tickle your brain a little? What kind of metrics might your customers want to see in relation to your app? What kind of features might they pay for?

The idea of Customer-Facing Metrics is that you can deliver personalized data to your user right through the front-end of the app. It could be the fundamental offering of your app! Or it could be a bonus paid feature, a lot of people love looking at their numbers! Imagine a social platform where users are able to see their most popular content, check the sources of the traffic, and explore all that through time and other filters.

Customer facing data, powered by Keen

Have you ever seen an incredible data visualization and imagined how that could be useful in your own app? You can probably follow a tutorial to help you build the visual part, but those tutorials generally assume you already have the data and skip over that part. Keen helps you with the hard part: collecting, storing, and querying all that data. Not to mention scales as you do.

Charts from Quartz, powered by Keen

Part of the beauty of Keen is how easy it is to get started. It works in whatever stack you've got in any language. Just a few lines of code to get up and running and get a proof of concept going.

In fact, if you're using Keen for the web, you might be interested in the Auto-Collector, which means you don't have to configure and send events manually, it will collect all pageviews, clicks, and form submissions automatically. That's particularly nice as you can answer questions you might have instantly, because you've already collected the information, you don't need to configure new collections and then wait. This is particularly great to help you get a proof-of-concept up very quickly and start figuring out things that your customers are sure to be interested in.

Auto-Collector Dashboard

Start prototyping today with Auto-Collector:

Sign up for Keen

Direct Link to ArticlePermalink

The post Keen makes it a breeze to build and ship customer-facing metrics appeared first on CSS-Tricks.

A Bit of Performance

Css Tricks - Thu, 02/28/2019 - 5:12am

Here’s a great post by Roman Komarov on what he learned by improving the performance of his personal website. There’s a couple of neat things he does to tackle font loading in particular, such as adding the <link rel="preload"> tags for fonts. This will encourage those font files to download a tiny bit faster which prevents that odd flash of un-styled text we know all too well. Roman also subsets his font files based on language which I find super interesting – as only certain pages of his website use Cyrillic glyphs.

He writes:

I was digging into some of the performance issues during my work for a few weeks, and I thought that it can be interesting to see how those could be applied to my site. I was already quite happy with how it performed (being just a small static site) but managed to find a few areas to improve.

I had also never heard of Squoosh, which happens to be an incredible image optimization tool that looks like this when you’re editing an image:

With that slider in the middle, it shows the difference between the original image and the newly optimized one, which is both super neat and helpful.

Direct Link to ArticlePermalink

The post A Bit of Performance appeared first on CSS-Tricks.

WorldWideWeb

Css Tricks - Wed, 02/27/2019 - 10:12am

For the 30th anniversary of the web, CERN brought nine web nerds together to recreate the very first web browser — Or a working replication of it anyway, as you use it from your web browser, inception style.

Well done, Mark Boulton, John Allsopp, Kimberly Blessing, Jeremy Keith, Remy Sharp, Craig Mod, Martin Akolo Chiteri, Angela Ricci, and Brian Suda! I love that it was written in React and the font is an actual replication of what was used back then. What a cool project.

They even opened-sourced the code.

You can visit any site with Document > Open from full document reference:

CSS-Tricks ain't too awful terrible, considering the strictness:

When this source code was written, there was no version number associated with HTML. Based on the source code, the following tags—the term 'element' was not yet used—were recognized:

  • ADDRESS
  • A
  • DL, DT, DD
  • H1, H2, H3, H4, H5, H6
  • HP1, HP2, HP3
  • ISINDEX
  • LI
  • LISTING
  • NEXTID
  • NODE
  • OL
  • PLAINTEXT
  • PRE
  • RESTOFFILE
  • TITLE
  • UL
  • XMP

Unrecognized tags were considered junk and ignored.

Direct Link to ArticlePermalink

The post WorldWideWeb appeared first on CSS-Tricks.

Did you know that CSS Custom Properties can handle images too?

Css Tricks - Wed, 02/27/2019 - 10:04am

So you might be aware of CSS Custom Properties that let you set a variable, such as a theme color, and then apply it to multiple classes like this:

:root { --theme: #777; } .alert { background: var(—-theme); } .button { background: var(—-theme); }

Well, I had seen this pattern so often that I thought Custom Properties could only be used for color values like rgba or hex – although that’s certainly not the case! After a little bit of experimentation and sleuthing around, I realized that it’s possible to use Custom Properties to set image paths, too.

Here’s an example of that in action:

:root { --errorIcon: url(error.svg) } .alert { background-image: var(--errorIcon); } .form-error { background-image: var(--errorIcon); }

Kinda neat, huh? I think this could be used to make an icon system where you could define a whole list of images in the :root and call it whenever you needed to. Or you could make it easier to theme certain classes based on their state or perhaps in a media query, as well. Remember, too, that custom properties can be overridden within an element:

:root { --alertIcon: url(alert-icon.svg) } .alert { background-image: var(--alertIcon); } .form-error { --alertIcon: url(alert-icon-error.svg) background-image: var(--alertIcon); }

And, considering that custom properties are selectable in JavaScript, think about the possibilities of swapping out images as well. I reckon this might useful to know!

The post Did you know that CSS Custom Properties can handle images too? appeared first on CSS-Tricks.

Text Wrapping & Inline Pseudo Elements

Css Tricks - Wed, 02/27/2019 - 9:34am

I love posts like this. It's just about adding a little icon to the end of certain links, but it ends up touching on a million things along the way. I think this is an example of why some people find front-end fun and some people rather dislike it.

Things involved:

  1. Cool [attribute] selectors that identify off-site links
  2. Deliberating on whether it's OK to use additional HTML within links or not
  3. Usage of white-space
  4. Combining margin-left and padding-right to place icons into placeholder space
  5. Using custom properties to keep things easier
  6. Usage of inline SVG versus background SVG
  7. Considering inline versus inline-block
  8. Using masks

Direct Link to ArticlePermalink

The post Text Wrapping & Inline Pseudo Elements appeared first on CSS-Tricks.

Control Icons with Font Size

Css Tricks - Wed, 02/27/2019 - 9:33am

Here’s a nifty trick from Andy Bell that now seems a little obvious in hindsight: if you set an SVG to have a width and height of 1em then you can change the size of it with the font-size property.

Try and change the font-size on the body element below to see the icon scale with the text:

See the Pen
Font size controlled icon
by Andy Bell (@andybelldesign)
on CodePen.

You pretty much always want your icons to be aligned with text so this trick helps by creating that inherent relationship in your code. Pretty nifty, eh?

Direct Link to ArticlePermalink

The post Control Icons with Font Size appeared first on CSS-Tricks.

Six tips for better web typography

Css Tricks - Wed, 02/27/2019 - 5:35am

How do we avoid the most common mistakes when it comes to setting type on the web? That’s the question that’s been stuck in my head lately as I’ve noticed a lot of typography that’s lackluster, frustrating, and difficult to read. So, how can we improve interfaces so that our content is easy to read at all times and contexts? How do learn from everyone else’s mistakes, too?

These questions encouraged me to jot down some rules that are easy to apply and have the greatest impact on legibility, based on my own personal experience. And, if you didn't know, I'm kinda a geek when it comes to typography. So, I thought I'd share the following six rules that I've come to adopt to get us started.

Rule #1: Set a good max-width for paragraphs

This is typically referred to as the measure in typographic circles and highly esteemed typographers will recommend that a paragraph have a width of around 75 characters for legibility reasons. Anything longer than that becomes difficult to read and causes unnecessary strain on the eyes because of the distance the eye has to travel left-to-right and back again (assuming ltr that is).

Here’s a quick example of a good max-width setting for a paragraph. Oh, and make sure to check out this demo on larger screen devices.

See the Pen
Typography Example 1
by Robin Rendle (@robinrendle)
on CodePen.

Now, this all depends on a ton of factors that great designers contemplate when setting a paragraph. However, as web designers, the difficulty for us is that we have to make sure that paragraphs feel good in additional contexts, like on mobile devices, too. So, while this rule of ~75 characters is nice to have in our back pocket, it's most helpful when we’re trying to figure out the maximum width of our text block. More on this in a bit.

Also, I’d recommend setting that width on a container or grid class that wraps the paragraph instead of setting a max-width value on the paragraph element itself.

Kind of like this:

<div class="container"> <p>This is where our text goes.</p> </div> p { font-size: 18px; line-height: 24px; } .container { max-width: 600px; }

Otherwise, there may be moments in the future when there's a need for certain paragraphs to be bigger and have a wider measure (like for introductory paragraphs perhaps). In those situations, making a different container class that just handles the larger width of the elements inside them is a nice and modular approach.

I’ve found that by having a system of classes that just deals with the width of things encourages writing much less code but also much more legible code as well. Although, yes, there is more HTML to write but I’d say that’s preferable to a lot of whacky CSS that has to be refactored in the future.

In short: make sure to set a good max-width for our paragraphs but also ensure that we set the widths on a parent class to keep our code readable.

Rule #2: Make the line height smaller than you think

One problem I often see in the wild is with paragraphs that have a line height that’s just way too big. This makes reading long blocks of text pretty exhausting and cumbersome as each hop from one line to the next feels like an enormous jump.

On mobile devices this is particularly egregious as I tend to see something like this often:

For some reason, a lot of folks tend to think that paragraphs on smaller devices require a larger line-height value — but this isn’t the case! Because the width of paragraphs are smaller, line-height can be even smaller than you might on desktop displays. That’s because on smaller screens, and with smaller paragraphs, the reader’s eye has a much shorter distance to hop from the end of one line to the beginning of the next.

This demo certainly isn’t typographically perfect (there’s no such thing), but it’s much easier to read than the majority of websites I stumble across today. In this example, notice how the line-height is probably much smaller than you’re familiar with and see how it feels as you read it:

See the Pen
Typography Example 1
by Robin Rendle (@robinrendle)
on CodePen.

Rule #3: Make the margins small on mobile, too

Another common mistake I frequently see is the use of very large margins on either side of a paragraph of text, it's often on mobile devices that make for blocks of text that are difficult to read like this:

Just — yikes! How are we expected to read this?

Instead try using no more than 10-15px of margin on either side of the paragraph because we need to ensure that our paragraphs are as wide as possible on smaller devices.

I even see folks bump the font-size down on mobile to try and have a nice paragraph width but I’d highly recommend to avoid this as well. Think of the context, because mobile devices are often held in front of the user's face. There's no need to force the user to bring the device any closer to read a small block of text.

Most of the time, smaller margins are the better solve.

Rule #4: Make sure that the type isn’t too thin

This is perhaps my biggest complaint when it comes to typography on the web because so many websites use extraordinarily thin sans-serif typefaces for paragraph text. This makes reading difficult because it’s harder to see each stroke in a letter when they begin to fade away into the background due to the lack of contrast.

Here’s an example of using a typeface that’s too thin:

See the Pen
Typography Example – Thin
by Robin Rendle (@robinrendle)
on CodePen.

Try and read the text there. Do you notice yourself struggling to read it? Because we’re using the light weight of Open Sans in this example, letterforms start to break apart and fall to bits. More focus is required to read it. Legibility decreases and reading becomes much more annoying than it really has to be.

I recommend picking a regular weight for body text, then trying to read a long string of text with those settings. Thin fonts look cute and pretty at a glance, but reading it in a longer form will reveal the difficulties.

Rule #5: Use bold weights for headings

Clear hierarchy is vital for controlling the focus of the reader, especially in complex applications that show a ton of data. And although it used to be more common a couple of years ago, I still tend to see a lot folks use very thin weights or regular weights for headings on websites. Again, this isn’t necessarily a die-hard rule — it’s a suggestion. That said, how difficult is it to scan this headline:

See the Pen
Typography Example – Heading 1
by Robin Rendle (@robinrendle)
on CodePen.

It’s a little difficult to see in this example but it's easy to missing the headline altogether in a large application with lots of UI. I’ve often found that inexperienced typographers tend to create hierarchy with font-size whilst experienced typographers will lead with font-weight instead.

Here’s an example of something much easier to scan:

See the Pen
Typography Example – Heading 2
by Robin Rendle (@robinrendle)
on CodePen.

In this example, I’ve set the paragraph text to a dark gray and the heading to a color closer to black while applying a bold weight. It’s not a substantial change in the code but it’s an enormous improvement in terms of hierarchy.

Little improvement like this will quickly add up to a better experience overall when the user is asked to slog through a ton of text.

Rule #6: Don’t use Lorem Ipsum to typeset a page

I think this advice might be the most underrated and I rarely hear it raised in front-end, typography, or design groups. I’ve even noticed seasoned designers struggle to typeset a page because Lorem Ipsum is used for the placeholder content, which makes it impossible for to gauge whether a paragraph of text is easy to read or not.

Setting text in Lorem Ipsum makes good typesetting kind of impossible.

Instead, pick text that you really enjoy reading. Ideally, typesetting would be done with finalized content but that's often a luxury in front-end development. That's why I’d recommend picking text that sounds close to the voice and tone of the project if there's a lack of actual content.

Seriously though, this one change will have an enormous impact on legibility and hierarchy because it encourages reading the text instead of looking at it all aesthetically. I noticed a massive improvement in my own designs when I stopped using undecipherable Lorem Ipsum text and picked content from my favorite novels instead.

And that’s it! There sure are a lot of rules when it comes to typography and these are merely the ones I tend to see broken the most. What kind of typographic issues do you see on the web though? Let us know in the comments!

The post Six tips for better web typography appeared first on CSS-Tricks.

Typography for Developers

Css Tricks - Wed, 02/27/2019 - 5:28am

Taimur Abdaal leads design at Retool, a fast way to build internal tools. They're working on a new design system for their platform, to let anyone easily build beautiful custom apps. Typography will be a huge part of this and Taimur wrote this based on that experience.

You may have read the title for this post and thought, "Why on earth does a developer need to know anything about typography?" I mean, there’s already a lot on your plate and you’re making hundreds of decisions a day. Should you use React or Vue? npm or Yarn? ES6 or ES7? Sadly, this often leaves something like type as an afterthought. But, let’s remember that web design is 95% typography:

95% of the information on the web is written language. It is only logical to say that a web designer should get good training in the main discipline of shaping written information, in other words: Typography.

Even though we deal with content everyday — whether reading, writing, or designing it — typography can be daunting to delve into because it’s filled with jargon and subjectivity, and it’s uncommon to see it taught extensively at school.

This is intended as a practical guide for developers to learn web typography. We’ll cover a range of practical and useful topics, like how to choose and use custom fonts on the web, but more importantly, how to lay text out to create a pleasant user experience. We’ll go over the principles of typography and the CSS properties that control them, as well as handy tips to get good results, quickly.

What is typography?

First and foremost, typography is about usability. Type is the user interface for conveying information, and conveying information is what we’re here to do on the web. There are many levers we can pull to affect the usability of reading text, and only by being deliberate about these can we create a pleasant experience for our users.

After (and only after) usability, typography is about emotion. Do the letters complement your content, or contradict it? Do they amplify your brand’s personality, or dampen it? Applied to the same text, different type will make people feel different things. Being deliberate about typography lets us control these feelings.

Same text, different personalities. I’ll bet the first experience is much more expensive. Typefaces: Bodoni 72 (Top), Tsukushi A Round Gothic (Bottom)

Despite what many golden ratio enthusiasts might try to tell you, typography isn’t an exact science. Good guidelines will get you most of the way there, but you’ll need to apply a little intuition too. Luckily, you’ve been reading text your whole life — books, magazines, the Internet — so you have a lot more untapped intuition than you think!

What’s in a font?

Let’s start off by getting a handle on some basic terminology and how fonts are categorized.

Typeface vs. Font

This is how the two have traditionally been defined and distinguished from one another:

  • Typeface: The design of a collection of glyphs (e.g. letters, numbers, symbols)
  • Font: A specific size, weight, or style of a typeface (e.g. regular, bold, italic)

In essence, a typeface is like a song and a font is like its MP3 file. You’ll see both terms used in typography literature, so it’s worth knowing the distinction. "Font vs. Typeface" is also a bit of meme in the design community — you might see it crop up on Twitter, so it’ll help to be "in the know."

HOW 2 MAJOR IN GRAPHIC DESIGN:
- CHOOSE A FONT
- "ITS CALLED A TYPEFACE NOT A FONT"
- CHOOSE A GODDAMN TYPEFACE
- U MADE THE WRONG CHOICE

— Deena (@itsDeenasaur) November 2, 2014

I may have used font and typeface interchangeably in this story. Please send all complaints to usuck@whocares.tk. https://t.co/IuHHmlaNAT

— Tristin Hopper (@TristinHopper) January 14, 2019

But, more recently, you can essentially use both terms interchangeably and people will know what you mean.

How fonts are categorized

The broadest split is between serif and sans-serif typefaces. It’s likely you’ve come across these terms just by seeing some some typeface names floating around (like, ahem, Comic Sans).

A "serif" is a small stroke attached to the ends of letters, giving them a traditional feel. In fact, most books and newspapers are set in serif typefaces. On the contrary, sans-serif typefaces don’t have these extra strokes, giving them a smooth, modern feel.

Times (left) and Helvetica Neue (right)

Both serif and sans-serif have categories within them. For example, serif has sub-categories including didone, slab and old style.

Didot (left), Rockwell (center) and Hoefler Text (right)

As far as sans-serif goes, it includes humanist, geometric and grotesk as sub-categories.

Gill Sans (left), Futura (center) and Aktiv Grotesk (right)

Monospace fonts (yes, fonts) are a noteworthy category all its own. Each glyph (i.e. letter/number/symbol) in a monospace font has the same width (hence the mono spacing terminology), so it’s possible to arrange them into visual structures. You may be well familiar with monospace because we see it often when writing code, where it’s helpful to make brackets and indents line up visually. The code editor you have open right now is likely using monospace.

Monaco How to choose fonts and font pairings

This is subjective, and depends on what you’re trying to do. Each typeface has its own personality, so you’ll have to find one that aligns with your brand or the content it’s communicating. Typefaces have to be considered within the context that they’re being applied. Are we looking for formality? Maybe start with the serif family. Warm, fun and friendly? That might be a cue for sans-serif. Heck, there’s a time and a place even for Comic Sans… really! Just know that there is no hard science to choosing a font, and even the most trained of typographers are considering contextual cues to find the "right" one.

But fonts can be paired together in the same design. For example, some designs use one typeface for headings and another for body text. This is a good way to get a unique look, but it does take a fair bit of work to get it right. Like colors in a palette, some typefaces work well together while others clash. And even purposeful clashing can make sense, again, given the right context.

The only way to find out if two fonts are complementary is to see them together. Tools like FontPair and TypeConnection can help with this. If a font catches your eye when surfing the web, WhatFont is a great browser extension to help identify it. Another great resource is Typewolf which allows you to see examples of great web typography, including different font combinations in use:

Alice Lee (left), American Documentary (center) and Studio Stereo (right)

While there’s a lot of subjectivity in choosing fonts, there are some objective considerations.

Font weight as a consideration

Some font families have a wide range of font weights — Light, Book, Regular, Medium, Semi-Bold, Bold, Black — whereas others just have a couple.

Inter UI comes with a fantastic range of weights

If you’re building a complex web app UI, you might need a range of font weights to establish hierarchy in different contexts. For something less complex, say a blog, you’ll likely be fine with just a couple.

Complex UI hierarchy (left) and Simple blog hierarchy (right)

Variable fonts are an exciting new technology that provide precise control over a font's characteristics. For font weights, this means there's no longer limitations to using "Light," "Regular," and "Bold," but really any weight in between. Try some variable fonts out here and check out Ollie Williams' post as well.

It's still early days — there aren't many variable fonts available right now, and browser support is limited. But definitely a space worth watching!

Consider the legibility of a font

Some typefaces are harder to read than others. Stay away from elaborate fonts when it comes to paragraphs, and if you must have tiny text somewhere, make sure its typeface is legible at those tiny sizes.

Of these two examples, which is easier on the eyes? (There is a right answer here. &#x1f642;)

See the Pen
Font Comparison: Body
by Geoff Graham (@geoffgraham)
on CodePen.

Remember, fonts come in a variety of styles

Making a font bold isn’t as simple as adding an outline to the text, and italics are more than slanted letters. Good fonts have specific bold and italic styles, without which the browser tries to "fake" it:

Lato

These faux styles tend to reduce legibility and break the text’s visual cohesion because the browser can only do so much with what it’s given. Stick to fonts that offer true bold/italics styles, if you can.

Other things worth consideration

What we’ve looked at so far are the high level characteristics and features of fonts that can help us decide which to choose for a particular design or context. There are many other things that can (and probably should) be taken into consideration, including:

  • Language support: Some fonts have glyphs for foreign characters, which may be a requirement for a project geared toward a multilingual audience or that contains multilingual content.
  • Ligatures: Some fonts (typically serifs) have glyphs to replace otherwise awkward characters, like ? and ? which are multiple characters in a single glyph.
  • File size: You’re a developer, so I know you care about performance. Some fonts come in bigger files than others and those can cause a site to take a hit on load times.
Using fonts on the world wide web

A mere 10 years ago, there were two complex ways to use custom fonts on the web:

  • SiFR: Embedding a Flash (remember that thing?) widget to render text.
  • cufon: converting the font to a proprietary format, and using a specific JavaScript rendering engine to generate the text using VML on an HTML <canvas>.

Today, there’s all we need is a single simple one: @font-face. It lets you specify a font file URL, which the browser then downloads and uses on your site.

You can use the @font-face declaration to define your custom font:

@font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); /* IE9 Compat Modes */ src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('webfont.woff2') format('woff2'), /* Super Modern Browsers */ url('webfont.woff') format('woff'), /* Pretty Modern Browsers */ url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */ url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ }

And then refer to it as normal, by the font-family attribute:

body { font-family: 'MyWebFont', Fallback, sans-serif; }

Even though @font-face is light years ahead of the old school approaches to custom web fonts, there is quite a bit to consider as far as browser support goes. Here’s a guide to getting the right amount of cross-browser support.

The impact of fonts on performance

Performance is the only downside to using custom fonts on the web. Fonts are relatively large assets — often hundreds of kilobytes in size — and will have and adverse effect on the speed of any site.

Here are some tips to soften the blow:

  • Use GZIP compression on your web font files.
  • Disable font features you don’t need, e.g. hinting, kerning.
  • Remove glyphs that you don’t need, e.g. foreign language characters.

One tool that can help tailor a font file to suit your needs is Transfonter. Just make sure you have the rights to any font that you want to use on your site because, well, it’s just the right thing to do.

Some services will host web fonts for you

One other significant way to shed some of the weight of using custom web fonts is to use a service that will host and serve them for you. The benefit here is that third-parties store the files on a speedy CDN, optimize them, and serve them to your site via a JavaScript snippet that gets dropped into the document head. In short: it takes a lot of hassle off your hands.

How easy is it to use a hosted service? Consider that using anything on Google Fonts only requires a single <link> in the HTML head:

<html> <head> <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> <style> body { font-family: 'Roboto', sans-serif; } </style> </head> <!-- Rest of the document -->

This example was taken from Google Fonts — the most popular hosted font service. It’s free to use, and, at the time of writing, has a catalogue of 915 font families. The quality of these can be hit-or-miss. Some are truly top-notch — beautiful design, many weights, true bold/italics, and advanced features like ligatures. Others, typically the more novel designs, are bare-bones, and might not be suitable for serious projects with evolving needs.

Adobe Fonts is also very popular. It comes bundled with Adobe’s Creative Cloud offering, which starts at $20.99 per month. At the time of writing, it has a catalogue of 1,636 font families. These are typically high quality fonts that you’d have to pay for, but with Adobe Fonts, you can access them all in a Netflix all-you-can-eat model.

Here are some other options:

  • Adobe Edge Web Fonts: This is the free version of Adobe Fonts. Adobe partnered with Google on this, so there’s a lot of overlap with the Google Fonts library. It has 503 font families in total.
  • Fontspring: This is a massive library of over 14,000 font families, but with an individual licensing model. This means paying more up-front, starting at ~$20 per individual font (and per weight or style), but no recurring costs. It’s also self-serve — you’ll have to host the files yourself.
  • MyFonts by Monotype: This is major type foundry. Similar to Fontspring: massive library of font families with an individual licensing model.
  • Fonts.com: This is similar to Fontspring. Options for one-off or pay-as-you go pricing (based on page views).
  • Cloud.typography by Hoefler&Co: This is a major type foundry. Over 1,000 font families (all by Hoefler&Co), with options for hosted (subscription, starting at $99 per year) or self-hosted (individually licensed) web fonts. The benefit here is that you get access to a library of fonts you cannot find anywhere else.
  • Fontstand: This services allows you to "rent" individual fonts cheaply on a monthly basis, starting ~$10 per month), which you get to own automatically after 12 months. To date, it boasts 1,500 families, with a hosted web font service.
CSS and Typography

OK, let’s move on to the intersection of design and development. We’ve covered a lot of the foundational terms and concepts of typography, but now we can turn our attention to what affordances we have to manipulate and style type, specifically with CSS.

Adjusting font sizing

Changing the size of a font is something that inevitably pops up in a typical project. Size is important because it creates hierarchy, implicitly guiding the user through the page. So, in this section, we’re going to look at two CSS features that are available in our tool belt for adjusting font sizes to create better content hierarchy.

Sizes can be expressed in a different units of measure

Did you know that there are 15 different units for sizing in CSS? Crazy, right? Most of us are probably aware of and comfortable working with pixels (px) but there are so many other ways we can define the size of a font.

Some of these are relative units, and others are absolute. The actual size of an element expressed in relative units depends on other parts of the page, while the actual size of an element expressed in absolute units is always the same. And, as you might expect, that difference is important because they serve different functions, depending on a design’s needs.

Of the 15 units we have available, we will selectively look at two in particular: px and em. Not only are these perhaps the two most used units that you’ll see used to define font sizes, but they also perfectly demonstrate the difference between absolute and relative sizing.

First off, px is an absolute unit and it actually doesn’t have much to do with pixels (it’s considered an angular measurement), but it’s defined so that a line of width 1px appears sharp and visible, no matter the screen resolution. The px value corresponds, roughly, to a little more than the distance from the highest ascender (e.g. the top of the letter A) to the lowest descender (e.g. the bottom of the letter p) in the font. Some fonts have taller letters than others, so 16px in one font might look noticeably "bigger" than 16px in another. Yet another consideration to take into account when choosing a font!

Interestingly enough, when it comes to typography, the px is a unit to be understood, but not used. The true purpose of px units is to serve as the foundation of a type system based on relative units. In other words, it’s an absolute value that a relative unit can point to in order to define its own size relative to that value.

Which takes us to em, a relative unit. Text with a font size of 2em would be twice as big as the font-size of its parent element. The body doesn’t have a parent element, but each device has its own default font-size for the body element. For example, desktop browsers usually default to 16px. Other devices (e.g. mobile phones and TVs) might have different defaults that are optimized for their form factors.

The em lets you reason about your typography intuitively: "I want this title to be twice as big as the paragraph text" corresponds directly to 2em. It’s also easy to maintain — if you need a media query to make everything bigger on mobile, it’s a simple matter of increasing one font-size attribute. Dealing in em units also lets you set other typographical elements in relation to font-size, as we’ll see later.

There are semantic HTML elements that CSS can target to adjust size

You’re sold on the em, but how many em units should each element be? You’ll want to have a range of text sizes to establish hierarchy between different elements of your page. More often than not, you’ll see hierarchies that are six level deep, which corresponds to the HTML heading elements, h1 through h6.

The right size scale depends on the use case. As a guideline, many people choose to use a modular scale. That refers to a scale based on a constant ratio for successive text elements in the hierarchy.

Example of a modular scale with a ratio of 1.4

Modular Scales is a tool by Tim Brown, who popularized this approach, which makes it easy to visualize different size scales.

Adjusting a font’s vertical spacing and alignment

The physical size of a font is a super common way we use CSS to style a font, but vertical spacing is another incredibly powerful way CSS can help improve the legibility of content.

Use line-height to define how tall to make a line of text

Line height is one of the most important factors affecting readability. It’s controlled by the line-height property, best expressed as a unit-less number that corresponds to a multiple of the defined font size.

Let’s say we are working with a computed font size of 16px (specified in the CSS as em units, of course), a line-height of 1.2 would make each line 19.2px tall. (Remember that px aren’t actually pixels, so decimals are valid!)

Most browsers default to a line-height of 1.2 but the problem is that this is usually too tight — you probably want something closer to 1.5 because provides a little more breathing room for your eyes when reading.

Here are some general guidelines to define a good line height:

  • Increase line-height for thick fonts
  • Increase line-height when fonts are a dark color
  • Increase line-height for long-form content
Increasing the line-height can drastically improve legibility Fonts can’t dance, but they still have rhythm

Rhythm describes how text flows vertically on a page. Much like music, some amount of consistency and structure usually leads to good "rhythm." Like most design techniques, rhythm isn’t an exact science but there are some sensible guidelines that give good results.

One school of thought prescribes the use of paragraph line height as a baseline unit from which all other spacing is derived. This includes gaps between paragraphs and headings, and padding between the text and other page elements.

Under this system, you might set the line height of a heading to twice the line height of paragraphs, and leave a one-line gap between a heading and paragraph. Handily, you can use the same em units to define margins and padding, so there’s really no need to hard-code anything.

Read more about rhythm here.

Horizontal Shape

Hopefully you’re convinced by now that vertical spacing is an important factor in improving legibility that we can control in CSS. Equally important is the horizontal spacing of individual characters and the overall width of content.

CSS can control the space between letters

Letter spacing is one of the most important factors affecting legibility. It is controlled by the CSS letter-spacing property, best expressed (again) in em units to keep everything relative. Tracking (the typography term for "letter spacing") depends entirely on the font — some fonts will look great by default, while others might need a little tweaking.

In general, you only need to worry about letter spacing for text elements that are particularly big or small because most fonts are spaced well at a typical paragraph size.

For larger text, like headings and titles, you’ll often want to reduce the space between letters. And a little bit of space goes a long way. For example, -0.02em is a tiny decimal, but a good starting point, which can be tweaked until it looks just right to your eye. The only time you should think about increasing letter spacing is when dealing with stylistically unusual text — things like all-capped titles and even some number sequences.

Adding or subtracting as little as 0.02em can refine the appearance of words

Some specific pairs of letters, like AV, can look awkwardly spaced without a little manual tweaking. Well-crafted fonts typically specify custom spacing for such pairs, and setting the font-kerning property to normal lets you enable this. Browsers disable this on smaller text by default. Here is a little more on letter spacing, as well as other CSS tools we have to control font spacing in general.

The length of a line of text is more important than you might think

It’s unpleasant for our eyes to move long distances while reading, so the width of lines should be deliberate. General consensus is that a good width is somewhere between 60 and 70 characters per line. If you find that a line of text (especially for long-form content) drastically falls outside this range, then start adjusting.

The ch is a little-known CSS unit that we didn’t cover earlier, but can be helpful to keep line length in check. It’s a relative unit, defined as the width of the 0 character in the element’s font. Because narrow characters like l and i are relatively frequent, setting the width of a text container to something like 50ch should result in lines that are 60-70 character long.

p { width: 50ch; } CSS can smooth otherwise crispy fonts

-webkit-font-smoothing is a nifty CSS property that controls how fonts are anti-aliased. This is a fancy way of saying it can draw shades of gray around otherwise square pixels to create a smoother appearance. Do note, however, the -webkit prefix there, because that indicates that the property is only supported by WebKit browsers, e.g. Safari.

The default setting is subpixel-antialiased, but it’s worth seeing what your type looks like when it’s set to just antialiased. It can improve the way many fonts look, especially for text on non-white backgrounds.

At small font sizes, this should be used with caution — it lowers contrast, affecting readability. You should also make sure to adjust letter-spacing when using this, since greater anti-aliasing will increase the space between letters.

Anti-aliased (left) Subpixel Anti-aliased (right) Wrapping up

Phew! We covered a lot of ground in a relatively short amount of space. Still, this is by no means an exhaustive guide, but rather, something that I hope will encourage you to take more control over the typography in your future projects, and to seek an even deeper knowledge of the topic. For that, I’ve compiled a list of additional resources to help you level up from here.

Learning about typography Typography Inspiration Identifying Fonts
  • WhatFont
  • Identifont
  • WhatTheFont
  • Typography in CSS

    The post Typography for Developers appeared first on CSS-Tricks.

    What We Want from Grid

    Css Tricks - Tue, 02/26/2019 - 3:14pm

    We felt spoiled with CSS grid for a minute there. It arrived hot and fast in all the major browsers all at once. Now that we're seeing a lot more usage, we're seeing people want more from grid.

    Michelle Barker lists hers wants (and I'll put my commentary after):

    • Styling row and column gaps. I've also heard requested styling grid cells directly, rather than needing to place an element there and style that element.
    • Multiple gap values. I wanted this just the other week, and I was told to use an empty column or row instead of a gap. The size of that column can be controlled, and things are placed accordingly to treat it like a gap. Sort of OK, except that isn't particularly friendly to implicit grids.
    • Autoflow patterns. This is clever. Check out Michelle's use case and proposal.
    • calc() with the fr unit. This is a mindbender. I can see wanting to do something like calc(1fr - 100px), but then isn't the leftover space 100px short and 1fr recalcuated to fill that space? Seems infinite loopy.
    • Aspect ratio grid cells. I suspect, if we get this, it'll be a generic aspect ratio solution that will work on any element, including elements placed onto a grid.

    Subgrid is also starting to be hotly requested, and I can see why. While building the last page layout I did using grid, I found myself strongly wishing I could share the overall page grid lines within sub-elements.

    Rachel Andrew talked about its status about six months ago in CSS Grid Level 2: Here Comes Subgrid. I'm not sure where it's at now, but I don't think any browser is supporting it quite yet. (I'm not even sure if the spec is technically done.)

    Brad put a point on the desire here:

    Container queries and subgrid would make my design system work so much easier.

    Define a grid and throw some components in there, then watch them snap into place to the parent grid and look great no matter what the container dimensions are.

    — Brad Frost (@brad_frost) February 11, 2019

    And Ken Bellows writes:

    • If we combine subgrid with grid-template-areas within the cards (read my last post if you don't know about Grid Areas, it'll blow your mind), complex responsive card-based layouts become trivial.
    • The prospect of a subgrid on both axes gives us a way to sort of accomplish relative grid positioning, at least for semantically grouped items, like I wished I had above! Group your stuff in a container, position your container on the grid, make that container a subgrid on both axes, and declare your tracks relative to the subgrid element's grid position!
    • Between Flexbox, Grid, display: contents, and subgrids, we will finally have everything we need to write very slim, clean, semantic markup with basically no fluff or purely structural elements. It will be a huge boon for accessibility, SEO, and just developers trying to understand your markup!

    Eric Meyer called subgrid an essential feature three years ago:

    This is why I’ve come to the same conclusion other grid experts (like Rachel) already have: subgrids are a major component of grid layout, and should be a part of any grid layout implementation when it emerges from developer-preview status.  If that means delaying the emergence of grids, I think it’s worth it.

    And of course, everybody still wants native masonry. ;)

    The post What We Want from Grid appeared first on CSS-Tricks.

    Look Ma, No Media Queries! Responsive Layouts Using CSS Grid

    Css Tricks - Tue, 02/26/2019 - 3:14pm

    Not only has CSS Grid reshaped the way we think and build layouts for the web, but it has also contributed to writing more resilient code, replacing "hacky" techniques we've used before, and in some cases, killing the need to rely on code for specific resolutions and viewports. What's so cool about this era in web development is that we're capable of doing more and more with fewer lines of code.

    In this article, we'll start dipping our toes into the power of CSS Grid by building a couple of common responsive navigation layouts. It's easier than what you may think, and since CSS Grid was built with responsiveness in mind, it'll take less code than writing media queries all over the place. Let’s do this!

    Layout #1: Hero content and list of articles

    See the Pen
    Hero Content and List of Articles
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    We'll kick off this set of examples by creating a common website layout: A full-width hero section, with a grid of cards below.

    Both elements will respond to window resizing and adapt accordingly. Though this might seem like a lot of code at first glance, the responsive behavior is done with only six lines of CSS Grid code, and without writing a single @media rule. Let's break down the code to see what's going on:

    The hero section

    Let’s take a look at the code for the .hero element:

    <section class="hero"> <h1>You thirsty?</h1> <article> <p>Explore local breweries with just one click and stirred by starlight across the centuries light years great turbulent clouds circumnavigated paroxysm of global death.</p> <a href="#breweries">Browse Breweries</a> </article> </section> .hero { /* Photo by mnm.all on Unsplash */ background: url('https://images.unsplash.com/photo-1518176258769-f227c798150e') center; background-size: cover; padding: 4rem 2rem; /* Grid styles */ display: grid; align-items: center; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

    We have a bunch of background styles to enable the beer background, a bit of padding to separate the content from the edge of the screen, and then three lines of grid styles:

    1. The first line (display: grid;) is changing the behavior of the .hero element to be a grid container. That means the elements inside .hero are now grid items.
    2. The second line (align-items: center;) is going to vertically center the columns on our grid. But these two lines don't do anything on their own until we set the columns of our grid.
    3. And that's where the third line comes in. A lot of stuff is going on in that single property, so let's go one step at a time.
    The repeat() function

    Generally speaking, what we usually do to define our columns and rows on a CSS Grid is to add the value for each track after defining the property, like this:

    .element { /* This will result on four columns, each one of 1fr */ grid-template-columns: 1fr 1fr 1fr 1fr; /* This will result on two rows, each one of 300px */ grid-template-rows: 300px 300px; }

    Now, that's quite dull. We can use the repeat() function to make that less verbose and easier to follow. The function takes two parameters:

    1. The number of times to repeat the value.
    2. The value itself.

    After refactoring our code to use repeat(), we should expect the same results from these lines of code:

    .element { /* this is the same as grid-template-columns: 1fr 1fr 1fr 1fr; */ grid-template-columns: repeat(4, 1fr); /* this is the same as grid-template-rows: 300px 300px; */ grid-template-rows: repeat(2, 300px); }

    Much cleaner, yeah?

    The minmax() function

    Now, the above examples are explicitly defining sizes for the tracks (1fr and 300px). That might work for some scenarios, but for our beer example here, we need to be able to automatically calculate the size of the track, based on the width of the viewport, and automatically adjust the number of columns shown. To be able to do that, we'll define a range of values using the minmax() function. What will we be defining? You've probably guessed by now: The *minimum* and *maximum* values we want these columns to be able to resize to.

    In the hero for our beer example above, we set our minmax() property to be 240px at its minimum size, and 1fr at its maximum size. fr units, if you've never heard of them, stand for fractional units. Nobody can explain them better than Jen Simmons on this video and Robin Rendle in this post.

    Using the Firefox Grid Inspector to check the change on the track's size when resizing

    That results in our tracks being 1fr when there's plenty of space on our viewport (aka desktop resolutions), and 240px when there's not enough space for both columns (like on mobile devices). That's why they nicely grow when we make our browser wider, since they're taking the remaining space and equally dividing it across the existing columns. Now, moving to the last piece of the puzzle!

    The auto-fit keyword

    The auto-fit keyword allows us to wrap our columns into rows when there's not enough space in our viewport to fit the 240px minimum value without overflowing the content. Sara Soueidan wrote an excellent article about auto-sizing columns using the auto-fill and auto-fit keywords, in case you want to dive a little deeper into what's going on under the hood. Now, with that last bit of code in place, we should be able to achieve this result:

    The column is automatically wrapping when there's not enough space in the viewport The article list

    Now that we've thoroughly reviewed the behavior of the elements inside our hero element, it's likely that the first two lines of CSS code for the breweries list below it might already seem familiar to you:

    .breweries > ul { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); grid-gap: 1rem; }

    That's right! We're using the exact same approach: On the first line we define our grid, on the second one we size our tracks using the same magic one-liner, and on the third line we set a gap for these columns. Nothing new under the sun, and what's really neat about this, is that our code is resilient enough to adjust the number of tracks and their sizes, according to the number of items we have inside our unordered list:

    The grid responds to the change in the number of tracks, and adapts the layout

    That's all, folks! A fully responsive website layout, using just six lines of CSS code. Not bad, huh? Make sure you check the source code and play around with this example on CodePen.

    Layout #2: Full-width image gallery

    See the Pen
    Full Width Image Gallery
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    On this next example, we'll embrace the power of our newly learned combination of repeat(), auto-fit and minmax() to create this responsive image gallery. We'll also be sizing our tracks using grid-column and grid-row, and learning about the handy property:value combination of grid-auto-flow: dense; that allows us to change the default behavior of the elements that can't fit on our explicit tracks: Instead of wrapping themselves in new rows or columns, we'll make them fit into the unused spots on our grid. Let's get into the coding!

    The grid setup

    The grid is created using our familiar display: grid; property, where columns are defined using repeat(), auto-fit and minmax(). We also added a bunch rows with a repeat() function and defined a gap to our images, using grid-gap. But the new player here is the grid-auto-flow: dense;. We’ll get to it in a second.

    .gallery > .gallery__list { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); grid-template-rows: repeat(6, 200px); grid-gap: 1rem; grid-auto-flow: dense; }

    We also created a repetition pattern using the nth-child() pseudo-selector to set different sizes for our tracks using grid-column and grid-row. Notice here that we’re using the span keyword to allow the selected item to occupy more than one column or row.

    /* This will create 2x images every 4 elements */ .gallery > .gallery__list > li:nth-child(4n) { grid-column: span 2; /* Spans two columns */ grid-row: span 2; /* Spans two rows */ } /* This will create 3x images every 8 elements */ .gallery > .gallery__list > li:nth-child(8n) { grid-column: span 3; grid-row: span 3; }

    And finally, we'll make sure our images cover the entire area of its container, regardless if it's 1x, 2x or 3x, using object-fit: cover;. If you have never heard of object-fit, it works fairly similar to how background-image does, but with HTML <img> tags:

    .gallery > .gallery__list > li > figure > img { width: 100%; height: 100%; object-fit: cover; }

    Now, the real deal here is grid-auto-flow: dense;. Check what happens when we take that out from our code:

    Removing grid-auto-flow: dense; leads to inconsistent placement of the elements on the grid

    See those holes on our beautifully crafted grid? That's because some of the elements on it are taking 2x or 3x spots, and when there isn't enough space on our tracks to fit them, they'll wrap into a new row, since that's the default behavior. By changing it from row to dense, we're telling the grid to fill any gaps we might have with elements that could fit them, regardless of their source order on the DOM.

    That's why this technique might come especially handy for things like image galleries, but might not be suitable for other use cases where you might need to preserve the order of the markup. Feel free to play around with the CodePen demo to check the differences between where items are placed.

    Layout #3: Trello-style card layout

    See the Pen
    Trello-Style Card Layout
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    Now, on to the last demo, where we'll take advantage of the ability to nest grids to recreate this Trello Board. We'll be creating a grid to hold our four different columns, and inside of those, we'll create a child grid for our cards. Even though this example won't explore new properties or revolutionary methods, it'll help us to get a grasp on how easy it is to build complex layouts with a few lines of CSS code. This demo has a lot of extra code to achieve the styling of the Trello layout, so we’ll focus solely on the grid styles.

    The columns

    To create the four columns, we'll use display: grid; on the container and use our magical one-liner for our grid-template-columns. We'll also be defining a gap between them, and use align-items: flex-start; to ensure that our columns don't stretch to the bottom of the screen.

    .column__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-gap: .5rem; align-items: flex-start; }

    Now, the original Trello is not responsive by default: If you resize your browser on a Trello Board, you'll notice that you'll end up having a horizontal scroll on your columns, rather than wrapping them on a new row. We're not following that behavior here since we want to build responsive layouts, but in case you're curious, and want to emulate Trello's functionality, you can achieve that by adding two more lines of CSS code:

    .column__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-gap: .5rem; align-items: flex-start; /* Uncomment these lines if you want to have the standard Trello behavior instead of the column wrapping */ grid-auto-flow: column; grid-auto-columns: minmax(260px, 1fr); }

    We learned about grid-auto-flow in our previous demo and discovered that it let us control how the auto-placement algorithm work, and how implicit elements should be added in the flow of the grid. The default behavior is row, meaning that any extra element that won't fit on our grid will wrap into a new line. We changed that to be dense on our previous demo, and we'll change it to be column on this one: That way, any new column added here will end up in an implicit column, and have a horizontal scroll. We'll also define a width for those auto-generated columns with the grid-auto-columns property.

    Modifying the grid-auto-flow property will make this demo behave like the real-world Trello The cards

    For the cards grid, we'll use a similar approach. We'll display: grid; on the container. We won't define any columns here, since we don't want to have any, and we'll put grid-template-rows: auto; to use to avoid all cards having the same height — we want some of them to be bigger and some of them smaller, based on the type of content being added to them.

    .card__list { display: grid; grid-template-rows: auto; grid-gap: .5rem; margin: .5rem 0; }

    And, again, that's all folks! Two more lines to set a gap and a margin to the cards, and we're done! Everything else in the Pen is standard CSS to achieve the Trello look and feel.

    So then... are media queries dead?

    Back in the day, when we were building layouts using display: inline-block or floats, media queries made a lot of sense in order to change the size of our elements as the viewport got smaller. But now, with the incredibly powerful layouts that we're able to create with a couple of CSS lines, you might feel tempted to think that media queries are doomed. I strongly disagree with that: I believe that we should change the way we think about them, and therefore use them differently.

    As Rachel Andrew stated about a year ago, we should use media queries to fix our layout when it breaks, rather than targeting devices: There are so many out there! With the advent of Media Queries Level 4 and 5, we're not only able to detect screen sizes now, but pointer types as well. As a result, we can dig into a user’s system preferences and adapt our code for those who prefer reduced motion or whether we should use inverted colors. That means media queries are not dead; on the flipside, I'd say it's an exciting time for using media queries, but we need to learn to use them right. In the meantime, building robust layouts using modern techniques such as Flexbox or CSS Grid, will save you a bunch of time, code, and headaches.

    The post Look Ma, No Media Queries! Responsive Layouts Using CSS Grid appeared first on CSS-Tricks.

    Responsive Designs and CSS Custom Properties: Building a Flexible Grid System

    Css Tricks - Tue, 02/26/2019 - 5:28am

    Last time, we looked at a few possible approaches for declaring and using CSS custom properties in responsive designs. In this article, we’ll take a closer look at CSS variables and how to use them in reusable components and modules. We will learn how to make our variables optional and set fallback values.

    As an example, we will build a simple grid system based on flexbox. Grid systems play a vital role in responsive designs. However, building a grid system that is flexible and lightweight at the same time can be a tricky task. Let’s see what the common approaches towards grid systems are and how CSS custom properties can help us build them.

    Article Series:
    1. Defining Variables and Breakpoints
    2. Building a Flexible Grid System (This Post)
    A simple CSS grid system

    Let’s start with a 12-column grid system:

    .container { max-width: 960px; margin: 0 auto; display: flex; } .col-1 { flex-basis: 8.333%; } .col-2 { flex-basis: 16.666%; } .col-3 { flex-basis: 25%; } .col-4 { flex-basis: 33.333%; } .col-5 { flex-basis: 41.666%; } .col-6 { flex-basis: 50%; } /* and so on up to 12... */

    See the Pen
    #5 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    There’s quite a lot of repetition and hard-coded values here. Not to mention how many more will be generated once we add more breakpoints, offset classes, etc.

    Building a grid system with Sass

    To make our grid example more readable and maintainable, let’s use Sass to preprocess our CSS:

    $columns: 12; // Number of columns in the grid system .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } @for $width from 1 through $columns { .col-#{$width} { flex-basis: $width / $columns * 100%; } }

    See the Pen
    #6 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This is definitely much easier to work with. As we develop our grid further and, let’s say, would like to change it from 12 columns to 16 columns, all we have to do is to update a single variable (in comparison to dozens of classes and values). But... as long as our Sass is shorter and more maintainable now, the compiled code is identical to the first example. We are still going to end up with a massive amount of code in the final CSS file. Let’s explore what happens if we try to replace the Sass variables with CSS custom properties instead.

    Building a grid system with CSS custom properties

    Before we start playing with CSS custom properties, let’s start with some HTML first. Here’s the layout we’re aiming for:

    It consists of three elements: a header, a content section and a sidebar. Let’s create markup for this view, giving each of the elements a unique semantic class (header, content, sidebar) and a column class which indicates that this element is a part of a grid system:

    <div class="container"> <header class="header column"> header </header> <main class="content column"> content </main> <aside class="sidebar column"> sidebar </aside> </div>

    Our grid system, as before, is based on a 12-column layout. You can envision it as an overlay covering our content areas:

    So .header takes all 12 columns, .content takes eight columns (66.(6)% of the total width) and .sidebar takes four columns (33.(3)% of the total width). In our CSS, we would like to be able to control the width of each section by changing a single custom property:

    .header { --width: 12; } .content { --width: 8; } .sidebar { --width: 4; }

    To make it work, all we need to do is write a rule for the .column class. Lucky for us, most of the work is already done! We can re-use the Sass from the previous chapter and replace the Sass variables with CSS custom properties:

    .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } .column { --columns: 12; /* Number of columns in the grid system */ --width: 0; /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); }

    Notice two important changes here:

    1. The --columns variable is now declared inside of the .column rule. The reason is that this variable is not supposed to be used outside of the scope of this class.
    2. The math equation we perform in the flex-basis property is now enclosed within a calc() function. Math calculations that are written in Sass are compiled by the preprocessor and don’t need additional syntax. calc(), on the other hand, lets us perform math calculations in live CSS. The equation always needs to be wrapped within a calc() function.

    On a very basic level, that’s it! We’ve just built a 12-column grid system with CSS custom properties. Congratulations! We could call it a day and happily finish this article right now, but... we usually need a grid system that is a bit more sophisticated. And this is when things are getting really interesting.

    See the Pen
    #8 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Adding a breakpoint to the grid

    Most times, we need layouts to look different on various screen sizes. Let’s say that in our case we want the layout to remain as it is on a large viewport (e.g. desktop) but have all three elements become full-width on smaller screens (e.g. mobile).

    So, in this case, we would like our variables to look as follows:

    .header { --width-mobile: 12; } .content { --width-mobile: 12; --width-tablet: 8; /* Tablet and larger */ } .sidebar { --width-mobile: 12; --width-tablet: 4; /* Tablet and larger */ }

    .content and .sidebar each hold two variables now. The first variable (--width-mobile) is a number of columns an element should take by default, and the second one (--width-tablet) is the number of columns an element should take on larger screens. The .header element doesn’t change; it always takes the full width. On larger screens, the header should simply inherit the width it has on mobile.

    Now, let’s update our .column class.

    CSS variables and fallback

    To make the mobile version work as expected, we need to alter the .column class as follows:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); }

    Basically, we replace the value of the --width variable with --width-mobile. Notice that the var() function takes two arguments now. The first of them is a default value. It says: "If a --width-mobile variable exists in a given scope, assign its value to the --width variable." The second argument is a fallback. In other words: "If a --width-mobile variable is not declared in a given scope, assign this fallback value to the --width variable." We set this fallback to prepare for a scenario where some grid elements won’t have a specified width.

    For example, our .header element has a declared --width-mobile variable which means the --width variable will be equal to it and the flex-basis property of this element will compute to 100%:

    .header { --width-mobile: 12; } .column { --columns: 12; --width: var(--width-mobile, 0); /* 12, takes the value of --width-mobile */ flex-basis: calc(var(--width) / var(--columns) * 100%); /* 12 ÷ 12 × 100% = 100% */ }

    If we remove the --width-mobile variable from the .header rule, then the --width variable will use a fallback value:

    .header { /* Nothing here... */ } .column { --columns: 12; --width: var(--width-mobile, 0); /* 0, takes the the fallback value */ flex-basis: calc(var(--width) / var(--columns) * 100%); /* 0 ÷ 12 × 100% = 0% */ }

    Now, as we understand how to set fallback for CSS custom properties, we can create a breakpoint, by adding a media query to our code:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet); /* Width of the element on tablet and up */ } }

    This works exactly as expected, but only for the content and sidebar, i.e. for the elements that have specified both --width-mobile and --width-tablet. Why?

    The media query we created applies to all .column elements, even those that don’t have a --width-tablet variable declared in their scope. What happens if we use a variable that is not declared? The reference to the undeclared variable in a var() function is then considered invalid at computed-value time, i.e. invalid at the time a user agent is trying to compute it in the context of a given declaration.

    Ideally, in such a case, we would like the --width: var(--width-tablet); declaration to be ignored and the previous declaration of --width: var(--width-mobile, 0); to be used instead. But this is not how custom properties work! In fact, the invalid --width-tablet variable will still be used in the flex-basis declaration. A property that contains an invalid var() function always computes to its initial value. So, as flex-basis: calc(var(--width) / var(--columns) * 100%); contains an invalid var() function the whole property will compute to auto (the initial value for flex-basis).

    What else we can do then? Set a fallback! As we learned before, a var() function containing a reference to the undeclared variable, computes to its fallback value, as long as it’s specified. So, in this case, we can just set a fallback to the --width-tablet variable:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, 0)); } }

    See the Pen
    #9 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This will create a chain of fallback values, making the --width property use --width-tablet when available, then --width-mobile if --width-tablet is not declared, and eventually, 0 if neither of the variables is declared. This approach allows us to perform numerous combinations:

    .section-1 { /* Flexible on all resolutions */ } .section-2 { /* Full-width on mobile, half of the container's width on tablet and up */ --width-mobile: 12; --width-tablet: 6; } .section-3 { /* Full-width on all resolutions */ --width-mobile: 12; } .section-4 { /* Flexible on mobile, 25% of the container's width on tablet and up */ --width-tablet: 3; }

    One more thing we can do here is convert the default 0 value to yet another variable so we avoid repetition. It makes the code a bit longer but easier to update:

    .column { --columns: 12; /* Number of columns in the grid system */ --width-default: 0; /* Default width, makes it flexible */ --width: var(--width-mobile, var(--width-default)); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, var(--width-default))); } }

    See the Pen
    #10 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Now, we have a fully functional, flexible grid! How about adding some more breakpoints?

    Adding more breakpoints

    Our grid is already quite powerful but we often need more than one breakpoint. Fortunately, adding more breakpoints to our code couldn’t be easier. All we have to do is to re-use the code we already have and add one variable more:

    .column { --columns: 12; /* Number of columns in the grid system */ --width-default: 0; /* Default width, makes it flexible */ --width: var(--width-mobile, var(--width-default)); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, var(--width-default))); } } @media (min-width: 768px) { .column { --width: var(--width-desktop, var(--width-tablet, var(--width-mobile, var(--width-default)))); } }

    See the Pen
    #11 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Reducing fallback chains

    One thing that doesn’t look that great in our code is that feedback chains are getting longer and longer with every breakpoint. If we’d like to tackle this issue, we can change our approach to something like this:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width-tablet: var(--width-mobile); --width: var(--width-tablet); } } @media (min-width: 768px) { .column { --width-desktop: var(--width-tablet); --width: var(--width-desktop); } }

    See the Pen
    #12 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This code is doing exactly the same job but in a bit different way. Instead of creating a full fallback chain for each breakpoint, we set a value of each variable to the variable from the previous breakpoint as a default value.

    Why so complicated?

    It looks like we’ve done quite a lot of work to complete a relatively simple task. Why? The main answer is: to make the rest of our code simpler and more maintainable. In fact, we could build the same layout by using the techniques described in the previous part of this article:

    .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } .column { --columns: 12; /* Number of columns in the grid system */ --width: 0; /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } .header { --width: 12; } .content { --width: 12; } .sidebar { --width: 12; } @media (min-width: 576px) { .content { --width: 6; } .sidebar { --width: 6; } } @media (min-width: 768px) { .content { --width: 8; } .sidebar { --width: 4; } }

    In a small project, this approach could work perfectly well. For the more complex solutions, I would suggest considering a more scalable solution though.

    Why should I bother anyway?

    If the presented code is doing a very similar job to what we can accomplish with preprocessors such as Sass, why should we bother at all? Are custom properties any better? The answer, as usually, is: it depends. An advantage of using Sass is better browser support. However, using custom properties has a few perks too:

    1. It’s plain CSS. In other words, it’s a more standardized, dependable solution, independent from any third parties. No compiling, no package versions, no weird issues. It just works (apart from the browsers where it just doesn’t work).
    2. It’s easier to debug. That’s a questionable one, as one may argue that Sass provides feedback through console messages and CSS does not. However, you can’t view and debug preprocessed code directly in a browser, whilst working with CSS variables, all the code is available (and live!) directly in DevTools.
    3. It’s more maintainable. Custom properties allow us to do things simply impossible with any preprocessor. It allows us to make our variables more contextual and, therefore, more maintainable. Plus, they are selectable by JavaScript, something Sass variables are not.
    4. It’s more flexible. Notice, that the grid system we’ve built is extremely flexible. Would you like to use a 12-column grid on one page and a 15-column grid on another? Be my guest—it’s a matter of a single variable. The same code can be used on both pages. A preprocessor would require generating code for two separate grid systems.
    5. It takes less space. As long as the weight of CSS files is usually not the main bottleneck of page load performance, it still goes without saying that we should aim to optimize CSS files when possible. To give a better image of how much can be saved, I made a little experiment. I took the grid system from Bootstrap and rebuilt it from scratch with custom properties. The results are as follows: the basic configuration of the Bootstrap grid generates over 54KB of CSS whilst a similar grid made with custom properties is a mere 3KB. That’s a 94% difference! What is more, adding more columns to the Bootstrap grid makes the file even bigger. With CSS variables, we can use as many columns as we want without affecting the file size at all.

    The files can be compressed to minimize the difference a bit. The gzipped Bootstrap grid takes 6.4KB in comparison to 0.9KB for the custom properties grid. This is still an 86% difference!

    Performance of CSS variables

    Summing up, using CSS custom properties has a lot of advantages. But, if we are making the browser do all the calculations that had been done by preprocessors, are we negatively affecting the performance of our site? It’s true that using custom properties and calc() functions will use more computing power. However, in cases similar to the examples we discussed in this article, the difference will usually be unnoticeable. If you’d like to learn more about this topic, I would recommend reading this excellent article by Lisi Linhart.

    Not only grid systems

    After all, understanding the ins and outs of custom properties may not be as easy as it seems. It will definitely take time, but it’s worth it. CSS variables can be a huge help when working on reusable components, design systems, theming and customizable solutions. Knowing how to deal with fallback values and undeclared variables may turn out to be very handy then.

    Thanks for reading and good luck on your own journey with CSS custom properties!

    The post Responsive Designs and CSS Custom Properties: Building a Flexible Grid System appeared first on CSS-Tricks.

    Moving a Self-Hosted WordPress Site to WordPress.com

    Css Tricks - Tue, 02/26/2019 - 5:23am

    I have a habit of getting some hosting when I need a new WordPress site. That is, a self-installed, self-hosted WordPress.org site. That's served me well over the years. I like my control. But along with that control comes a certain level of extra responsibility that sometimes just isn't worth it.

    That's the case for me now with my little blog Email is Good.

    Right from the get-go, I knew I wanted Email is Good to be as absolutely simple as could be. At the moment, I can't prioritize a fancy custom design or really any specialized functionality at all. All I want is a simple, clean blog in which to publish blog posts. And as powerful and flexible as WordPress is, it's still extra good at that use case.

    Email is Good uses an untouched, stock copy of the TwentySixteen theme.

    I'd like to move it over to WordPress.com, so that I don't have to deal with hosting, upgrades, backups, security... it'll just host my simple blog and I can unburden myself of that little spoonful of technical debt.

    Their docs for this are there, but a little on the light side, so I'll document my process here.

    Set up the WordPress.com side first

    There is a nice clean URL for kicking off a new WordPress.com site:

    https://wordpress.com/start/

    There isn't really a one-click just suck everything over in one shot system. Instead, you set up the site on WordPress.com, deal with the domain, and import the content. It might feel a little weird, but this first step is just kinda re-setting up the basics:

    Deal with the domain

    By "domain", I mean the URL that you may already own. I own "email-is-good.com" which is what I want to continue to use.

    During setup you can buy a domain (or get a free one! They'll give you a wordpress.com or .blog subdomain), but since I'm moving a site here, I'll select the option that I already own the domain.

    My domain name is already registered on GoDaddy.com. I could just leave the domain name there and map the domain over to WordPress.com. I think that's generally a smart thing to do, but I wanted to try what seems to be the default which is transferring it over to WordPress.com.

    Part of the beauty of transferring the domain is there is no settings to screw up, as it will be handled by WordPress.com

    I went through a process of basically re-registering the domain with WordPress.com.

    In order to actually transfer the domain, I had to go to GoDaddy and "unlock" the domain as well as request a transfer authorization code.

    If you're transferring a domain, it can take a little while.

    The note on the page above tells me it might take a full week to complete. It took me one day less. I got the success email on February 18th instead of 19th.

    I did have to "flip the switch", as the email suggests, to use the WordPress nameservers.

    But before I did, I made sure the new WordPress.com site had all the old content!

    Exporting Content & Media

    There is an export tool baked right into WordPress. Find it under Tools.

    You'll get an .xml file as output. Mine was called:

    emailisgood.wordpress.2019-02-12.xml

    Importing Content & Media

    On the WordPress.com side, there is a big Import option right in the sidebar. In those options, there is a WordPress option to choose.

    Drag and drop the .xml file there.

    Mine was pretty quick, but I imagine it could take a while. You'll even get an email when it's done.

    All my content and media made the journey just fine!

    Clean Up

    I had to do a little cleanup here and there to get the site exactly as it was. My site is so basic, it was hardly any work, but it's worth knowing you might have to mop up a little. For example, the site already had a contact page, so I had to nuke the one that was imported (which was using a contact form plugin I didn't need any more anyway) and make sure it was all functional.

    Another thing that didn't make the trip to the new site was the widgets. I had a sidebar with some widgets that I had to re-build, but that was no big deal. I literally copy-pasted the content from them from the old site before I flipped the switch.

    So now! I've ditched a pile of technical debt. No more worrying about my SSL certifiate. No more having to manually follow up with any hosting company about downtime. Performance is largely in the hands of someone else.

    I just have a simple site where I can write write write.

    Video!

    If it's helpful for you to watch me talk all this out, I've put it on YouTube:

    The post Moving a Self-Hosted WordPress Site to WordPress.com appeared first on CSS-Tricks.

    iconsvg.xyz

    Css Tricks - Mon, 02/25/2019 - 10:45am

    There is a lot to like about Gaddafi Rusli's ICONSVG.

    1. It provides inline <svg>, which is the most generically useful way to deliver them, and probably how they should be used anyway. Each icon is a tiny amount of SVG and I'd bet they were all hand-golfed.
    2. They are all stroke-based, so they can be beefed up or slimmed down as needed.
    3. The stroke-linecap and stroke-linejoin properties can be adjusted, which presents an opportunity to make their edges sharper or more rounded. I often find icons that are close to what I want, but the weight isn't right or the edges are either too sharp or too round. This quick and easy configuration is awesome.

    Direct Link to ArticlePermalink

    The post iconsvg.xyz appeared first on CSS-Tricks.

    Dealing with overflow and position: sticky;

    Css Tricks - Mon, 02/25/2019 - 10:44am

    Any overflow value other than visible and no height is the enemy of child elements with position: sticky;. It's like that element is ready to stick when the parent scrolls, but it never does because the height is unconstrained. Adding a fixed height can solve the issue, but that's not always desirable.

    Dannie Vinther digs into a way of dealing with that. The end result is avoiding that situation all together by removing the element that wants to be sticky from the element that needs an overflow. But as soon as you do that, the elements no longer scroll together since they aren't siblings. The use case here is a table with sticky headers on vertical scrolling and allowing for horizontal scrolling as well. Dannie uses a script to sync the scroll positions.

    Direct Link to ArticlePermalink

    The post Dealing with overflow and position: sticky; appeared first on CSS-Tricks.

    Responsive Designs and CSS Custom Properties: Defining Variables and Breakpoints

    Css Tricks - Mon, 02/25/2019 - 5:22am

    CSS custom properties (a.k.a. CSS variables) are becoming more and more popular. They finally reached decent browser support and are slowly making their way into various production environments. The popularity of custom properties shouldn’t come as a surprise, because they can be really helpful in numerous use cases, including managing color palettes, customizing components, and theming. But CSS variables can also be really helpful when it comes to responsive design.

    Article Series:
    1. Defining Variables and Breakpoints (This Post)
    2. Building a Flexible Grid System

    Let’s consider an <article> element with a heading and a paragraph inside:

    <article class="post"> <h2 class="heading">Post's heading</h2> <p class="paragraph"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium numquam adipisci recusandae officiis dolore tenetur, nisi, beatae praesentium, soluta ullam suscipit quas? </p> </article>

    It’s a common scenario in such a case to change some sizes and dimensions depending on the viewport’s width. One way to accomplish this is by using media queries:

    .post { padding: 0.5rem 1rem; margin: 0.5rem auto 1rem; } .heading { font-size: 2rem; } @media (min-width: 576px) { .post { padding: 1rem 2rem; margin: 1rem auto 2rem; } .heading { font-size: 3rem; } }

    See the Pen
    #1 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Such an approach gives us an easy way to control CSS properties on different screen sizes. However, it may be hard to maintain as the complexity of a project grows. When using media queries, keeping code readable and DRY at the same time quite often turns out to be challenging.

    The most common challenges when scaling this pattern include:

    • Repeated selectors: Apart from bloating code with multiple declarations, it also makes future refactoring more difficult, e.g. every time a class name changes it requires remembering to update it in multiple places.
    • Repeated properties: Notice that when overwriting CSS rules within media queries, it requires repeating the entire declaration (e.g. font-size: 3rem;) even though it’s just the value (3rem) that actually changes.
    • Repeated media queries: To keep responsive styles contextual, it’s a common practice to include the same media queries in multiple places, close to the styles they override. Unfortunately, it not only makes code heavier, but also might make breakpoints much harder to maintain. On the other hand, keeping all responsive styles in one place, away from their original declarations, may be very confusing: we end up with multiple references to the same elements sitting in completely different places.

    We can argue that repeated declarations and queries shouldn’t be such a big deal with proper file compression enabled, at least as long as we’re referring to performance. We can also merge multiple queries and optimize your code with post-processing tools. But wouldn’t it be easier to avoid these issues altogether?

    There’s a lot of ways to avoid the issues listed above. One of them, that we will explore in this article, is to use CSS custom properties.

    Using CSS variables for property values

    There are plenty of amazing articles on the web explaining the concept of CSS custom properties. If you haven’t got chance to get familiar with them yet, I would recommend starting with one of the beginner articles on this topic such as this awesome piece by Serg Hospodarets as we are not going to get into details of the basic usage in this article.

    The most common way of utilizing CSS custom properties in responsive design is to use variables to store values that change inside of media queries. To accomplish this, declare a variable that holds a value that is supposed to change, and then reassign it inside of a media query:

    :root { --responsive-padding: 1rem; } @media (min-width: 576px) { :root { --responsive-padding: 2rem; } } .foo { padding: var(--responsive-padding); }

    Assigning variables to the :root selector is not always a good idea. Same as in JavaScript, having many global variables is considered a bad practice. In real life, try to declare the custom properties in the scope they will actually be used.

    This way, we are avoiding multiple rules of the .foo class. We are also separating the logic (changing values) from the actual designs (CSS declarations). Adapting this approach in our example from above gives us the following CSS:

    .post { --post-vertical-padding: 0.5rem; --post-horizontal-padding: 1rem; --post-top-margin: 0.5rem; --post-bottom-margin: 1rem; --heading-font-size: 2rem; } @media (min-width: 576px) { .post { --post-vertical-padding: 1rem; --post-horizontal-padding: 2rem; --post-top-margin: 1rem; --post-bottom-margin: 2rem; --heading-font-size: 3rem; } } .post { padding: var(--post-vertical-padding) var(--post-horizontal-padding); margin: var(--post-top-margin) auto var(--post-bottom-margin); } .heading { font-size: var(--heading-font-size); }

    See the Pen
    #2 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Notice that the use of variables in shorthand properties (e.g. padding, margin or font) allow some very interesting repercussions. As custom properties may hold almost any value (more on this later), even an empty string, it’s unclear how the value of a shorthand property will be separated out into longhand properties that are used in the cascade later. For example, the auto used in the margin property above may turn out to be a top-and-bottom margin, a left-and-right margin, a top margin, a right margin, a bottom margin or a left margin — it all depends on the values of the custom properties around.

    It’s questionable whether the code looks cleaner than the one from the previous example, but on a larger scale, it’s definitely more maintainable. Let’s try to simplify this code a bit now.

    Notice that some values are repeated here. What if we try to merge duplicate variables together? Let’s consider the following alteration:

    :root { --small-spacing: 0.5rem; --large-spacing: 1rem; --large-font-size: 2rem; } @media (min-width: 576px) { :root { --small-spacing: 1rem; --large-spacing: 2rem; --large-font-size: 3rem; } } .post { padding: var(--small-spacing) var(--large-spacing); margin: var(--small-spacing) auto var(--large-spacing); } .heading { font-size: var(--large-font-size); }

    See the Pen
    #3 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    It looks cleaner but is it actually better? Not necessarily. For the sake of flexibility and readability, this may not be the right solution in every case. We definitely shouldn’t merge some variables just because they accidentally turned out to hold the same values. Sometimes, as long as we’re doing this as a part of a well thought out system, it may help us simplify things and preserve consistency across the project. However, in other cases, such a manner may quickly prove to be confusing and problematic. Now, let’s take a look at yet another way we can approach this code.

    Using CSS variables as multipliers

    CSS custom properties are a fairly new feature to the modern web. One of the other awesome features that rolled out in the last years is the calc() function. It lets us perform real math operations in live CSS. In terms of the browser support, it’s supported in all browsers that support CSS custom properties.

    calc() tends to play very nicely with CSS variables, making them even more powerful. This means we can both use calc() inside custom properties and custom properties inside calc()!

    For example, the following CSS is perfectly valid:

    :root { --size: 2; } .foo { --padding: calc(var(--size) * 1rem); /* 2 × 1rem = 2rem */ padding: calc(var(--padding) * 2); /* 2rem × 2 = 4rem */ }

    Why does this matter to us and our responsive designs? It means that we can use a calc() function to alter CSS custom properties inside media queries. Let’s say we have a padding that should have a value of 5px on mobile and 10px on desktop. Instead of declaring this property two times, we can assign a variable to it and multiply it by two on larger screens:

    :root { --padding: 1rem; --foo-padding: var(--padding); } @media (min-width: 576px) { :root { --foo-padding: calc(var(--padding) * 2); } } .foo { padding: var(--foo-padding); }

    Looks fine, however all the values (--padding, calc(--padding * 2)) are away from their declaration (padding). The syntax may also be pretty confusing with two different padding variables (--padding and --foo-padding) and an unclear relationship between them.

    To make things a bit clearer, let’s try to code it the other way around:

    :root { --multiplier: 1; } @media (min-width: 576px) { :root { --multiplier: 2; } } .foo { padding: calc(1rem * var(--multiplier)); }

    This way, we accomplished the same computed output with much cleaner code! So, instead of using a variable for an initial value of the property (1rem), a variable was used to store a multiplier (1 on small screens and 2 on larger screens). It also allows us to use the --multiplier variable in other declarations. Let’s apply this technique to paddings and margins in our previous snippet:

    :root { --multiplier: 1; } @media (min-width: 576px) { :root { --multiplier: 2; } } .post { padding: calc(.5rem * var(--multiplier)) calc(1rem * var(--multiplier)); margin: calc(.5rem * var(--multiplier)) auto calc(1rem * var(--multiplier)); }

    Now, let’s try to implement the same approach with typography. First, we’ll add another heading to our designs:

    <h1 class="heading-large">My Blog</h1> <article class="post"> <h2 class="heading-medium">Post's heading</h2> <p class="paragraph"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium numquam adipisci recusandae officiis dolore tenetur, nisi, beatae praesentium, soluta ullam suscipit quas? </p> </article>

    With multiple text styles in place, we can use a variable to control their sizes too:

    :root { --headings-multiplier: 1; } @media (min-width: 576px) { :root { --headings-multiplier: 3 / 2; } } .heading-medium { font-size: calc(2rem * var(--headings-multiplier)) } .heading-large { font-size: calc(3rem * var(--headings-multiplier)) }

    You may have noticed that 3 / 2 is not a valid CSS value at all. Why does it not cause an error then? The reason is that the syntax for CSS variables is extremely forgiving, which means almost anything can be assigned to a variable, even if it’s not a valid CSS value for any existing CSS property. Declared CSS custom properties are left almost entirely un-evaluated until they are computed by a user agent in certain declarations. So, once a variable is used in a value of some property, this value will turn valid or invalid at the computed-value time.

    Oh, and another note about that last note: in case you’re wondering, I used a value of 3 / 2 simply to make a point. In real life, it would make more sense to write 1.5 instead to make the code more readable.

    Now, let’s take a look at the finished live example combining everything that we discussed above:

    See the Pen
    #4 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Again, I would never advocate for combining calc() with custom properties to make the code more concise as a general rule. But I can definitely imagine scenarios in which it helps to keep code more organized and maintainable. This approach also allows the weight of CSS to be significantly reduced, when it’s used wisely.

    In terms of readability, we can consider it more readable once the underlying rule is understood. It helps to explain the logic and relations between values. On the other hand, some may see it as less readable, because it’s tough to instantly read what a property holds as a value without first doing the math. Also, using too many variables and calc() functions at once may unnecessarily obscure code and make it harder to understand, especially for juniors and front-end developers who are not focused on CSS.

    Conclusion

    Summing up, there’s a lot of ways to use CSS custom properties in responsive design, definitely not limited to the examples shown above. CSS variables can be used simply to separate the values from the designs. They can also be taken a step further and be combined with some math. None of the presented approaches is better nor worse than the others. The sensibility of using them depends on the case and context.

    Now that you know how CSS custom properties can be used in responsive design, I hope you will find a way to introduce them in your own workflow. Next up, we’re going to look at approaches for using them in reusable components and modules, so let's check that out.

    The post Responsive Designs and CSS Custom Properties: Defining Variables and Breakpoints appeared first on CSS-Tricks.

    Using CSS Grid the right way

    Css Tricks - Fri, 02/22/2019 - 12:59pm

    Violet Peña has shared her recommendations for using CSS Grid. They basically boil down to these high-level points:

    1. Use names instead of numbers for setting up our grid columns.
    2. fr should be our flexible unit of choice.
    3. We don’t really need a grid system anymore.

    Although this is all great advice and Violet provides a few examples to support her recommendations, I particularly like what she has to say about learning CSS Grid:

    “Learning” CSS Grid requires developing working knowledge of many new properties that don’t just describe one aspect of appearance or behavior, but feed into a completely new layout system. This system includes around 18 properties which use paradigms and syntax rarely (or never) seen anywhere else in the CSS spec.

    This means that CSS Grid has a pretty high skill floor — a developer needs to learn and internalize lots of new information in order to be effective with it. Once you’re above that skill floor, Grid is an amazing ally in layout creation. Below that skill floor, Grid is an encumbrance. You wonder why you’re bothering to use it at all, since it seems to require lots of additional work for little reward.

    In this post, I want to help you overcome that skill floor by showing you the most effective ways to leverage the Grid spec.

    Also this post reminded me that, although I’m not sure why, I tend to avoid naming my grid columns up. Like in this bit of code that Violet walks us through:

    .container { display: grid; grid-template-columns: [sidebar] 3fr [content] 4fr; }

    Now we can use the sidebar or content names when we define our grid-column like this:

    .content { grid-column: content; }

    I really like that! It seems super easy to read and if we wanted to change the size of our .content, class then it only requires going back to where the grid is defined in the first place. Anyway, I’ll be sure to name my grid columns from here on out.

    Direct Link to ArticlePermalink

    The post Using CSS Grid the right way appeared first on CSS-Tricks.

    Writing Animations That Bring Your Site to Life

    Css Tricks - Fri, 02/22/2019 - 7:36am

    Web animation is one of the factors that can strongly enhance your website’s look and feel. Sadly, unlike mobile apps, there aren’t as many websites using animation to their benefit as you would think. We don’t want to count yours among those, so this article is for you and anyone else looking for ways to use animation for a better user experience! Specifically, we’re going to learn how to make web interactions delightful using CSS animations.

    Here’s what we’re going to build together:

    Live Demo GitHub Repo

    Before we move ahead, it’s worth mentioning that I’m going to assume you have at least some familiarity with modern front-end frameworks and a basic understanding of CSS animations. If you don’t, then no fear! CSS-Tricks has a great guides on React and Vue, as well as a thorough almanac post on the CSS animation property.

    Good? OK, let’s talk about why we’d want to use animation in the first place and cover some baseline information about CSS animations.

    Why would we to animate anything?

    We could probably do an entire post on this topic alone. Oh, wait! Sarah Drasner already did that and her points are both poignant and compelling.

    But, to sum things up based on my own experiences:

    • Animations enhance the way users interact with an interface. For example, smart animations can reduce cognitive load by giving users better context between page transitions.
    • They can provide clear cues to users, like where we want them to focus attention.
    • Animations serve as another design pattern in and of themselves, helping users to get emotionally attached to and engage with the interface.
    • Another benefit of using animations is that they can create a perception that a site or app loads faster than it actually does.
    A couple of house rules with animations

    Have you ever bumped into a site that animates all the things? Wow, those can be jarring. So, here’s a couple of things to avoid when working with animations so our app doesn’t fall into the same boat:

    • Avoid animating CSS properties other than transform and opacity. If other properties have to be animated, like width or height, then make sure there aren’t a lot of layout changes happening at the same time. There’s actually a cost to animations and you can see exactly how much by referring to CSS Triggers.
    • Also, just because animations can create perceived performance gains, there’s actually a point of diminishing return when it comes to using them. Animating too many elements at the same time may result in decreased performance.

    Now we can get our hands dirty with some code!

    Let’s build a music app

    We’re going to build the music app we looked at earlier, which is inspired by Aurélien Salomon’s Dribbble shot. I chose this example so that we can focus on animations, not only within a component, but also between different routes. We’ll build this app using Vue and create animations using vanilla (i.e. no framework) CSS.

    Animations should go hand-in-hand with UI development. Creating UI before defining their movement is likely to cost much more time. In this case, the Dribbble shot provides that scope for us.

    Let’s start with the development.

    Step 1: Spin up the app locally

    First things first. We need to set up a new Vue project. Again, we’re assuming some base-level understanding of Vue here, so please check out the Learning Vue guide for more info on setting up.

    We need a couple of dependencies for our work, notably vue-router for transitioning between views and sass-loader so we can write in Sass and compile to CSS. Here’s a detailed tutorial on using routes and Sass can be installed by pointing the command line at the project directory and using npm install -D sass-loader node-sass.

    We have what we need!

    Step 2: Setting up routes

    For creating routes, we’re first going to create two bare minimum components — Artists.vue and Tracks.vue. We’ll drop a new file in the src folder called router.js and add routes for these components as:

    import Vue from 'vue' import Router from 'vue-router' import Artists from './components/Artists.vue' import Tracks from './components/Tracks.vue' Vue.use(Router) export default new Router({ mode: 'history', routes: [ { path: '/', name: 'artists', component: Artists }, { path: '/:id', name: 'tracks', component: Tracks } ] })

    Import router.js into the main.js and inject it to the Vue instance. Lastly, replace the content of your App.vue by <router-view/>.

    Step 3: Create the components and content for the music app

    We need two components that we’ll transition between with animation. Those are going to be:

    1. Artists.vue: a grid of artists
    2. Tracks.vue: An artist image with a back button

    If you wanna jump ahead a bit, here are some assets to work with:

    1. Images and sample data in JSON format.
    2. Content for the components

    When all is said and done, the two views will come out to something like this:

    Artists.vue (left) and Tracks.vue (right) Step 4: Animate!

    Here we are, the part we’ve really wanted to get to all this time. The most important animation in the app is transitioning from Artists to Tracks when clicking on an artist. It should feel seamless where clicking on an artist image puts that image in focus while transitioning from one view into the next. This is exactly the type of animation that we rarely see in apps but can drastically reduce cognitive load for users.

    To make sure we’re all on the same page, we’re going to refer to the first image in the sequence as the “previous” image and the second one as the "current" image. Getting the effect down is relatively easy as long as we know the dimensions and position of the previous image in the transition. We can animate the current image by transforming it as per previous image.

    The formula that I’m using is transform: translate(x, y) scale(n), where n is equal to the size of previous image divided by the size of current image. Note that we can use a static value of n since the dimensions are fixed for all the images. For example, the image size in the Artists view is 190x190 and 240x240 in the Tracks view. Thus, we can replace n by 190/240 = 0.791. That means the transform value becomes translate(x, y) scale(0.791) in our equation.

    Animating from Artists to Tracks

    Next thing is to find x and y. We can get these values though click event in the Artists view as:

    const {x, y} = event.target.getBoundingClientRect()

    ...and then send these values to the Tracks view, all while switching the route. Since we aren’t using any state management library, the two components will communicate via their parent component, which is the top level component, App.vue. In App.vue, let’s create a method that switches the route and sends the image info as params.

    gotoTracks(position, artistId) { this.$router.push({ name: 'tracks', params: { id: artistId, position: position } }) }

    Here’s the relevant code from the repo to reference, in case you’re interested.

    Since we have received the position and ID of the image in Tracks, we have all the required data to show and animate it. We’ll first fetch artist information (specifically the name and image URL) using artist ID.

    To animate the image, we need to calculate the transform value from the image’s starting position. To set the transform value, I’m using CSS custom properties, which can be done with CSS-in-JS techniques as well. Note that the image’s position that we received through props will be relative to window. Therefore we’ll have to subtract some fixed offset caused by the padding of the container <div> to even out our math.

    const { x, y } = this.$route.params.position // padding-left const offsetLeft = 100 // padding-top const offsetTop = 30 // Set CSS custom property value document.documentElement.style.setProperty( '--translate', `translate(${x - offsetLeft}px, ${y - offsetTop}px) scale(0.792)` )

    We’ll use this value to create a keyframe animation to move the image:

    @keyframes move-image { from { transform: var(--translate); } }

    This gets assigned to the CSS animation:

    .image { animation: move-image 0.6s; }

    ...and it will animate the image from this transform value to its original position on component load.

    Transitioning from Artists to Tracks

    We can use the same technique when going the opposite direction, Tracks to Artists. As we already have the clicked image’s position stored in the parent component, we can pass it to props for Artists as well.

    Transitioning from Tracks to Artists Step 5: Show the tracks!

    It’s great that we can now move between our two views seamlessly, but the Tracks view is pretty sparse at the moment. So let’s add the track list for the selected artist.

    We’ll create an empty white box and a new keyframe to slide it upwards on page load. Then we’ll add three subsections to it: Recent Tracks, Popular Tracks, and Playlist. Again, if you want to jump ahead, feel free to either reference or copy the final code from the repo.

    The Tracks view with content

    Recent Tracks is the row of thumbnails just below the artist image where each thumbnail includes the track name and track length below it. Since we’re covering animations here, we’ll create a scale-up animation, where the image starts invisible (opacity: 0) and a little smaller than it’s natural size (scale(0.7)), then is revealed (opacity: 1 )and scales up to its natural size (transform: none).

    .track { opacity: 0; transform: scale(0.7); animation: scale-up 1s ease forwards; } @keyframes scale-up { to { opacity: 1; transform: none; } }

    The Popular Tracks list and Playlist sit side-by-side below the Recent Tracks, where Popular tracks takes up most of the space. We can slide them up a bit on initial view with another set of keyframes:

    .track { ... animation: slide-up 1.5s; } @keyframes slide-up { from { transform: translateY(140px); } }

    To make the animation feel more natural, we’ll create a stagger effect by adding an incremental animation delay to each item.

    @for $i from 1 to 5 { &:nth-child(#{$i + 1}) { animation-delay: #{$i * 0.05}s; } }

    The code above is basically looking for each child element, then adding a 0.05 second delay to each element it finds. So, for example, the first child gets a 0.05 second delay, the second child gets a 0.10 second delay and so on.

    Check out how nice and natural this all looks:

    Bonus: micro-interactions!

    One of the fun things about working with animations is thinking through the small details because they’re what tie things together and add delight to the user experience. We call these micro-interactions and they serve a good purpose by providing visual feedback when an action is performed.

    Depending on the complexity of the animations, we might need a library like anime.js or GSAP. This example is pretty straightforward, so we can accomplish everything we need by writing some CSS.

    First micro-interaction: The volume icon

    Let’s first get a volume icon in SVG format (Noun Project and Material Design are good sources). On click, we’ll animate-in and out its path element to show the level of volume. For this, we’ll create a method which switches its CSS class according to the volume level.

    <svg @click="changeVolume"> <g :class="`level-${volumeLevel}`"> <path d="..."/> <!-- volume level 1 --> <path d="..."/> <!-- volume level 2 --> <path d="..."/> <!-- volume level 3 --> <polygon points="..."/> </g> </svg>

    Based on this class, we can show and hide certain path elements as:

    path { opacity: 0; transform-origin: left; transform: translateX(-5px) scale(0.6); transition: transform 0.25s, opacity 0.2s; } .level-1 path:first-child, .level-2 path:first-child, .level-2 path:nth-child(2), .level-3 path { opacity: 1; transform: none; } The animated volume control Second micro-interaction: The favorite icon

    Do you like it when you click on Twitter’s heart button? That’s because it feels unique and special by the way it animates on click. We’ll make something similar but real quick. For this, we first get an SVG heart icon and add it to the the markup. Then we’ll add a bouncy animation to it that’s triggered on click.

    @keyframes bounce { 0%, 100% { transform: none; } 30% { transform: scale(1.3); } 60% { transform: scale(0.9); } }

    Another fun thing we can do is add other small heart icons around it with random sizes and positions. Ideally, we’d add a few absolute-positioned HTML elements that a heart as the background. Let’s Arrange each of them as below by setting their left and bottom values.

    We’ll also include a fade away effect so the icons appear to dissolve as they move upward by adding a keyframe animation on the same click event.

    @keyframes float-upwards { 0%, 100% { opacity: 0; } 50% { opacity: 0.7; } 50%, 100% { transform: translate(-1px, -5px); } } The animated favorite button Summing up

    That’s all! I hope you find all this motivating to try animations on your own websites and projects.

    While writing this, I also wanted to expand on the fundamental animation principles we glossed over earlier because I believe that they help choose animation durations, and avoid non-meaningful animations. That’s important to discuss because doing animations correctly is better than doing them at all. But this sounds like a whole another topic to be covered in a future article.

    The post Writing Animations That Bring Your Site to Life appeared first on CSS-Tricks.

    Syndicate content
    ©2003 - Present Akamai Design & Development.