Archiwum kategorii: CSS

Vue + TypeScript: A Match Made in Your Code Editor

Post pobrano z: Vue + TypeScript: A Match Made in Your Code Editor

Vue is so hot right now and I’ve been thinking of doing a serious project with it since quite a while, so when the opportunity popped up, I hopped in. But there was a little problem — one of the requirements of the project was to write it in TypeScript. At first, I was super stressed about how I was going to ever get started on this combo, but vue-cli made it so easy.

I’d be lying if I said this ride was super smooth. There were frustrations, hours of staring at the screen and some fistbumps with my table but after working with Vue + TypeScript for over a month now, I can say it was worth it — and if I had to code another app with Vue, I wouldn’t do it without TypeScript.

Prerequisites

This article is about pairing Vue and TypeScript and assumes some basic knowledge of both. If you haven’t had a chance to play with them yet and are curious, Vue has a great guide, and the TypeScript docs are a great place to start.

We need to have vue-cli installed globally, so we can quickly spin up Vue project. Install vue-cli by running the following command in your terminal:

npm install -g @vue/cli

Once we have that installed, we’re good to go. If you don’t have TypeScript installed, we don’t need to do that beforehand, as vue-cli takes care of that when you start a new project and choose TypeScript there.

Getting Started

Now that we have vue-cli installed, all we need to do to get a project with Vue + TypeScript started is to run vue create. While creating a new project, choose TypeScript and we’re good to go.

vue create <app-name>

Here’s the result once our project spins up:

vue-cli also provides us the ability to choose Babel along with TypeScript for polyfills, CSS preprocessors, linter, unit testing libraries (I picked Jest, go Jest!) along with other config. You can even save your choices in a preset, to use it later, for another project.

Here’s a rundown of the handy questions you’ll get asked to configure the project:

One thing I’d like to mention is that vue-cli 3.0 comes with a user interface which makes it even more easy to create a new project. Run vue ui in terminal and vue-cli opens a UI where you can set up a new project.

What’s in the Box

After vue-cli is done, we get a nice directory structure of our app with all the setup already done.

  • tsconfig.json: This is all set up and we can edit it to suit our requirements.
  • shims-vue.d.ts: These shims are already set up to help TypeScript understand .vue files (Single File Components) when they are imported.
  • vue-property-decorator: If you choose to use class-style components, vue-cli adds this plugin so we can use all sorts of decorators. This comes quite handy and make the code more readable.
  • Class components: If you choose to use them, vue-cli sets the stage for you. Bear in mind that you would still need to register router hooks so class components can resolve them.

Sass Setup

One thing that I needed to set up and I wish was included out of the box was shared Sass partials. To avoid importing my Sass variables and mixins in every component, I had to load them in vue.config.js. shared.scss is the file exporting all variables and mixins that are used within the app.

Here’s where I landed with my Sass configuration:

