Here’s the thing about “unused CSS” tools

Post pobrano z: Here’s the thing about “unused CSS” tools

There are a lot of tools that aim to help you remove „unused CSS” from your project. Never a week goes by that I don’t see a tool for this being shared or promoted. It must strike some kind of perfect chord for some developers. I care about performance, and I know that reducing file sizes is good for performance. Indeed, it is. I bet we have CSS that is unused in our stylesheets, if we removed that, that’s a performance win. Yep, it would be. We should automate that. Ehhhhhh, I’m not so sure.

There are major performance tooling players that play up this idea, like Lighthouse and how it gives you CSS and JS „Coverage”, which will surely tell you that you’re shipping code you don’t need to be.

The tools that claim to help you with unused CSS have to perform analysis to be able to tell you what is unused and what isn’t.

Here’s one way to do that analysis. Render a page of your site and get the complete DOM. Then get the complete CSSOM as well, which can give you an array of all the selectors in your CSS. Loop over those selectors and do a querySelector in the DOM and see if it matches anything. If it doesn’t, that CSS selector is unused.

Clever, right?!

I think so. But that analysis paints a rather limited picture.

Say that analysis runs two seconds after the page is complete, but there is some JavaScript that runs and injects a modal after five seconds (ughghk, I know). The analysis would have missed the HTML in that modal, which likely has styles, and thus would have incorrectly reported those styles as unused.

So, timing is one factor. Hopefully, this analysis tool has some way to configure multiple timings.

We’re also only looking at one page so far. Of course, a site might have tens, hundreds, or thousands of pages. To be entirely sure about unused styles, looking at all of them is the most sure-fire bet.

Multiple pages is another factor. Hopefully, an analysis tool has a way to look at as many pages as you tell it to. Perhaps it can look at a sitemap?

Remember the timing thing? We might think of timing as one generic form of state. There are countless other things that could be state related. Is the user logged in or not? What plan are they on? Is their credit card expired thus showing some kind of special message? Do situational things like time/date/geolocation change state? What about real-time data? Stuff from an API?

Application-level state is clearly a big factor. Hopefully, this analysis tool can trigger/set all possible combinations of state.

There is interactive state as well. What about modals that come up because something is clicked? What is the active tab? Is this menu open or closed? What scroll position are they at? There are infinite permutations of this. Imagine a warning bar that shows up seven seconds after the user logs in to warn user about their expired credit card which contains a custom styled select menu which can be in an open or closed state, but only on the user settings page.

It seems unlikely that this analysis tool can handle all those possibilities. Even with loads of configuration, mock state, and integration testing, it couldn’t cover the near-infinite possible permutations of all this.

And yet, I don’t think these tools are useless — they are just…tools. Their use can actually be a positive step toward better code. Their use says OK, I admit it, I’m a little afraid our CSS. You could use this tool to get a broad picture of what your unused CSS might be, then combine that with your own knowledge of your CSS code base to make more informed decisions. Or take another technological step and do something like add a background image to those unused selectors and check server logs to see if they get hit.

It should be said that this whole idea of unused CSS is a part of the CSS-in-JS saga that our industry is going through. If all your styles are written as part of components, there kinda is no unused CSS. Either the component gets used and the styles come with it, or it doesn’t. If you’re particularly sensitive about the danger of unused CSS, that alone might sway you toward a CSS-in-JS tool.

It also should be said that this DOM and CSSOM analysis technique is only one possible way of checking for unused styles. If you had some kind of fancy tooling that could analyze all of your templates, styles, and scripts, presumably that could determine unused styles as well. We talk about that in the recent ShopTalk Show episode with Chris Eppstein.

The post Here’s the thing about “unused CSS” tools appeared first on CSS-Tricks.

How to Create a Set of Glitches in Adobe Photoshop

Post pobrano z: How to Create a Set of Glitches in Adobe Photoshop

Final product image
What You’ll Be Creating

Experimental glitches are not only used to depict the 80s—nowadays they’re also used to convey a robotic, trendy feel. Here is a quick and easy way to create this trend in Adobe Photoshop! 

Looking for amazing fonts and Photoshop addons? Head on over to GraphicRiver.

What You’ll Need to Create Your Poster

You will need the following resource in order to complete this tutorial:

1. How to Create the Base of the Glitch

Step 1

In Photoshop, go to File > New. Name the document Glitch_Set. Set the Width to 1270 px and Height to 1600 px. Set the Resolution to 72 Pixels/Inch. Click OK.

Create a new Photoshop file

Step 2

