Tag: Code

Editing HTML Like A Boss In VS Code

Here’s a seven minute video from Caleb Porzio that focuses on some of Emmet‘s HTML editing features. You might think of Emmet as that thing that expands abbreviations like table.stats>tr*3>td*3 into glorious, expanded, and perfect HTML. But Emmet has other HTML editing trickery up its sleeve. My favorite is “wrap with abbreviation” (which happens to be Cmd/Ctrl + Shift + A on CodePen), but there are more, like expanding your selection inward and outward and tag changing.

If you haven’t seen it, the Emmet 2 preview on CodePen is pretty neeeeat. It shows you what you’re about to expand into before you do it:

Direct Link to ArticlePermalink


The post Editing HTML Like A Boss In VS Code appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , ,

How to Simplify SVG Code Using Basic Shapes

There are different ways to work with icons, but the best solution always includes SVG, whether it’s implemented inline or linked up as an image file. That’s because they’re “drawn” in code, making them flexible, adaptable, and scalable in any context.

But when working with SVG, there’s always the chance that they contain a lot of unnecessary code. In some cases, the code for an inline SVG can be long that it makes a document longer to scroll, uncomfortable to work with, and, yes, a little bit heavier than it needs to be.

We can work around this reusing chunks of code with the <use> element or apply native variables to manage our SVG styles from one place. Or, if we’re working in a server-side environment, we can always sprinkle in a little PHP (or the like) to extract the contents of the SVG file instead of dropping it straight in.

That’s all fine, but wouldn’t be great if we could solve this at the file level instead of resorting to code-based approaches? I want to focus on a different perspective: how to make the same figures with less code using basic shapes. This way, we get the benefits of smaller, controllable, and semantic icons in our projects without sacrificing quality or visual changes. I’ll go through different examples that explore the code of commonly used icons and how we can redraw them using some of the easiest SVG shapes we can make.

Here are the icons we’ll be working on:

Showing an close icon in the shape of an x, a clock with the hands pointing at 3 o-clock, and a closed envelope.

Let’s look at the basic shapes we can use to make these that keep the code small and simple.

Psssst! Here is a longer list of simple icons I created on holasvg.com! After this article, you’ll know how to modify them and make them your own.

Simplifying a close icon with the <line> element

This is the code for the “close” or “cross” icon that was downloaded from flaticon.com and built by pixel-perfect:

In this example, everything is happening inside the <path> with lots of commands and parameters in the data attribute (d). What this SVG is doing is tracing the shape from its borders.

A quick demonstration using mavo.io

If you are familiar with Illustrator, this is the equivalent of drawing two separate lines, converting them to shape, then combining both with the pathfinder to create one compound shape.

The <path> element allows us to draw complex shapes, but in this case, we can create the same figure with two lines, while keeping the same appearance:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50" overflow="visible" stroke="black" stroke-width="10" stroke-linecap="round">    <line x1="0" y1="0" x2="50" y2="50" />    <line x1="50" y1="0" x2="0" y2="50" /> </svg>

We started by defining a viewBox that goes from 0,0 to 50,50. You can choose whatever dimensions you prefer; the SVG will always scale nicely to any width and height you define. To make things easier, in this case, I also defined an inline width and height of 50 units, which avoids extra calculations in the drawing.

To use the <line> element, we declare the coordinates of the line’s first point and the coordinates of its last point. In this specific case, we started from x=0 y=0 and ended at x=50 y=50.

Grid of the coordinate system.

Here’s how that looks in code:

<line x1="0" y1="0" x2="50" y2="50" />

The second line will start from x=50 y=0 and end at x=0 y=50:

<line x1="50" y1="0" x2="0" y2="50" />

An SVG stroke doesn’t have a color by default — that’s why we added the black value on the stroke attribute. We also gave the stroke-width attribute a width of 10 units and the stroke-linecap a round value to replicate those rounded corners of the original design. These attributes were added directly to the <svg> tag so both lines will inherit them.

<svg ... stroke="black" stroke-width="10" stroke-linecap="round" ...>

Now that the stroke is 10 units bigger that its default size of 1 unit, the line might get cropped by the viewBox. We can either move the points 10 units inside the viewBox or add overflow=visible to the styles.

The values that are equal to 0 can be removed, as 0 is the default. That means the two lines end up with two very small lines of code:

<line x2="50" y2="50" /> <line x1="50" y2="50" />

Just by changing a <path> to a <line>, not only did we make a smaller SVG file, but a more semantic and controllable chunk of code that makes any future maintenance much easier. And the visual result is exactly the same as the original.

Same cross, different code.

Simplifying a clock icon with the <circle> and <path> elements

I took this example of a clock icon created by barracuda from The Noun Project:

This shape was also drawn with a <path>, but we also have a lot of namespaces and XML instructions related to the software used and the license of the file that we can delete without affecting the SVG. Can you tell what illustration editor was used to create the icon?

Let’s recreate this one from scratch using a circle and a path with simpler commands. Again, we need to start with a viewBox, this time from 0,0 to 100,100, and with a width and height matching those units.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100" fill="none" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round">   <circle cx="50" cy="50" r="40"/>   <path d="M50 25V50 H75" />  </svg>

We keep the same styles as the previous icon inside the <svg> tag. fill is black by default, so we need to explicitly give it a none value to remove it. Otherwise, the circle will have have a solid black fill, obscuring the other shapes.

To draw the <circle> we need to indicate a center point from where the radius will sit. We can achieve that with cx (center x) and cy (center y). Then r (radius) will declare how big our circle will be. In this example, the radius is slightly smaller than the viewBox, so it doesn’t get cropped when the stroke is 10 units wide.

What’s up with all those letters? Check out Chris Coyier’s illustrated guide for a primer on the SVG syntax.

We can use a <path> for the clock hands because it has some very useful and simple commands to draw. Inside the d (data) we must start with the M (move to) command followed by the coordinates from where we’ll start drawing which, in this example, is 50,25 (near the top-center of the circle). 