chainWebpack: (config) => {
   config
     .module
     .rule('vue')
     .uses
     .get('vue-loader')
     .tap(({ loaders, loaders: { scss }, ...options }) => ({
       ...options,
       loaders: {
         ...loaders,
         scss: [
           ...scss,
           {
             loader: 'sass-resources-loader',
             options: {
               resources: [
                 './src/styles/shared.scss',
               ],
             },
           },
         ],
       },
     }));

Vue Property Decorator

The vue-property-decorator package exposes Vue properties and makes them available to use as decorators. In my application, I ended up using only @Component, @Prop, @Watch but there are others such as @Emit, @Inject and @Model, that make your code much more verbose when used extensively.

Vuex

Vuex has typings…nuff said! Vuex supports TypeScript to boot and, at first, I didn’t even know it. I started to look for proper ways to combine Vuex with TypeScript and stumbled upon Alex Jover Morales’ egghead.io course on Vue.js State Management with Vuex and TypeScript. It helped me understand the correct way of managing Vuex state when using TypeScript.

For example:

// actions.ts
import { ActionTree } from 'vuex';
import { RootState, ModuleState } from '@/types';


const actions: ActionTree<ModuleState, RootState> = {
  // all your actions go here
};

Vuex-class

This is yet another thing that I didn’t know existed when I first started but know wish I had found it sooner. I was creating getters for almost everything, but that didn’t feel right. I started looking for better ways to do this and found an interesting article by Francesco Vitullo which cleared up a few things for me. That’s where I found out about vuex-class which provides decorators for all vuex mappers.

So, now instead of writing a new getter for simply accessing a property in state, I could do this:

import {
  State,
} from 'vuex-class'

@Component
export class MyComp extends Vue {
  @State(state => state.bar) stateBar
}

Development Experience With VS Code

With TypeScript, the coding experience on VS Code is so much better. There is no going back and forth to check what mutation types I declared in mutation-types.ts because VS Code can recognize them and suggest correct ones as I type.

The same goes for modifying state in mutations — with TypeScript, the editor knew what my state structure looks like and suggests correct properties.

If you’re using VS Code, I strongly recommend using the Vetur plugin because it provides Vue tooling and comes with other bells and whistles like syntax highlighting (this works great with Vue single file components) and linting right out of the box.

Final Thoughts

Just like everything else in the JavaScript ecosystem, Vue + TypeScript still has a long way to go. For example, I could not use vuelidate because it doesn’t have typings. But thankfully vee-validate provided a workaround, so I didn’t have to go down the difficult road of writing those myself.

In conclusion, I found the development experience to be much smoother and VS Code is a totally different beast when you work with TypeScript. I don’t really need to sing the praises of Vue — it is very easy to pick up and start building and saves days trying to wrap your head around the inner workings of a framework.

The post Vue + TypeScript: A Match Made in Your Code Editor appeared first on CSS-Tricks.

Better rendering for variable fonts

Post pobrano z: Better rendering for variable fonts

I was messing around with a variable font the other day and noticed this weird rendering issue in the latest version of Chrome where certain parts of letterforms were clipping into each other in a really weird way. Thankfully, though, Stephen Nixon has come to the rescue with a temporary hack to fix the issue which using a text-shadow on the text that’s using the variable font:

.variable-font {
  text-shadow: 0 0 0 #000; /* text color goes last here */
} 

Once you do that, you shouldn’t be able to see those weird clip marks in the letterforms anymore. Yeah, it feels pretty hacky but I’m sure this rendering bug will be fixed relatively soon. It doesn’t look like it affects other browsers, as far as I can tell.

Direct Link to Article — Permalink

The post Better rendering for variable fonts appeared first on CSS-Tricks.

Handling Errors with Error Boundary

Post pobrano z: Handling Errors with Error Boundary

Thinking and building in React involves approaching application design in chunks, or components. Each part of your application that performs an action can and should be treated as a component. In fact, React is component-based and, as Tomas Eglinkas recently wrote, we should leverage that concept and err on the side of splitting any large chunking into smaller components.

Splitting inevitably introduces component hierarchies, which are good because they bloated components and architecture. However, things can begin to get complicated when an error occurs in a child component. What happens when the whole application crashes?! Seriously, React, why do the parent and sibling components have to pay for the sins of another component? Why?

Error Boundaries

React 16 came with a lot of goodies, one of which is error boundaries. Let’s consult the documentation and break down what it says about this gem because we can use it to spot errors where they occur and resolve them faster and with less headache!

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

That’s a lot of jargon but, like components, we can break it down into less complex chunks.

Error boundaries are React Components

This makes a lot of sense and useful because it’s a concept we have using all along. The difference is that juice was sprayed on it to make it different from a normal component. Still, don’t forget the basic idea that error boundaries are themselves React Components!

Error boundaries catch JavaScript errors anywhere in their child component tree

In case you have forgotten how children component tree work, here is an example:

<ParentComponent>
  <FirstChild>
    <FirstChildDaughter>
    </FirstChildDaughter>
  </FirstChild>
  <SecondChild>
  </SecondChild>
</ParentComponent>

We have two parent and three child components. According to what we have learned so far about error boundaries, we can replicate the above tree to:

<ErrorBoundaryComponent>
  <ParentComponent>
    <FirstChild>
      <FirstChildDaughter>
      </FirstChildDaughter>
    </FirstChild>
    <SecondChild>
    </SecondChild>
  </ParentComponent>
</ErrorBoundaryComponent>

By wrapping the whole tree up in an ErrorBoundaryComponent, we can catch any JavaScript errors that occur in its child components. Cool, right?

Error boundaries log those errors

When errors are caught, we want boundaries errors to do something with them, preferably something to tell us about the. Developers often make use of error logging platforms to monitor errors that occur on their software. With error boundaries, we can do the same.

Error boundaries display a fallback UI

Instead of displaying the whole annoying combo of reds in different shades, you can choose a customized user interface to display when an error occurs. That can come in super handy because it allows you to tailor errors in a style that makes it easier for you to read and scan. Super cool, right?

Like me, you’ll think that this means error boundaries will catch all JavaScript errors. Sadly, that’s not true. Here are errors that they will gracefully ignore:

  • Event handlers
  • Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
  • Server-side rendering
  • Errors thrown in the error boundary itself (rather than its children)

componentDidCatch()

The extra juice that makes a component an error boundary is componentDidCatch() — this is a lifecycle method that works like the JavaScript catch{} block, but for components. When an error is found in a child component, the error is handled by the closest error boundary. Only class components can be error boundaries.

componentDidCatch() accepts two parameters:

  • error: This is the error that was thrown
  • info: An object which contains a trace of where the error occurred

Error Boundary In Action

Say we are working on a feature that lists locations where conferences can be held. Something like this:

See the Pen error boundary 0 by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

The application lists locations from the Location component and the individual locations are output as Location Cards. We take a little extra care to ensure the name of each location is rendered in uppercase for consistency. For this tutorial purpose, we will add an empty object to the list of locations.

class Location extends React.Component {
  state = {
    locations: [
      {
        "name": "Ojo",
        "zone": "Lagos State",
        "region": "South West"
      },
      {
        "name": "Ahiazu Mbaise",
        "zone": "Imo State",
        "region": "South East"
      },
      {
        "name": "Akoko-Edo",
        "zone": "Edo State",
        "region": "South South"
      },
      {
        "name": "Anka",
        "zone": "Zamfara State",
        "region": "North West"
      },
      {
        "name": "Akwanga",
        "zone": "Nasarawa State",
        "region": "North Central"
      },
      {
        
      }
    ]
  }
  render() {
    return (
      <div>
        <div>
          <div>
            <h2>Locations</h2>
          </div>
        </div>
        <div>
          {this.state.locations
            .map(location => 
              <LocationCard key={location.id} {...location} />
          )}
        </div>
      </div>
    )
  }
}

const LocationCard = (props) => {
  return (
    <div>
      <hr />
      <p><b>Name:</b> {props.name.toUpperCase()}</p>
      <p><b>Zone:</b> {props.zone}</p>
      <p><b>Region:</b> {props.region}</p>
      <hr />
    </div>
  )
}

const App = () => (
  <div>
     <Location />
  </div>
)

ReactDOM.render(<App />, document.getElementById("root"));

If you run this in the browser, you will see an error similar to this screenshot:

A screenshot of the Type Error providing the error message Cannot read property toUpperCase of undefined. Background color is tan and there is a block of code with a light red background indicating where the error is in the code base.

That’s not totally helpful, so let’s apply an error boundary to handle help us out. First, we’ll create an ErrorBoundary component:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      info: null
    };
  }
  componentDidCatch(error, info) {
    this.setState({
      hasError: true,
      error: error,
      info: info
    });
  }
  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h1>Oops, something went wrong :(</h1>
          <p>The error: {this.state.error.toString()}</p>
          <p>Where it occured: {this.state.info.componentStack}</p>
        </div>
      );
    }
    return this.props.children;
  }
}