Using the Rectangle Tool (U), create a stripe at the top of the page. Head over to the Options bar and change the fill color to #ff0000. On the Layers panel, duplicate the Rectangle 1 layer by pressing Command-J. Change the color again, but this time to #00ff00. Place the rectangle under the first red rectangle. Duplicate the rectangle once more and set the color to #0000ff.

With the Rectangle Tool create horizontal lines in green blue and red colors

Step 3

Now we need to fill the page with the rectangles we created. Select the rectangle layers and, on the page, click on the elements and press Option-Shift and drag to duplicate. Do this until you’ve covered the whole page. 

Select all the Rectangle layers and Right-click > Rasterize Layers. Now we can merge the layers—while selecting all the layers, Right-click > Merge Layers. Let’s rename the layer as Main. Now we have the basis to create our set of glitches.

Fill the all of the page with the lines

2. Glitch A

Step 1

On the Layers panel, duplicate the Main layer by selecting the layer and pressing Command-J. Hide the original Main layer. While selecting the newly duplicated layer, head over to Filter > Distort > Wave. The Wave options window will pop up, and now we can experiment! 

Let’s start by setting the Type: of wave to Sine. We will be able to see how the artwork changes through the small view window. I am setting the Number of Generators to 999, Wavelength to Min. 1 and Max. 21, Amplitude to Min. 1 and Max. 2, and Scale to 100%.

Rasterize the horizontal lines and apply the Wave filter

Step 2

Head over to Filter > Distort > Shear. To make the glitch look like a disrupted VHS tape, we need to create waves. Under Undefined Areas, select Wrap Around and add points on the grip—this is to create waves on the composition. I added various points, and I find it works better when the points are random and have sharp turns. 

On the same layer use the Shear filter

Step 3

We can leave this as is or change the color by adding a solid color or a Gradient layer over it. We can also create a black and white look by going to Adjustment Layer > Black & White on the Layers panel and tweaking the color separately. I will do the latter as it will come in handy to create Glitch C. 

Let’s organize the first glitch by dragging the duplicated layer and the black and white layer into a folder at the bottom of the Layers panel. Let’s hide the visibility and move on to Glitch B. 

Add a black and white adjustment layer

3. Glitch B

Step 1

Duplicate the Main layer with the stripe by pressing Command-J when selecting it. Move the layer to the very top of the layers. 

Duplicate the stripes

Step 2

Head over to Filter > Pixelate > Color Halftone. I am using the following settings: Max. Radius: 20, Channel 1: 108, Channel 2: 162, Channel 3: 90, and Channel 4: 45. Click OK. The reason we are doing this step is so that when we apply the Wave effect, the divisions will look rougher compared to Glitch A. 

Apply a color halftone filter

Step 3

Go to Filter > Distort > Wave. Let’s set the Type: of wave to Square. We will be able to see how the artwork changes through the small view window. I am setting the Number of Generators to 720, Wavelength to Min. 270 and Max. 365, Amplitude to Min. 1 and Max. 2, and Scale to 100%. Click OK. 

Now we have our second glitch. As with Glitch A, go ahead and organize it in a folder.

Apply the wave filter

4. Glitch C

Step 1

Duplicate the Main layer twice with the stripe by pressing Command-J when selecting it. Move the layer to the very top of the layers.

Duplicate the horizontal lines

Step 2

Select one of them and go to Create a New Fill or Adjustment Layer  > Black & White. Right click on the new layer and select Create Clipping Mask. This is to apply this new Adjustment layer only to the one after it.

Create a black and white clipping mask over the horizontal lines

Step 3

Select the layer after it and go to Filter > Distort > Wave. The Wave options window will pop up. Set the Type: of wave to Sine, and under Undefined Areas select Wrap Around. We will be able to see how the artwork changes through the small view window. I am setting the Number of Generators to 999, Wavelength to Min. 1 and Max. 999, Amplitude to Min. 999 and Max. 999, and Scale to 100%. Click OK. Apply this effect twice to get an even finer scratchy look.

Apply the wave effect twice to create a scratchy look

Step 4

Click on the Black & White Adjustment layer and tweak the colors on the Properties panel. If you don’t have the panel, double click on the layer thumbnail. I changed the color Red to 300 and lowered the Green to -120.

You can adjust the settings of the black and white clipping mask to add contrast to the layer

Step 5

Let’s do the same with the second layer we duplicated in Step 1. We can repeat Step 3, but this time in color, without the Black & White Adjustment Layer.

On the toolbar, select the Rectangular Marquee Tool (M). With this tool, we can select the parts that we want to delete to reveal the black and white layer behind it. Don’t be afraid to duplicate layers and experiment. You can get the best result by just playing with the layers and settings to create something that is yours! 