After the V (vertical) command, we only need one value as we can only move up or down with a negative or positive number. A positive number will go down. The same for H (horizontal) followed by a positive number, 75, that will draw toward the right. All commands are uppercase, so the numbers we choose will be points in the grid. If we decided to use lowercase (relative commands) the numbers will be the amount of units that we move in one direction and not an absolute point in the coordinate system.

Same clock, different code.

Simplifying an envelope icon with the <rect> and <polyline> elements

I drew the envelope icon in Illustrator without expanding the original shapes. Here’s the code that came from the export:

Illustrator offers some SVG options to export the graphic. I chose “Style Elements” in the “CSS Properties” dropdown so I can have a <style> tag that contains classes that I might want to move to a CSS file. But there are different ways to apply the styles in SVG, of course.

We already have basic shapes in this code! I unselected the “Shape to paths” option in Illustrator which helped a lot there. We can optimize this further with SVGOMG to remove the comments, XML instructions, and unnecessary data, like empty elements. From there, we can manually remove other extras, if we need to.

We already have something a little more concise:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190" xml:space="preserve">   <style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}   </style><rect x="5" y="5" class="st0" width="300" height="180"/>   <polyline class="st0" points="5 5 155 110 305 5"/> </svg>

We can remove even more stuff without affecting the visual appearance of the envelope, including: 

  • version="1.1" (this has been deprecated since SVG 2)
  • id="Layer_1" (this has no meaning or use)
  • x="0" (this is a default value)
  • y="0" (this is a default value)
  • xml:space="preserve" (this has been deprecated since SVG 2)
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190">   <style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}   </style>   <rect x="5" y="5" class="st0" width="300" height="180"/>   <polyline class="st0" points="5 5 155 110 305 5"/> </svg>

We can move the CSS styles to a separate stylesheet if we really want to get really aggressive.

<rect> needs a starting point from where we’ll extend a width and a height, so let’s use  x="5" and y="5" which is our top-left point. From there, we will create a rectangle that is 300 units wide with a height of 180 units. Just like the clock icon, we’ll use 5,5 as the starting point because we have a 10-unit stroke that will get cropped if the coordinates were located at 0,0.

<polyline> is similar to <line>, but with an infinite amount of points that we define, like pairs of coordinates, one after the other, inside the points attribute, where the first number in the pair will represent x and the second will be y. It’s easier to read the sequence with commas, but those can be replaced with whitespace without having an impact on the result.

Same envelope, different code.

Bonus shapes!

I didn’t include examples of icons that can be simplified with <polygon> and <ellipse> shapes, but here is a quick way to use them.

<polygon> is the same as <polyline>, only this element will always define a closed shape. Here’s an example that comes straight from MDN:

Remember the circle we drew earlier for the clock icon? Replace the r (radius) with rx and ry. Now you have two different values for radius. Here’s another example from MDN:

Wrapping up

We covered a lot here in a short amount of time! While we used examples to demonstrates the process of optimizing SVGs, here’s what I hope you walk away with from this post:

  • Remember that compression starts with how the SVG is drawn in illustration software.
  • Use available tools, like SVOMG, to compress SVG.
  • Remove unnecessary metadata by hand, if necessary.
  • Replace complex paths with basic shapes.
  • <use> is a great way to “inline” SVG as well as for establishing your own library of reusable icons.

How many icons can be created by combining these basic shapes? 

I’m working my list on holasvg.com/icons, I’ll be constantly uploading more icons and features here, and now you know how to easily modified them just by changing a few numbers. Go ahead and make them yours!


The post How to Simplify SVG Code Using Basic Shapes appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , ,
[Top]

Want to get better at code? Teach someone CSS.

A friend of mine recently asked me to teach her to code. She was an absolute beginner, having no idea what coding really involves. I decided to start where I started: HTML and CSS. Using CodePen, we started forking Pens and altering them. Soon, a learning path started to unravel.

The aim of this article is not to teach basic CSS to those who already know it but rather to highlight the things that inspired a newcomer and hopefully inspire you to pass on some knowledge to others if the opportunity arises. It felt good to help someone out and, in turn, I learned some really valuable lessons that have changed the way I think about my code. Win win!

So, here we go: five lessons I learned from teaching someone CSS.

Lesson 1: Don’t start from scratch

When I starting coding for the web 12 years ago, I began with layout — positioning with floats, margins, padding and position declarations. It might seem outdated these days, but still, this is where I went right away with my new coding buddy.

It didn’t go that well.

As you might guess, starting with something like, “Here is how to position an empty box in the middle of the screen,” was a mistake. How uninspiring! And even though I was impressed with my own ability to demonstrate how Flexbox can position an element in the center of the screen (more on that later), I was immediately faced with lots of additional, non-positional questions.

“So how do you change the colors?”

“Can it change shape when hovered over?”

“What fonts can you use on the web?”

I thought we were weeks away from all that.

So, my plans of teaching the 12-column grid went out the window and we pulled up Chris’ named color chart alongside a couple of forked Pens and started playing around. First off, we changed the colors of Cassidy Williams Netflix/Netlify logo. Wow! Instant hit.

<a class="container" href="https://netlify.com" target="_blank">    <div class="logo">     <div class="uno"></div>     <div class="dos"></div>     <div class="tres"></div>   </div>   <div class="name">Prettier</div> </a>

Then a few simple tweaks to the CSS:

body {   background: #F9F2DB;   color: #092935;   font-size: 50px; } 
 a {   color: #092935; } 
 .logo .uno, .dos, .tres {   background: #C61561; }  .logo .dos {   box-shadow: 0 0 20px #F9F2DB; }  .logo::before {   background: #F9F2DB; } 
 .name {   letter-spacing: 8px; }

Within minutes, my friend was hooked! There was no boring positioning to worry about, just a clear example of how a few simple lines of code can change something so familiar into something entirely different.

Then it kicked in that you can change the color of anything! We loaded up a couple of well known sites in the browser and changed the colors of some text and backgrounds with DevTools, all in a couple of minutes. Mission accomplished! My friend was hooked. 

Lesson learned: Don’t worry about trying to build something from scratch. Have a play with what’s already out there! 

Lesson 2: Comments

This isn’t where I had planned to go with my planned class, but the question of why some parts of CSS start with /* and end with */ came up, so we went with it. 

This one really had me thinking about my own work. I really do not comment my code enough. Watching a new coder comment everything (and I mean everything) reminded me just how helpful comments are, not only for yourself, but also to a wider team, or even future you. (Sarah Drasner has a great talk on this topic).

And here is the thing: until then, I thought I was commenting pretty diligently. However, watching someone else do it made me realize how many times I look at a piece of code (particularly JavaScript) and wish I had put a line or two in there to remind myself what I was doing. A ten-second task might have saved me five (or perhaps even more) minutes down the road. That adds up and is now something I am working on.

Lesson learned: Comment more. 

Lesson 3: Positioning

We started with some basic HTML, and honestly, I saw my friend’s eyes glazing over almost immediately. It just looks so dull when you can’t see it doing anything right away (unlike editing pre-written CSS). However, we stuck with it, and got results.

Take my word for it, don’t start by positioning empty <div> elements with 1-pixel borders around them. You’ll lose your audience very quickly. Put a picture of a dog in there — or baby Yoda or a pizza — just as long as it’s anything other than an empty element.

We then turned to Flexbox. We actually found CSS Grid a bit too much at the start. We looked briefly at CSS Grid, but when reading lots of articles about it, it’s clear that many assume the reader already has familiarity with CSS, Flexbox in particular. My friend decided to start with Flexbox.

An admission on my part: I am so used to using UI frameworks (especially Bootstrap) that I very rarely position anything in Flexbox by writing the CSS myself. I know how it works and (most of) the declarations, but I still very rarely write it out myself, even in situations where it would be relatively easy. Teaching made me think about my reliance on UI frameworks as a whole. Yes, they are undoubtedly amazing and save us tons of time on projects, but I recalled using Bootstrap on a recent project that was essentially two pages and probably didn’t need it! 

Lesson learned: If the project is something small with a minimal number of elements to position, then consider ditching the framework and code from scratch! The end result will be lightweight, fast, and way more satisfying!

Lesson 4: Typography

I love typography. I’ve been lucky enough to work with great designers over the past few years and that has really helped me dial in on the nuances of type. It’s amazing how changes to things like line-height and letter-spacing can really help lift a design from average to amazing. This was something I was keen to impress upon my eager new student. Well, I needn’t have bothered, as the only thing of interest (initially) was changing the fonts and then, crucially for me, the sheer number of fonts available for us to use. The choices are almost limitless and the services and foundries offering web fonts have exploded in the past few years to a point where anything is possible, at speed with little impact on load times.

But here is the thing about designers (and front-end developers like myself): we can be a bit narrow-minded in our font choices. Designs tend to stick to the same fonts from the same services (Roboto and Open Sans anyone?) because we know they are easy to implement and that they work. Exploring fonts with someone new to the trade forced me to look beyond the old staples and try a few new things. I’m now looking for new pairings that work together and dialing in on how they work on screen and impact the whole look and feel of a design. In short, teaching someone else about type has improved my own journey with type, which was probably stuck in something like 2017. 

Lesson learned: Keep up to date with type.

Lesson 5. :hover makes everything fun

Things were going OK up to this point, but as you can probably imagine, things were still pretty static. Without really planning, we stumbling into adding a hover effect on on an element and it was an instant hook, just like it was changing colors for the first time!

Hovers add interaction and easily impress, which makes them great for a newcomer to play around with. Scaling objects, changing a box from square to round, hiding content — these are the types of thing that can all be done so easily that hovers are an ideal way for a new coder to get instant results. And here’s the thing: “‘playing” around like this opens other doors. “What if I just do this?” is something many us rarely get to ask ourselves in our day-to-day jobs. With defined designs to work from, there is often little chance to play and equally less chance to experiment.

So, here is the final lesson: Make time to play. Just by being asked, “How do you make this thing do that?” has forced me to learn new things, see what’s new in CSS, and see what I can take back into my day-to-day work. Experimenting (or better yet, playing) has made me a better designer, and I’ll be doing more.

Lesson learned: Make time to play.

Conclusion

If my time teaching CSS to a newbie has taught me anything, it’s that I rarely write code from scratch anymore. Code snippets and autocomplete save me hours, but it’s those same conveniences that let me forget about some really basic stuff. Stuff I should know. By teaching someone else, even if just for 15 minutes now and then, my coding has generally improved and my eyes are open to new ideas and techniques that I may not have otherwise considered.

And as for my friend? Well, she was so taken by CSS in our short time together that she is now doing an online course that includes HTML, which doesn’t seem so dull now that she knows what it is capable of doing!


The post Want to get better at code? Teach someone CSS. appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,
[Top]

How to Disable Code: The Developer’s Production Kill Switch

The following is a guest post written by Carlos Schults.

Being able to disable code in production is a power that many developers aren’t aware of. And that’s a shame. The ability to switch off some portions—or even complete features—of the codebase can dramatically improve the software development process by allowing best practices that can shorten feedback cycles and increase the overall quality.

So, that’s what this post will cover: the mechanisms you can use to perform this switching off, why they’re useful and how to get started. Let’s dig in.

Why Would You Want to Disable Code?

Before we take a deep dive into feature flags, explaining what they are and how they’re implemented, you might be asking: Why would people want to switch off some parts of their codebase? What’s the benefit of doing that?

To answer these questions, we need to go back in time to take a look at how software was developed a couple of decades ago. Time for a history lesson!

The Dark Ages: Integration Hell

Historically, integration has been one of the toughest challenges for teams trying to develop software together. 

Picture several teams inside an organization, working separately for several months, each one developing its own feature. While the teams were working in complete isolation, their versions of the application were evolving in different directions. Now they need to converge again into a single, non conflicting version. This is a Herculean task. 

That’s what “integration hell” means: the struggle to merge versions of the same application that have been allowed to diverge for too long. 

Enter the Solution: Continuous Integration

“If it hurts, do it more often.” What this saying means is that there are problems we postpone solving because doing so is hard. What you often find with these kinds of problems is that solving them more frequently, before they accumulate, is way less painful—or even trivial.

So, how can you make integrations less painful? Integrate more often.

That’s continuous integration (CI) in a nutshell: Have your developers integrate their work with a public shared repository, at the very least once a day. Have a server trigger a build and run the automated test suite every time someone integrates their work. That way, if there are problems, they’re exposed sooner rather than later.

How to Handle Partially Completed Features

One challenge that many teams struggle with in CI is how to deal with features that aren’t complete. If developers are merging their code to the mainline, that means that any developments that take more than one day to complete will have to be split into several parts. 

How can you avoid the customer accessing unfinished functionality? There are some trivial scenarios with similarly trivial solutions, but harder scenarios call for a different approach: the ability to switch off a part of the code completely.

Feature Flags to the Rescue

Defining Feature Flags

There are many names for the mechanisms that allow developers to switch a portion of their code off and on. Some call them “feature toggles” or “kill switches.” But “feature flags” is the most popular name, so that’s what we’ll use for the remainder of this post. So, what are feature flags?

Put simply, feature flags are techniques that allow teams to change the behavior of an application without modifying the code. In general, flags are used to prevent users from accessing and using the changes introduced by some piece of code, because they’re not adequate for production yet for a number of reasons.

Disable Code: What Are the Use Cases?

We’ll now cover some of the most common use cases for disabling code in production.

Switching Off Unfinished Features

As you’ve seen, one of the main use cases for feature flags is preventing users from accessing features that aren’t ready for use yet.

That way, programmers developing features that are more complex and take a longer time to complete aren’t prevented from integrating their work often and benefiting from it.

Enabling A/B Testing

The adoption of feature flags enables the use of several valuable practices in the software development process, one of which is A/B testing

A/B testing is a user experience research technique that consists of comparing two versions of a website or application to decide which one to keep. It entails randomly splitting users into two groups, A and B, and then delivering a different version of the application to each group. One group might receive the current production version, which we call the “control,” whereas the second group would receive the candidate for the new version, called the “treatment.” 

The testers then monitor the behavior of both groups and determine which of the versions achieved better results. 

Feature flags are a practical way to enable A/B testing because they allow you to quickly and conveniently change between the control and treatment versions of your application.

Enabling Canary Releases

If you deliver the new version of your app to your entire userbase at once, 100 percent of your users will be impacted if the release is bad in some way. What if you could gradually roll out the new version instead? You’d first deploy to a small subset of users, monitoring that group to detect issues. If something went wrong, you could roll it back. If everything looked fine, you could then gradually release the version for larger groups. That’s a canary release in a nutshell. It’s another powerful technique that feature flags might help with.

Customizing Features According to Users’ Preferences

It’s not uncommon to have to customize your application according to the needs of specific users, and there are several ways in which software teams can accomplish that—some more efficient, and others less so (companies that create separate branches or entire repositories for each client come to mind).

This is another area where feature flags could help, allowing teams to dynamically switch between different versions of the same functionality.

Disable Code in Production 101

How do you go about disabling code? That’s what we’re going to see now, in three increasingly sophisticated phases.

First Stage: The Most Basic Approach

We start with an approach that’s so primitive, it maybe shouldn’t be considered a feature flag at all. Consider the pseudocode below:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {   // return calculateAdditionalWorkHoursSameOldWay(employee, start, end);   return calculateAdditionalWorkHoursImproved(employee, start, end); }

In the code above, we’re just commenting out the old version of some method and replacing it with a new version. When we want the older version to be used, we just do the opposite. (Well, I said it was primitive.) This approach lacks one of the most fundamental properties of a feature flag—the ability to change how the application behaves without changing its code.

However, it plants the seed for more sophisticated approaches.

Second Stage: Taking the Decision Out of the Code

The previous approach didn’t allow developers to select the desired version of the feature without changing the code. Fortunately, that’s not so hard to do. First, we introduce a logical variable to determine which version we’re going to use:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {    var result = useNewCalculation     ? calculateAdditionalWorkHoursImproved(employee, start, end)     : calculateAdditionalWorkHoursSameOldWay(employee, start, end);    return result; }

Then, we use some mechanism to be able to assign the value to the variable from an external source. We could use a configuration file:

var useNewCalculation = config[newCalculation];

Passing arguments to the application might be another option. What matters is that we now have the ability to modify how the app behaves from the outside, which is a great step toward “true” feature flagging.

Keep in mind that the code examples you see are all pseudocode. Using your favorite programming language, there’s nothing stopping you from starting with this approach and taking it up a notch. You could, for instance, use classes to represent the features and design patterns (e.g., factories) to avoid if statements.

Stage 3: Full-Fledged Feature Flag Management

The previous approach might be enough when your application has only a small number of flags. But as that number grows, things start to become messy.

First, you have the issue of technical debt. Manually implemented feature flags can create terribly confusing conditional flows in your codebase. That only grows worse with new flags being introduced each day. Additionally, they might make the code harder to understand and navigate, especially for more junior developers, which is an invitation for bugs.

Another problem is that as the number of flags grows, it becomes more and more common to forget to delete old, obsolete ones.

The main problem of a homegrown approach is that it doesn’t give you an easy way to see and manage all of your flags at once. That’s why our third and final stage is a single piece of advice: Instead of rolling out your own feature flags approach, adopt a third-party feature flag management system.

Feature Flags Are a CI/CD Enabler

We’ve covered the mechanisms developers can use to disable portions of their codebase in production without having to touch the code. This capability is powerful and enables techniques such as A/B testing and canary releases, which are all hallmarks of a modern, agile-based software development process.

The names for the techniques might vary—feature flags, feature toggles, feature flipper, and so on. The way in which the techniques are implemented can also vary—from a humble if statement to sophisticated cloud-based solutions.

But no matter what you call them, you can’t overstate the benefit these mechanisms offer. They’re an enabler of Continuous Integration, which is essential for any modern software organization that wants to stay afloat.

The post How to Disable Code: The Developer’s Production Kill Switch appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

My Visual Studio Code Setup: Extensions and Themes

Matthias Ott’s posted his VS Code setup. I find lists like this (I rounded up some recent updates of my own) irresistible, probably because, like y’all, I spend an awful lot of time in VS Code and wanna make sure I’m getting the most out of it.

Things from the list that stood out to me:

  • I didn’t realize Bracket Pair Colorizer had gone v2 and it’s a separate install.
  • I din’t realize you needed an extension to honor .editorconfig files.
  • I wasn’t using anything for PHP, but Matthias listed PHP Intelephense and I’m giving it a whirl. It has fewer users than the non-weirdly named one though? And when I installed that, I saw Format HTML in PHP which I’m also trying because, yes, please! (Even Prettier’s PHP add-on can’t do that.)

Messing with extensions is also a good opportunity to clear out old crap.

Also super interesting…

The main point of that series is cleaning up the interface of VS Code in extreme ways. All the way down to:

Direct Link to ArticlePermalink

The post My Visual Studio Code Setup: Extensions and Themes appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

Some Little Improvements to My VS Code Workflow (Workspaces, Icons, Tasks)

I did a little thing the other day that I didn’t know was possible until then. I had a project folder open in VS Code like I always do, and I added another different root folder to the window. I always assumed when you had a project open, it was one top level root folder and that’s it, if you needed another folder elsewhere open, you would open that in another window. But nope!

We kind of have a “duo repo” thing going on at CodePen (one is the main Ruby on Rails app, and one is our microservices), and now I can open them both together:

Multiple folders open at once. This means I don’t need to deal with my symlinks anymore.

Now I can search across both projects and basically just pretend like it’s one big project.

When you do that for the first time and then close the VS Code window, it will ask you if you want to save a “Workspace.” Meh, maybe later, I always thought. I knew what it meant, but I was too lazy to deal with it. It’ll make a file, I thought, and I don’t really have a place for files like that. (I’d avoid the repo itself, just because I don’t want to force my system on anyone else.)

Well, I finally got over it and did it. I chucked all my .code-workspace files into a local folder. They are actually quite useful as files, because I can put the files in my Dock and one-click open my Workspace just how I like it.

Custom Workspace icons

Workspace files have special little icons like this:

The icon is a little generic, but I like it. A document with a little tiny VS Code icon below it.

Since I’m putting these in my Dock, I saw that as a cool opportunity to make them into custom icons! That’ll make it super clear for me and a little more delightful to use since I’ll probably reach for them many times a day.

Taking a little inspiration from the original, I snagged the SVG logo and plopped it on the bottom-right of my project logos.

Changing logos on macOS is as simple as “Get Info” on the file, clicking the logo in that panel, then pasting the image.

Now I can keep them in my Dock and open everything with a single click:

Launch terminal commands when opening a project

Now that I have these really handy one-click icons for opening my projects, I thought, “How cool would it be if it kicked off the commands to start the project too!” Apparently, that’s what Tasks are for, and it wasn’t too hard to set up (thanks, Andrew!). Right next to that settings file, at .vscode/tasks.json, is where I have this:

{   "version": "2.0.0",   "tasks": [     {       "label": "Run Gulp",       "type": "shell",       "command": "gulp",       "task": "default",       "presentation": {         "focus": false,         "panel": "shared",         "showReuseMessage": true,         "clear": true       },       "runOptions": {         "runOn": "folderOpen"       }     }   ] } 

That kicks off the command gulp for me whenever I open this Workspace. I guess you have to run the task once manually (Terminal → Run Task) so that it has the right permissions, then it works from there on out.

Overrides

I don’t think this is specific to Workspaces necessarily, but I really like how you can have a file like .vscode/settings.json in a project folder to override VS Code settings for a particular project.

For example, here on CSS-Tricks, I have a super basic Sass setup where Gulp preprocesses .scss into .css. That’s all fine, but it’s likely that I’ll search for a selector at some point. I don’t need to see it in .css because I’m not working in vanilla CSS. Like ever. I can put this in that settings file, and know that it’s just for this project, rather than all my projects:

{   "search.exclude": {     "**/*.css": true,   } }

The post Some Little Improvements to My VS Code Workflow (Workspaces, Icons, Tasks) appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , ,
[Top]

Fake Code

Here’s a fun little idea from Knut Synstad. You give it the URL of a GitHub Gist and it converts the Gist into grayscale rounded blobs (SVG) that sorta look like code if you squint. Maybe fun for interesting dynamic backgrounds or for whatever you might use code-looking stock art for.

SVG blobs that look like code.

It reminded me of Christian Naths’s Redacted font, which turns every glyph into a box or squiggles.


And if you need some actual totally fake code, Harry Parton’s Pen is nice for that:

The post Fake Code appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Tips for Writing Animation Code Efficiently

I’ve been coding web animations and helping others do the same for years now. However, I have yet to see a concise list of tips focused on how to efficiently build animations, so here you go!

I will be using the GreenSock Animation Platform (GSAP). It provides a simple, readable API and solves cross-browser inconsistencies so that you can focus on animating. The code and concepts should be understandable even if you’ve never used GSAP. If you’d like to familiarize yourself with the basics of GSAP first so that you can get the most out of this article, the best place to begin is GSAP’s getting started page (includes a video). 

Tip #1: Use an animation library

Some developers think that using an animation library is wasteful because they can just use native browser technologies like CSS transitions, CSS animations or the Web Animations API (WAAPI) to accomplish the same thing without loading a library. In some cases, that’s true. However, here are a few other factors to consider:

  • Browser bugs, inconsistencies, and compatibility: An animation library, like GSAP, solves these for you and is universally compatible. You can even use motion paths in IE9! There are many problematic areas when it comes to cross-browser issues, including handling transform-origin on SVG elements, path stroke measurements, 3D origins in Safari, and many more that we don’t have the space to list.
  • Animation workflow: Building even moderately complex animations is much faster and more fun with a tool like GSAP. You can modularize animations, nest them as deeply as you want, and have their timing adjusted automatically. This makes it so much easier to experiment. Trust me: once you try building an animation sequence in CSS and then in GSAP, you’ll see what I mean. Night and day! Future edits are faster too.
  • Animate beyond the DOM: Canvas, WebGL, generic objects, and complex strings can’t be animated with native technologies. Using one consistent tool for all your animations is much cleaner. 
  • Runtime control: Using a good animation library can enable you to pause, resume, reverse, seek through, or even gradually change the speed of an entire animation sequence. You can control each transform component independently (rotation, scale, x, y, skew, etc.). You can also retrieve those values at any time as well. JavaScript animations give you ultimate flexibility.
  • Easing options (bounce, elastic, etc.): CSS only gives you two control points for eases. GSAP’s CustomEase lets you literally create any ease you can imagine. 
  • Lag smoothing: GSAP can prioritize absolute timing or adjust things on the fly to avoid jumps if the CPU gets bogged down.
  • Advanced capabilities: Using GSAP, it’s easy to morph SVGs, add physics/inertia, edit motion paths directly in the browser, use position-aware staggers, and more.

Most of the top animators in the industry use a tool like GSAP because they’ve learned these same things over the years. Once you get beyond very basic animations, a JavaScript library will make your life much, much easier and open up entirely new possibilities. 

Tip #2: Use timelines

A good animation library will provide some way of creating individual animations (called tweens) and a way to sequence animations in a timeline. Think of a timeline like a container for your tweens where you position them in relation to one another. 

const tl = gsap.timeline();  tl.to(".box", { duration: 1, x: 100 })   .to(".box", { duration: 1, backgroundColor: "#f38630" }, "+=0.5")    .to(".box", { duration: 1, x: 0, rotation: -360 }, "+=0.5") 

By default in GSAP, tweens added to a timeline will wait for the previous tweens to complete before running. The +=0.5 adds an additional offset or delay of a half-second as well, so the second tween will start 0.5 seconds after the first tween finishes no matter how long the first tween’s duration is.

To increase the amount of time between the tween to 1 second, all you need to do is change the +=0.5 to +=1! Super easy. With this approach, you can iterate on your animations quickly without worrying about doing the math to combine previous durations.

Tip #3: Use relative values

By “relative values” I mean three things:

  1. Animate values relative to their current value. GSAP recognizes += and -= prefixes for this. So x: "+=200" will add 200 units (usually pixels) to the current x. And x: "-=200" will subtract 200 from the current value. This is also useful in GSAP’s position parameter when positioning tweens relative to one another.
  2. Use relative units (like vw, vh and, in some cases, %) when values need to be responsive to viewport size changes.
  3. Use methods like .to() and .from() (instead of .fromTo()) whenever possible so that the start or end values are dynamically populated from their current values. That way, you don’t need to declare start and end values in every tween. Yay, less typing! For example, if you had a bunch of differently-colored elements, you could animate them all to black like gsap.to(".class", {backgroundColor: "black" }).

Tip #4: Use keyframes

If you find yourself animating the same target over and over in a row, that’s a perfect time to use keyframes! You do so like this:

gsap.to(".box", { keyframes: [   { duration: 1, x: 100 },   { duration: 1, backgroundColor: "#f38630", delay: 0.5 },    { duration: 1, x: 0, rotation: -360, delay: 0.5 } ]});

No timeline necessary! To space out the tweens we just use the delay property in each keyframe. (It can be negative to create overlaps.)

Tip #5: Use smart defaults

GSAP has default values for properties like ease ("power1.out") and duration (0.5 seconds). So, the following is a valid tween that will animate for half a second.

gsap.to(".box", { color: "black" })

To change GSAP’s global defaults, use gsap.defaults():

// Use a linear ease and a duration of 1 instead gsap.defaults({ ease: "none", duration: 1 });

This can be handy, but it’s more common to set defaults for a particular timeline so that it affects only its children. For example, we can avoid typing duration: 1 for each of the sub-tweens by setting a default on the parent timeline:

const tl = gsap.timeline({ defaults: { duration: 1 } });  tl.to(".box", { x: 100 })   .to(".box", { backgroundColor: "#f38630" }, "+=0.5")    .to(".box", { x: 0, rotation: -360 }, "+=0.5") 

Tip #6: Animate multiple elements at once

We mentioned this briefly in the third tip, but it deserves its own tip.

If you have multiple elements that share the same class of .box, the code above will animate all of the elements at the same time!

You can also select multiple elements with different selectors by using a more complex selector string:

gsap.to(".box, .circle", { ... });

Or you can pass an array of variable references as long as the elements are of the same type (selector string, variable reference, generic object, etc.):

var box = document.querySelector(".box"); var circle = document.querySelector(".circle");  // some time later… gsap.to([box, circle], { ... });

Tip #7: Use function-based values, staggers, and/or loops

Function-based values

Use a function instead of a number/string for almost any property, and GSAP will call that function once for each target when it first renders the tween. Plus, it’ll use whatever gets returned by the function as the property value! This can be really handy for creating a bunch of different animations using a single tween and for adding variance.

GSAP will pass the following parameters into the function:

  1. The index
  2. The specific element being affected
  3. An array of all of the elements affected by the tween

For example, you could set the movement direction based on the index:

Or you could choose items from an array:

Staggers

Make your animations look more dynamic and interesting by offsetting the start times with a stagger. For simple staggered offsets in a single tween, just use stagger: 0.2 to add 0.2 seconds between the start time of each animation.

You can also pass in an object to get more complex stagger effects, including ones that emanate outward from the center of a grid or randomize the timings:

For more information about GSAP’s staggers, check out the stagger documentation.

Loops

It can be helpful to loop through a list of elements to create or apply animations, particularly when they are based on some event, like a user’s interaction (which I’ll discuss later on). 

To loop through a list of items, it’s easiest to use .forEach(). But since this isn’t supported on elements selected with .querySelectorAll() in IE, you can use GSAP’s utils.toArray() function instead.

In the example below, we are looping through each container to add animations to its children that are scoped to that container.

Tip #8: Modularize your animations

Modularization is one of the key principles of programming. It allows you to build small, easy-to-understand chunks that you can combine into larger creations while still keeping things clean, reusable, and easy to modify. It also lets you to use parameters and function scope, increasing the re-usability of your code.

Functions

Use functions to return tweens or timelines and then insert those into a master timeline:

function doAnimation() {   // do something, like calculations, maybe using arguments passed into the function      // return a tween, maybe using the calculations above   return gsap.to(".myElem", { duration: 1, color: "red"}); }  tl.add( doAnimation() );

Nesting timelines can truly revolutionize the way you animate. It lets you sequence really complex animations with ease while keeping your code modular and readable.

function doAnimation() {   const tl = gsap.timeline();   tl.to(...);   tl.to(...);   // ...as many animations as you’d like!    // When you’re all done, return the timeline   return tl; }  const master = gsap.timeline(); master.add( doAnimation() ); master.add( doAnotherAnimation() ); // Add even more timelines! 

Here’s a real-world use case modified from Carl Schooff’s “Writing Smarter Animation Code” post.

Here’s a more complex demo showing the same technique using a Star Wars theme by Craig Roblewsky:

Wrapping your animation-building routines inside functions also makes recreating animations (say, on resize) a breeze!

var tl; // keep an accessible reference to our timeline  function buildAnimation() {   var time = tl ? tl.time() : 0; // save the old time if it exists    // kill off the old timeline if it exists   if (tl) {     tl.kill();   }    // create a new timeline   tl = gsap.timeline();   tl.to(...)     .to(...); // do your animation   tl.time(time); // set the playhead to match where it was }  buildAnimation(); //kick things off  window.addEventListener("resize", buildAnimation); // handle resize

Effects

With effects, you can turn a custom animation into a named effect that can be called anytime with new targets and configurations. This is especially helpful when you have standards for your animations or if you are going to be calling the same animation from different contexts.

Here’s a super-simple “fade” effect to show the concept:

// register the effect with GSAP: gsap.registerEffect({     name: "fade",     defaults: {duration: 2}, //defaults get applied to the "config" object passed to the effect below     effect: (targets, config) => {         return gsap.to(targets, {duration: config.duration, opacity:0});     } });  // now we can use it like this: gsap.effects.fade(".box"); // Or override the defaults: gsap.effects.fade(".box", {duration: 1}); 

Tip #9: Use control methods

GSAP provides many methods to control the state of a tween or timeline. They include .play(), .pause(), .reverse(), .progress(), .seek(), .restart(), .timeScale(), and several others. 

Using control methods can make transitions between animations more fluid (such as being able to reverse part way through) and more performant (by reusing the same tween/timeline instead of creating new instances each time). And by giving you finer control over the state of the animation, it can help with debugging as well.

Here’s a simple example:

One amazing use case is tweening the timeScale of a timeline!

Use case: interaction events that trigger animations

Inside of event listeners for user interaction events, we can use control methods to have fine control over our animation’s play state.

In the example below, we are creating a timeline for each element (so that it doesn’t fire the same animation on all instances), attaching a reference for that timeline to the element itself, and then playing the relevant timeline when the element is hovered, reversing it when the mouse leaves.

Use case: Animating between multiple states of a timeline

You may want a set of animations to affect the same properties of the same elements, but only in certain sequences (e.g. active/inactive states, each with mouseover/mouseout states). It may get tricky to manage. We can simplify it by using states of a timeline and control events. 

Use case: Animating based on the scroll position

We can easily fire animations based on the scroll position by using control methods. For example, this demo plays a full animation once a scroll position has been reached:

You can also attach the progress of an animation to the scroll position for more fancy scroll effects!

But if you’re going to do this, it’s best to throttle the scroll listener for performance reasons:

Hot tip: GreenSock is working on a plugin to make scroll-based animations even easier! You’re in for quite a treat. Keep your eyes peeled for news.

Bonus tip: Use GSAP’s plugins, utility methods, and helper functions

GSAP plugins add extra capabilities to GSAP’s core. Some plugins make it easier to work with rendering libraries, like PixiJS or EaselJS, while other plugins add superpowers like morphing SVG, drag and drop functionality, etc. This keeps the GSAP core relatively small and lets you add features when you need them.

Plugins

MorphSVG morphs between any two SVG shapes, no matter the number of points, and gives you fine control over how the shapes are morphed.

DrawSVG progressively reveals (or hides) the stroke of an SVG element, making it look like it’s being drawn. It works around various browser bugs that affect typical stroke-dashoffset animations.

MotionPath animates anything (SVG, DOM, canvas, generic objects, whatever) along a motion path in any browser. You can even edit the path in-browser using MotionPathHelper!

GSDevTools gives you a visual UI for interacting with and debugging GSAP animations, complete with advanced playback controls, keyboard shortcuts, global synchronization and more.

Draggable provides a surprisingly simple way to make virtually any DOM element draggable, spinnable, tossable, or even flick-scrollable using mouse or touch events. Draggable integrates beautifully (and optionally) with InertiaPlugin so the user can flick and have the motion decelerate smoothly based on momentum.

CustomEase (along with CustomBounce and CustomWiggle) add to GSAP’s already extensive easing capabilities by enabling you to register any ease that you’d like.

SplitText is an easy to use JavaScript utility that allows you to split HTML text into characters, words and lines. It’s easy to use, extremely flexible, works all the way back to IE9, and handles special characters for you.

ScrambleText scrambles the text in a DOM element with randomized characters, refreshing new randomized characters at regular intervals, while gradually revealing your new text (or the original) over the course of the tween. Visually, it looks like a computer decoding a string of text.

Physics2D lets you tween the position of elements based on velocity and acceleration as opposed to going to specific values. PhysicsProps is similar but works with any property, not just 2D coordinates.

Utility methods

GSAP has built-in utility methods that can make some common tasks easier. Most are focused on manipulating values in a particular way, which can be especially helpful when generating or modifying animation values. The ones that I use most often are .wrap(), .random, .interpolate(), .distribute(), .pipe(), and .unitize(), but there are many others you might find helpful.

Helper functions

In a similar light, but not built into GSAP’s core, are some helper functions GreenSock has created over the years to deal with specific use cases. These functions make it easy to FLIP your animations, return a random number based on an ease curve, blend two ease curves, and much more. I highly recommend checking them out!

Conclusion

You’ve made it to the end! Hopefully, you’ve learned a thing or two along the way and this article will continue to be a resource for you in the years to come.

As always, if you have any questions about GSAP, feel free to drop by the GreenSock forums. They’re incredibly helpful and welcoming! As an employee of GreenSock, that’s where I hang out often; I love helping people with animation-related challenges!

The post Tips for Writing Animation Code Efficiently appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Rethinking Code Comments

Justin Duke asks if treating code comments like footnotes could help us understand the code in a file better. In his mockup, all the comments are hidden by default and require a click to reveal:

What a neat idea! Justin’s design reminds me of the way that Instapaper treated inline footnotes.

Instapaper (circa 2012)

I guess the reason I like this idea so much is that a lot of comments don’t need to be read constantly, — they’re sort of a reminder that, “Hey, this needs work in the future” or “Yikes, this is weird and I’m sorry.” Keeping these comments out of the code makes it much easier to scan the whole file, too.

I do wonder if there could be a toggle that shows every comment, just in case you need to read all the comments in sequence rather than clicking to toggle each one.

Anyway, all this talk about comments reminds me of an absolutely fantastic talk by Sarah Drasner at JSConf this year where she discussed why comments are so dang hard to get right:

Direct Link to ArticlePermalink

The post Rethinking Code Comments appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Web Component for a Code Block

We’ll get to that, but first, a long-winded introduction.

I’m still not in a confident place knowing a good time to use native web components. The templating isn’t particularly robust, so that doesn’t draw me in. There is no state management, and I like having standard ways of handling that. If I’m using another library for components anyway, seems like I would just stick with that. So, at the moment, my checklist is something like:

  • Not using any other JavaScript framework that has components
  • Templating needs aren’t particularly complex
  • Don’t need particularly performant re-rendering
  • Don’t need state management

I’m sure there is tooling that helps with these things and more (the devMode episode with some folks from Stencil was good), but if I’m going to get into tooling-land, I’d be extra tempted to go with a framework, and probably not framework plus another thing with a lot of overlap.

The reasons I am tempted to go with native web components are:

  • They are native. No downloads of frameworks.
  • The Shadow DOM is a true encapsulation in a way a framework can’t really do.
  • I get to build my own HTML element that I use in HTML, with my own API design.

It sorta seems like the sweet spot for native web components is design system components. You build out your own little API for the components in your system, and people can use them in a way that is a lot safer than just copy and paste this chunk of HTML. And I suppose if consumers of the system wanted to BYO framework, they could.

So you can use like <our-tabs active-tab="3"> rather than <div class="tabs"> ... <a href="#3" class="tab-is-active">. Refactoring the components certainly gets a lot easier as changes percolate everywhere.

I’ve used them here on CSS-Tricks for our <circle-text> component. It takes the radius as a parameter and the content via, uh, content, and outputs an <svg> that does the trick. It gave us a nice API for authoring that abstracted away the complexity.

So!

It occurred to me a “code block” might be a nice use-case for a web component.

  • The API would be nice for it, as you could have attributes control useful things, and the code itself as the content (which is a great fallback).
  • It doesn’t really need state.
  • Syntax highlighting is a big gnarly block of CSS, so it would be kinda cool to isolate that away in the Shadow DOM.
  • It could have useful functionality like a “click to copy” button that people might enjoy having.

Altogether, it might feel like a yeah, I could use this kinda component.

This probably isn’t really production ready (for one thing, it’s not on npm or anything yet), but here’s where I am so far:

Here’s a thought dump!

  • What do you do when a component depends on a third-party lib? The syntax highlighting here is done with Prism.js. To make it more isolated, I suppose you could copy and paste the whole lib in there somewhere, but that seems silly. Maybe you just document it?
  • Styling web components doesn’t feel like it has a great story yet, despite the fact that Shadow DOM is cool and useful.
  • Yanking in pre-formatted text to use in a template is super weird. I’m sure it’s possible to do without needing a <pre> tag inside the custom element, but it’s clearly much easier if you grab the content from the <pre>. Makes the API here just a smidge less friendly (because I’d prefer to use the <code-block> alone).
  • I wonder what a good practice is for passing along attributes that another library needs. Like is data-lang="CSS" OK to use (feels nicer), and then convert it to class="language-css" in the template because that’s what Prism wants? Or is it better practice to just pass along attributes as they are? (I went with the latter.)
  • People complain that there aren’t really “lifecycle methods” in native web components, but at least you have one: when the thing renders: connectedCallback. So, I suppose you should do all the manipulation of HTML and such before you do that final shadowRoot.appendChild(node);. I’m not doing that here, and instead am running Prism over the whole shadowRoot after it’s been appended. Just seemed to work that way. I imagine it’s probably better, and possible, to do it ahead of time rather than allow all the repainting caused by injecting spans and such.
  • The whole point of this is a nice API. Seems to me thing would be nicer if it was possible to drop un-escaped HTML in there to highlight and it could escape it for you. But that makes the fallback actually render that HTML which could be bad (or even theoretically insecure). What’s a good story for that? Maybe put the HTML in HTML comments and test if <!-- is the start of the content and handle that as a special situation?

Anyway, if you wanna fork it or do anything fancier with it, lemme know. Maybe we can eventually put it on npm or whatever. We’ll have to see how useful people think it could be.

The post Web Component for a Code Block appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]