An initial state for hasError, error, and info is created. Then, the componentDidCatch() lifecycle method is added. If an error occurs in the constructor, render or lifecycle method of any of its children components, the hasError state will be changed to true. When this happens, the ErrorBoundary component renders and displays the error. But if there are no errors, the children of the ErrorBoundary component are rendered instead as we’d expect.

Next, we need to add both the ErrorBoundary and Location components to our main App component:

const App = () => (
  <div>
    <ErrorBoundary>
      <Location />
    </ErrorBoundary>
  </div>
)

See the Pen error boundary 2 by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

We don’t see that annoying TypeError UI anymore! Things are working!

There’s one little thing we can do to improve the app. If you check the code in the demo, you’ll see an empty object we added at the end. Is it possible to have the other credible locations render? Most definitely! Inside the Location component, we can wrap the LocationCard component with the ErrorBoundary component to scope error logging directly to the cards:

class Location extends React.Component {
  state = {
    locations: [
      {
        "name": "Ojo",
        "zone": "Lagos State",
        "region": "South West"
      },
      {
        "name": "Ahiazu Mbaise",
        "zone": "Imo State",
        "region": "South East"
      },
      {
        "name": "Akoko-Edo",
        "zone": "Edo State",
        "region": "South South"
      },
      {
        "name": "Anka",
        "zone": "Zamfara State",
        "region": "North West"
      },
      {
        "name": "Akwanga",
        "zone": "Nasarawa State",
        "region": "North Central"
      },
      {
        // Empty!
      }
    ]
  }
  render() {
    return (
      <div>
        <div>
          <div>
            <h2>Locations</h2>
          </div>
        </div>
        <div>
          {this.state.locations
            .map(location => 
            <ErrorBoundary>
              // Should render all locations, but the empty instance
              <LocationCard key={location.id} {...location} />
            </ErrorBoundary>
          )}
        </div>
      </div>
    )
  }
}