Using the Rectangular Marquee Tool you can delete certain parts of the layer to reveal the back

Step 6

Don’t forget that this effect also works with text. Using the Text Tool (T), add any kind of text. I added the word TEST in Bw Nista International Black and color #0000ff. Try to fill the whole page. On the Layers panel, select the text layer and Right click > Rasterize Type. Once you have the text set, repeat the Wave effect by going to Filter > Distort > Wave. Feel free to play with the settings! 

You can also apply the Wave effect on text

Awesome Work—You’re Done!

Congratulations! In this tutorial, you’ve learned to:

  • Use the Wave effect to create a unique glitch set from scratch.
  • Use the Color Halftone effect to your advantage. 
  • Experiment! Scratchy and techno designs can be difficult to create because of the randomness, and experimenting with colors and various methods is the only way to achieve it!  

If you liked this tutorial, you might like these:

Building a RSS Viewer With Vue: Part 1

Post pobrano z: Building a RSS Viewer With Vue: Part 1

As I explore, learn, and most importantly, play with Vue.js, I’ve been building different types of apps as a way to get practice with and improve my use of it. A few weeks ago, I was reading about the shut down of Digg’s RSS Reader and while great alternatives exist, I thought it would be fun to build my own with Vue. In this article, I’m going to explain how I put it together and also what’s wrong with it. I knew getting into this that I was going to make some compromises, so the plan is to follow up this version with a nicer one in a follow-up post.

Article Series:

  1. Setup and first iteration (This Post)
  2. Refinements and final version (Coming Soon!)

Let’s start by looking at the app and explaining the various components.

A Look at the App

When opening the application, you’re presented with some basic instructions and a prompt to add a new RSS feed.

Clicking the button opens a modal letting you enter a feed:

Once you add the button, the blog entries for that feed will be displayed:

Notice the color. I set it up so that each feed would have a unique color, making it easier to tell one site’s content from another. For example, here is how it looks with more feeds added.

The panel on the left lets you filter by clicking on a feed. Unfortunately you can’t delete a feed yet so, if you need to remove something, you’ll need to open up your DevTools and edit the cached value.

Let’s go over the tech stack!

The Components

First and foremost is the Vue library itself. I’m *not* using webpack for this application — just a simple script include with no build process.

The UI is all Vuetify, a very nice material design framework that is easy to use. I’m still learning it, so you can be sure that my design could be better, though I’m really happy with how it looks now.

Persistence is done via localStorage. I store the feed metadata retrieved from the RSS feed. This typically includes things like the name of the site, the main URL, and a description. I do not store feed items which means every time you load the site, I re-fetch items. The next version will keep items locally using IndexedDB.

So, how do I load feed information? I could just make a network request to the URL, but most RSS feeds aren’t making use of CORS which means the browser would be blocked from loading it. To get around this, I wrote a quick serverless function with Webtask. It handles both creating a CORS-friendly endpoint as well as parsing the feeds’ XML into friendly JSON.

Now that I’ve covered the various parts of the application, let’s start looking at the code!

The Layout

Let’s start with the layout. As I said, I’m using Vuetify for the UI. I started off using the dark sample layout. This is what creates the header, footer, and left column used for the menu.

Application template

I used the card component for individual feed items. I’m not quite happy with the layout here. For example, I don’t have publication dates rendered yet because I had trouble finding a nice way to render it. I decided to simply punt and wait till the next version, which we’ll **see in Part 2 of this series.

Instead of dumping the entire source code on you at once, let’s look at the individual parts. First, here’s the introductory/help text before any feeds have been added:

<div v-if="showIntro">
  <p>
    Welcome to the RSS Reader, a simple way to manage RSS feeds and read content.  To begin using the RSS Reader, add your first feed by clicking the button below.
  </p>
  <p>
    <v-btn color="primary" large @click="addFeed">
      <v-icon>add</v-icon>
      Add Feed
    </v-btn>
  </p>
</div>

When you do have feeds, items are displayed as a list of cards:

<v-container fluid grid-list-lg>
  <v-layout row wrap>
    <v-flex xs12 v-for="item in items">
      <v-card :color="item.feedColor">
        <v-card-title primary-title>
          <div class="headline">{{item.title}}</div>
        </v-card-title>
        <v-card-text>
          {{item.content | maxText }}
        </v-card-text>
        <v-card-actions>
        <v-btn flat target="_new" :href="item.link">Read on {{item.feedTitle}}</v-btn>
        </v-card-actions>
      </v-card>
    </v-flex>
  </v-layout>