This time, the credible locations show, except the one that is empty. You can choose to wrap the whole component tree with an error boundary component once, or you can wrap different components at strategic places. The decision is up to you.

Wrapping Up

I encourage you to start making use of error boundaries in your applications. Similarly, it’s worth digging in a little deeper. For that, here are some issues in the React repo on Error Boundaries and event handles, go through them so you can see the current state of where things are at:

The post Handling Errors with Error Boundary appeared first on CSS-Tricks.

Animate Calligraphy with SVG

Post pobrano z: Animate Calligraphy with SVG

From time to time at Stackoverflow, the question pops up whether there is an equivalent to the stroke-dashoffset technique for animating the SVG stroke that works for the fill attribute. But upon closer inspection, what the questions are really trying to ask is something like this:

I have something that is sort of a line, but because it has varying brush widths, in SVG it is defined as the fill of a path.

How can this „brush” be animated?

In short: How do you animate calligraphy?

A mask path covers the calligraphic brush

The basic technique for this is relatively simple: draw a second (smooth) path on top of the calligraphy so that it follows the brush line and then choose the stroke width in such a way that it covers the calligraphy everywhere.

This path on top will be used as a mask for the one beneath it. Apply the stroke-dashoffset animation technique to the mask path. The result will look as if the lower path is being „written” directly on the screen in real-time.

The is a case for a mask, not a clip-path — that would not work. Clip-paths always reference the fill area of a path, but ignore the stroke.

The easiest variant is to set stroke: white for the path in the mask. Then everything outside the area painted white is hidden, and anything inside is shown without alteration.

See the Pen Writing calligraphy: basic example by ccprog (@ccprog) on CodePen.

So far, so simple. Things get tricky, however, when the calligraphic lines overlap. This is what happens in a naive implementation:

See the Pen Writing calligraphy: faulty intersection by ccprog (@ccprog) on CodePen.

At the intersection point, the mask reveals part of the crossing brush. Therefore, the calligraphy has to be cut into non-overlapping pieces. Stack them in drawing order and define separate mask paths for each one.

The cut on the mask path and the calligraphic brush must match

The most tricky part is to maintain the impression that the drawing is a single continuous stroke. If you cut a smooth path, ends will fit together as long as both path tangents have the same direction at their common point. The stroke ends are perpendicular to that, and it is essential that the cut in the calligraphic line aligns exactly. Take care all paths have consecutive directions. Animate them one after the other.

While many line animations can get by with rough math on the length for stroke-dasharray, this scenario requires accurate measurements (although small roundings shouldn’t hurt). As a reminder, you can get them in the DevTools console with:

document.querySelector('#mask1 path').getTotalLength()

See the Pen Writing calligraphy: divide up intersections by ccprog (@ccprog) on CodePen.

The „one after the other” part is slightly awkward to write in CSS. The best pattern is probably to give all partial animations the same start time and total duration, then set intermediate keyframes between the stroke-dashoffset changes.

Something like this:

@keyframes brush1 {
  0% { stroke-dashoffset: 160; } /* leave static */
  12% { stroke-dashoffset: 160; } /* start of first brush */
  44% { stroke-dashoffset: 0; }   /* end of first brush equals start of second */
  100% { stroke-dashoffset: 0; }   /* leave static */
}

@keyframes brush2 {
  0% { stroke-dashoffset: 210; } /* leave static */
  44% { stroke-dashoffset: 210; } /* start of second brush equals end of first */
  86% { stroke-dashoffset: 0; }   /* end of second brush */
  100% { stroke-dashoffset: 0; }   /* leave static */
}

Further down, you’ll see how a SMIL animation enables a more fluent and expressive way to define timing. Keeping with CSS, computations done with Sass might be pretty helpful since it can handle some math.

The mask path (left) and its application (right)

A comparable problem appears if the curve radius of the mask path gets smaller than the stroke width. While the animation runs through that curve, it may happen that an intermediate state looks seriously crooked.

The solution is to move the mask path out of the calligraphic curve. You only need to take care its inner edge still covers the brush.

You can even cut the mask path and misalign the ends, as long as the cutting edges fit together.

The radius stays large enough

See the Pen Writing calligraphy: divide up intersections by ccprog (@ccprog) on CodePen.

And, thus, you can even draw something complex, like the Arabic calligraphy in this example:

See the Pen Tughra Mahmud II – text animation by ccprog (@ccprog) on CodePen.

The original design, the Tughra of Osmanic Sultan Mahmud II., is by an unknown 19th-century calligrapher. The vectorized version was done by Wikipedia illustrator Baba66. The animation is my attempt to visualize the position of the Arabic letters inside the drawing. It builds upon an earlier version by Baba66. Creative Commons Attribution-Share Alike 2.5.

The following code snippet shows the advanced method used to run the animations in order and in a repeatable fashion.

mask path {
  fill: none;
  stroke: white;
  stroke-width: 16;
}

.brush {
  fill: #0d33f2;
}
<mask id="mask1" maskUnits="userSpaceOnUse">
  <path stroke-dasharray="160 160" stroke-dashoffset="160" d="...">
    <!-- animation begins after document starts and repeats with a click
         on the "repeat" button -->
    <animate id="animate1" attributeName="stroke-dashoffset"
             from="160" to="0" begin="1s;repeat.click" dur="1.6s" />
  </path>
</mask>
<mask id="mask2" maskUnits="userSpaceOnUse">
  <path stroke-dasharray="350 350" stroke-dashoffset="350" d="...">
    <!-- animation begins at the end of the previous one -->
    <animate id="animate2" attributeName="stroke-dashoffset"
             from="350" to="0" begin="animate1.end" dur="3.5s" />
  </path>
</mask>
<!-- more masks... -->
<mask id="mask15" maskUnits="userSpaceOnUse">
  <path stroke-dasharray="230 230" stroke-dashoffset="230" d="...">
    <!-- insert an artificial pause between the animations, as if the
         brush had been lifted -->
    <animate id="animate15" attributeName="stroke-dashoffset"
             from="230" to="0" begin="animate14.end+0.5s" dur="2.3s" />
  </path>