</v-container>

Note the button for reading a feed item uses a target to open it up in a new tab.

To display feeds, I use a list component:

<v-list dense>
  <v-list-tile @click="allFeeds">
    <v-list-tile-action>
      <v-icon>dashboard</v-icon>
    </v-list-tile-action>
    <v-list-tile-content>
      <v-list-tile-title>All Feeds</v-list-tile-title>
    </v-list-tile-content>
  </v-list-tile>
  <v-list-tile @click="filterFeed(feed)" v-for="feed in feeds" :value="feed == selectedFeed">
    <v-list-tile-action>
     <v-icon :color="feed.color">bookmark</v-icon>
    </v-list-tile-action>
    <v-list-tile-content>
      <v-list-tile-title>{{ feed.title }} </v-list-tile-title>
    </v-list-tile-content>
  </v-list-tile>
  <v-list-tile @click="addFeed">
    <v-list-tile-action>
      <v-icon>add</v-icon>
    </v-list-tile-action>
    <v-list-tile-content>
      <v-list-tile-title>Add Feed</v-list-tile-title>
    </v-list-tile-content>
  </v-list-tile>
</v-list>

Finally, here is the modal layout:

<v-dialog v-model="addFeedDialog" max-width="500px">
  <v-card>
    <v-card-title>Add Feed</v-card-title>
    <v-card-text>
      Add the RSS URL for a feed below, or the URL for the site and I'll try to 
      auto-discover the RSS feed.
      <v-text-field v-model="addURL" label="URL" :error="urlError"
      :rules="urlRules"></v-text-field>
    </v-card-text>
    <v-card-actions>
      <v-btn color="primary" @click.stop="addFeedAction">Add</v-btn>
      <v-btn color="primary" flat @click.stop="addFeedDialog=false">Close</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>

The Logic

Now for the fun part — JavaScript! As before, I’m not going to dump the entire file on you. Instead, let’s tackle it bit by bit.

On start up, I load any existing feeds that may have defined and then display the introduction text, if needed:

created() {
  this.restoreFeeds();
  if (this.feeds.length === 0) this.showIntro = true;
},

The restoreFeeds method handles checking LocalStorage for existing feeds.

restoreFeeds() {
  let feeds = localStorage.getItem('feeds');
  if (feeds) {
    this.feeds = JSON.parse(feeds);
    this.feeds.forEach((feed,idx) => {
      feed.color = colors[idx % (colors.length-1)];
      this.loadFeed(feed);
    });
  }
},

Note that this method handles assigning a color (which is a simple array) and then loading feed data.

Speaking of that, how do I handle loading RSS information? Currently there are two times where this happens. First is when you initially add the feed and second when you reload the application and the feed was already defined. In both cases, I call one URL — the serverless task defined with Webtask. This task will return everything — the metadata about the feed and the items itself. I only care about the metadata on the *first* call and, in theory, I could have made the code a bit quicker by removing the metadata at the server side and strip that out but it didn’t seem like it was worth the effort.

That serverless function is rather simple:

'use strict';

const Parser = require('rss-parser');
const parser = new Parser();

module.exports = function(context, cb) {
  let url = '';
  if(context.body && context.body.url) url = context.body.url;
  if(context.query && context.query.url) url = context.query.url;
  if(url === '') cb(new Error('URL parameter not passed.'));
  console.log('gonna parse '+url);
  
  parser.parseURL(url)
  .then(feed => {
    console.log(feed);
    cb(null, {feed:feed});
  })
  .catch(e => {
    cb(e);
  });
        
}

All I’m doing here is wrapping the npm package rss-parser and that handles all the converting for me. The if statements you see in the beginning handle looking for the url parameter. When calling my webtask, I can either pass a query string variable or send it as part of a HTTP body. Either way, I simply use the rss-parser module and return the result.

The endpoint for this function is:

https://wt-c2bde7d7dfc8623f121b0eb5a7102930-0.sandbox.auth0-extend.com/getRss

You’re welcome to try it out yourself. You can see this being used in the method handling adding a feed:

addFeedAction() {
  this.urlError = false;
  this.urlRules = [];
  //first, see if new
  if(this.feeds.findIndex((feed) => {
    return (feed.rsslink === this.addURL);
  }) >= 0) {
    this.urlError = true;
    this.urlRules = ["URL already exists."];
    return;
  } else {
    fetch(rssAPI+encodeURIComponent(this.addURL))
    .then(res => res.json())
    .then(res => {
      // ok for now, assume no error, cuz awesome
      this.addURL = '';

      //assign a color first
      res.feed.color = colors[this.feeds.length % (colors.length-1)];

      // ok, add the items (but we append the url as a fk so we can filter later)
      res.feed.items.forEach(item => {
        item.feedPk = this.addURL;
        item.feedColor = res.feed.color;
        this.allItems.push(item);
      });

      // delete items
      delete res.feed.items;

      // add the original rss link
      res.feed.rsslink = this.addURL;

      this.feeds.push(res.feed);
      this.addFeedDialog = false;

      //always hide intro
      this.showIntro = false;

      //persist the feed, but not the items
      this.storeFeeds();
    });
  }

},

This method first checks if a feed already exists and, if it doesn’t, it hits the serverless endpoint to get the details. I’ve got a bit of data duplication going on when I store items. I didn’t want to store items „under” a feed object and instead use a global Vue data value, allItems. Therefore, I copy the feed identifier and color into each item. The idea was to make it easier to do item display and filtering later. This feels „wrong” to me, but again, this is my first draft. I’m using a computed property for items and you can see that logic here:

items:function() {
  if(this.allItems.length === 0) return [];
  // filter
  let items = [];
  if(this.selectedFeed) {
    console.log('filtered');
    items = this.allItems.filter(item => {
            return item.feedPk == this.selectedFeed.rsslink;
    });
  } else {
    items = this.allItems;
  }
  items = items.sort((a, b) => {
    return new Date(b.isoDate) - new Date(a.isoDate);
  });

  return items;
}

Looking at it now, I could gather my items from each feed instead of storing one global array, though I could address this later, if I want. I love that Vue gives me options for how to solve things like this.

Where Next?

When I started this article, I explicitly thought *this* *is* a first draft. I’ve pointed out things here and there that I like and don’t like, but what exactly do I plan for the next version?

  • I want to move all the data access into Vuex. Vuex is described as a „state management pattern + library” for Vue. If that doesn’t make much sense to you, don’t worry. I had no idea what it meant at first either. To me, Vuex provides a way to handle more complex data in an encapsulated manner. This becomes even more important as you start building more components that need to share data.
  • Speaking of components, I should consider making „item” a proper Vue component. That’s an easy win.
  • I want to start storing feed items in IndexedDB so you’ll get content the second you open the application. This will make the application much more performant and provide basic offline support. Of course, you can’t read the full entries if you’re offline, but at least *something* could be provided.
  • …and anything you suggest! Take a look at the code and feel free to make suggestions and point out mistakes!

Stay tuned for the second post!

The post Building a RSS Viewer With Vue: Part 1 appeared first on CSS-Tricks.

Illustrator in 60 Seconds: The Asset Export Panel

Post pobrano z: Illustrator in 60 Seconds: The Asset Export Panel

Final product image
What You’ll Be Creating

Welcome to our Illustrator in 60 Seconds series, in which you can learn an Illustrator skill, feature, or technique in just a minute!

Illustrator in 60 Seconds: The Asset Export Panel

The process of exporting multiple assets from Illustrator at the same time used to be a tedious task, but luckily for us Adobe has added a new tool that changes everything for the better.

If you want to learn more then you should definitely check out this short video, which comes with a couple of steps to help you.

The Asset Export Panel

Back in
the day, the process of exporting multiple assets at the same time used to be
really clunky, but luckily for us Adobe has introduced a new tool that allows you to
save as many items as you want, using just a couple of clicks.

By default, the tool is hidden, but you can find it underneath the Window menu, or within the Layers
and Artboards group if you’re using the
Essentials Classic workspace.

asset export panel location

You start by selecting and then dragging the desired items within the
panel, which treats each group as its own asset.

adding the assets to the export panel

Moving on, you have your Export Settings, which allow you to generate not one but multiple
scales to which you can assign a custom suffix, and then choose from eight different file formats that can be individually set for each and every one of
them.

export settings preview

If you’re designing for iOS or Android you have a
set of dedicated buttons that will create all the required size variations, to
which you can add new ones or even remove those that are unnecessary.

example of using the android preset

Once you’re ready, all you have to do is press
the Export button, which will ask you
for a location to save the generated files.

example of exporting the selected assets

Learn More With Our Awesome Tutorials!

Looking to expand your bag of Adobe Illustrator skills? Start right now by checking out these in-depth tutorials that will help you bring your art to the next level!

Need Awesome Resources? We’ve Got You Covered!

Whether you’re looking for brushestextures or any other creative resource, we’ve put together an amazing library that’s forever increasing, which you can check out by heading over to Envato Elements.

That being said, I’ll see you in the next one!