</mask>

<g class="brush">
  <path id="brush1" d="...">
    <!-- The mask is only applied  after document starts/repeats and until
         the animation has run. This makes sure the brushes are visible in
         renderers that do not support SMIL -->
    <set attributeName="mask" to="url(#mask1)"
         begin="0s;repeat.click" end="animate1.end;indefinite" />
  </path>
  <path id="brush2" d="...">
    <set attributeName="mask" to="url(#mask2)"
         begin="0s;repeat.click" end="animate2.end;indefinite" />
  </path>
  <!-- more paths... -->
  <path id="brush15" d="...">
    <set attributeName="mask" to="url(#mask2)"
         begin="0s;repeat.click" end="animate15.end;indefinite" />
  </path>
</g>

In contrast to the other examples we’ve look at, this animation uses SMIL, which means it will not work in Internet Explorer and Edge.


This article is published in German over at Browser…​unplugged.

The post Animate Calligraphy with SVG appeared first on CSS-Tricks.

Don’t Use The Placeholder Attribute

Post pobrano z: Don’t Use The Placeholder Attribute

Eric Bailey takes a hardline position on <input placeholder>.

You might be thinking, as I did: yeah, yeah I know the pitfalls. I’m capable of using placeholder responsibly. But when you look at all the negatives together:

  • Can’t be automatically translated;
  • Is oftentimes used in place of a label, locking out assistive technology;
  • Can hide important information when content is entered;
  • Can be too light-colored to be legible;
  • Has limited styling options;
  • May look like pre-filled information and be skipped over.

…and the fact that there are advantages to just moving whatever helper text you would want in there anyway outside the input to real markup…I’m fairly well convinced.

Direct Link to Article — Permalink

The post Don’t Use The Placeholder Attribute appeared first on CSS-Tricks.

Balancing Time

Post pobrano z: Balancing Time

I first wrote this post four years ago. I put it on a blog that no longer exists. Funnily enough, I still refer to it myself, so I figured it might be best served in a place where other people can see it. I’ve made only a few minor tweaks to the original content. A lot about how I work has changed, but most of these pieces have not.


I work on many personal projects concurrently. I love doing this, as it keeps me in a constant mode of creation. At the same time, it can become a delicate balancing act. In order to keep everything moving forward, I have set up some guidelines for myself and I’m going to share them with you in this post. However, it’s more important to understand what works best for you and consider the sage words of Thich Nhat Hahn:

“Don’t follow someone else’s map.”

What works for me might not work for you. However, hearing about how other people set up their workflow might help you reconsider your own, so hopefully this is a useful mental exercise.

Organize

Every three months or so, I compile a list of all my projects. The projects that have time parameters go first in line (but do not always come first if my passion lies elsewhere). For each project, I break down the tasks I need to perform in order to get them done. I try to make each one as small and actionable as possible.

grid of X drawn out on a moleskine sketchbook

I actually write out the same list multiple ways — some digital, some paper. I find the repetition helps me reinforce and recall what my priorities are. I also find large gridded Moleskine sketchbooks useful for organizing myself. It’s important to me that they’re large enough to have enough space to write notes, draw terrible sketches, or generally spread out.

Unless they must be done in order, I often place the easiest and quickest tasks first so I can get them out of the way. I love the feeling of checking things off my list because it serves as positive re-enforcement. I make a schedule of due dates for items that have no due dates; having a specific deadline helps me push forward.

Only stop when you know what happens next

This a really simple and useful trick. If you stop when your plan is veering or meandering, then chances are that project will never see the light of day again. If you can help it, try to only stop working when you know what the next actionable item is. You will arrive back at the project with brighter eyes than before.

Of course, this one doesn’t work when you’ve smacked your head on a problem forever and ever. Sometimes you need a break and just leaving it for a little while or coming back to it the next day will help you solve it. Generally speaking though, you still still know what comes next even before you come to a solution. It’s more the feeling of malaise that I’m warning against. Stop while you still have a plan.

Even backwards work is forward progress

fingers on a keyboard
Photo by John Schnobrich, via Unsplash

Allow yourself to make mistakes. Seriously, make them. I used to tell my students that it takes two bad projects to make a good one. Never compare yourself to what others show you — their final output is often the result of many failed attempts. Make a lot and then edit down. Try not to get discouraged if you spend a day or two messing up. You’ll likely learn more from those mistakes than if you had done everything perfectly. Forge ahead.

Push outside of your comfort zone, but slowly

Work on a few things that you know and understand, and a few things you don’t. We should foster personal growth in our projects, but without some semblance of comfort, it’s easy to get discouraged. Let your projects push the limits of your boundaries, but don’t go overboard. Give yourself a foundation to spring off before floating into space.

Figure out your “studio commandments”

What do you need to work? Do you need music? Do you need water? Do you need isolation? Do you work better in a cafe? Maybe you need a certain monitor. Perhaps you concentrate better if you have scheduled breaks? Do you work better if you have a snack in your bag in case you get hungry? Study yourself. Write down 10 things you need in order to be productive and try to sort them out before you get going so that you give yourself fewer excuses to stop making progress. I wrote another post about this on SuperYesMore, posted here.

Make the time

I usually break up my time so that I have certain nights, like appointments, where I work on each project. There are times, however, where you should keep on going and not worry about other outstanding projects. Sometimes working 15 or more continuous hours will gain you traction in a way that you can’t if you break it up over several weeks. However…

Break your own rules

Do you have a consistent schedule and you can’t possibly do X because of Y? Double and triple check that you aren’t setting up guidelines for yourself that give you excuses ti not get things done. Something that worked last week might not work this week, so take the time to re-evaluate your own rules. In other words: be adaptive.

Do things for other people

Make one of your projects something that benefits others. This guideline might sound strange, but if you continuously work on things just for yourself, work starts to feel a little dreary. I’m not talking about your job, either. It needn’t be overkill. Even donating a few hours here or there to people who need it will help you think more broadly about the world around you.

Bonus: If you build a community and reach the point where you’re ready to launch that donated project, you might just have other people around you who to share the excitement of a job well done.

Research is productive time

Reading about what you find interesting or doing a little bit of digging about your interests can save you time in process. Find heroes in the field in which you are working and follow them. I have so many.

Poke around at other things. Reverse engineer something. I have a giant private collection on CodePen called „To reverse engineer.” When I’m bored at an airport, or sitting on hold, or have an hour to kill, I’m usually poking around in that folder: breaking things, changing things, finding the boundaries of how everything works.

Read a book, read some docs, watch some talks, do a workshop, watch some anime, go to a museum, listen to some music with your eyes closed, play a video game. Need a starting point? CodePen Challenges are good for that. There are all kinds of things that can feed your work. All of this spent time — while it won’t make your GitHub contribution graph greener — is important for development.

Make it fun

photo of a mimosa and a woman's torso
Photo by Hanny Naibaho, via Unsplash

Personal projects are fun because you want to do them, right? Enjoy yourself. I really like mimosas on the weekends so I enjoy one by my window every Saturday morning while writing code. It’s a very simple trick. It’s not drudgery; it’s pure enjoyment. I turn down other plans to do this because I love it. Find ways to make the work a reward in and of itself. Maybe you only get to listen to that one album you like while you work on a side project. Maybe you have a nice fuzzy blanket that you get to wrap yourself in while you read that programming book. Maybe you get to go to the park after you get that last component in. You know the difference between something that genuinely excites you to work or not — use this to your advantage.

I also imagine how I might feel when something is done. This particularly works when the only thing keeping me from finishing something is a bit of drudgery. I imagine it’s done and feel the little dopamine rush from accomplishing something and not letting it sit. Then I chase that feeling.

The post Balancing Time appeared first on CSS-Tricks.

Advanced Document Conversions with Filestack

Post pobrano z: Advanced Document Conversions with Filestack

You might know Filestack from being an incredible service to add file uploading, storage, and management to your own web apps.

There is another thing Filestack can do for you: convert documents into different formats.

For one thing, it can manipulate documents. Take images. Perhaps you would like to offer some image manipulation for your users uploaded images, like cropping and rotation. That’s a common feature for apps that offer avatar uploading. With Filestack, you got it.

It’s great to be able to have that kind of functionality without having to build it yourself. You almost surely aren’t in the avatar cropping business, you’re in your own unique business that just happens to have users with avatars.

I’ve said it before:

Being smart is using a service like Filestack to handle files while you focus on what your app really does.

But let’s up the ante a little bit here. What if you need to get an entirely different document format out of another document? How about the hardest document format at all, feared by web developers everywhere, the Microsoft Word document format! 😱

Filestack has you covered! Say you have an invoice document created in Word and you need it as a PDF. But a perfect PDF, not some hack job conversion. And you need to do it programmatically. That’s tricky stuff, and Filestack has solved it.

Of course, it isn’t just Microsoft Word document formats, they have a whole matrix of in’s and out’s.

See full size

Just about any file format conversion you need, they got. Personally, I’m impressed by the idea that conversion between PDF and SVG maintains the vectors in both directions.

Document security is a prime concern of course and is handled through policy and signature validation.

See their security docs for all things security related.

Need a way to show users files like PDFs? Browsers can view PDFs, but only as a whole, not embedded into regular web pages. Not a problem with the document viewer!

If you think Filestack might solve some problems for your app, like transforming files, check out their getting started guide.

The post Advanced Document Conversions with Filestack appeared first on CSS-Tricks.

Centering: The Newest Coolest Way vs. The Oldest Coolest Way

Post pobrano z: Centering: The Newest Coolest Way vs. The Oldest Coolest Way

This isn’t a comprehensive guide to centering things. We have that!

This is just a little observation about old and new. One of the trickier things related to centering in CSS is when you need to center both vertically and horizontally and you don’t know the width or height of what you are centering. Vertical centering being the extra tricky of the two.

Believe it or not, there was a way to do that even in IE 8. Czytaj dalej Centering: The Newest Coolest Way vs. The Oldest Coolest Way →

Don’t just copy the @font-face out of Google Fonts URLs

Post pobrano z: Don’t just copy the @font-face out of Google Fonts URLs

I don’t think this is an epidemic or anything, but I’ve seen it done a few times and even advocated for. This is what I mean…

You go to Google Fonts and pick a font like Open Sans, and it gives you either a <link> or an @import with a URL there in which to ready this font for usage on your site.

You can take a peek in there and see what it returns…

It’s just some @font-face declarations, of course!

Now your performance-minded brain kicks off. Wait. So, I make one HTTP request for this stylesheet, and then it makes more HTTP requests for those woff2 files it’s linking up. Screw the middle man here, why not just copy those @font-face blocks right out of here and use them.

You can! But!

The issue is that Google does fancy Google things here and the contents of that original stylesheet changes based on the browser requesting it. That screenshot above is Chrome 66. Here’s Firefox 20 on Windows 7:

It’s different! It’s only got woff, not woff2. If we open that URL in IE 8, we’d get an @font-face block that includes the eot format!

The point is, what that URL gives is very specific to what the current browser needs. That’s a pretty cool thing to abstract away and not worry about. Should new browsers have new formats and new CSS syntax needed, that’ll just come along for the ride.

Not that Google Fonts is perfect with this stuff. For example, by not controlling your own @font-face blocks, you can’t take advantage of font-display, which is a shame. Maybe we’ll get that someday, or maybe it’s worth self-hosting your Google Fonts, which is another whole thing we’ll get into someday.

The post Don’t just copy the @font-face out of Google Fonts URLs appeared first on CSS-Tricks.