Tag: stack

2020 Stack

In an article with the most clickbaity article ever, Joe Honton does a nice job of talking about the evolving landscape of web development. “Full-stack” perhaps had its day as a useful term, but since front-end development touches so many parts of the stack now, it’s not a particularly useful term. Joe himself did a lot to popularize it, so it does feel extra meaningful coming from him.

Plus the spectrum of how much there is to know is so wide we can’t all know it all, so to get things done, we take what we do know and slot ourselves into cross-functional teams.

Since no one person can handle it all, the 2020 stack must be covered by a team. Not a group of individuals, but a true team. That means that when one person is falling behind, another will pick up the slack. When one person has superior skills, there’s a mechanism in place for mentoring the others. When there’s a gap in the team’s knowledge-base, they seek out and hire a team member who’s smarter than all of them.

So the “2020 Stack” is essentially “know things and work on teams” more so than any particular combination of technologies. That said, Joe does have opinions on technologies, including writing HTML in some weird GraphQL looking syntax that I’d never seen before.

Direct Link to ArticlePermalink

The post 2020 Stack appeared first on CSS-Tricks.

CSS-Tricks

,

Full Stack Panic

A new podcast from Sean Fioritto inspired by Joel Califa’s term “Full Stack Anxiety”.

… the little voice in your head says … “I should know all of this. Do I even know what I’m doing?” Why do web developers the world over feel like this?

There is an episode with Joel talking about it as well as other interesting angles like an episode with psychologist Dr. Sherry Walling.

The overall vibe is that of catharsis in that, hopefully, none of this matters as much as it seems like it might. I’d like to think we try to deliver that, through a bit of levity, on ShopTalk Show as well.

Oh hey and Panic started a podcast too, a must-subscribe from me as a long-time fan of all their interesting work.

Direct Link to ArticlePermalink

The post Full Stack Panic appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

How to Stack Elements in CSS

If you want to create fantastic and unique visual experiences on the web, you will eventually need two elements to overlap or exist in the same place. You may even just need them to be positioned near or next to each other. Let’s go over two different ways to accomplish this, one with the position property and one with CSS Grid.

Method 1: Using the Position Property

You may already know that position: absolute; will place something absolutely on the page wherever you want it to be. In this case, we’re absolutely positioning the child to the top-left of the page. No matter where the parent is, the child will be placed in that corner, absolutely.

.child {   ...   position: absolute;   top: 0;   left: 0; }

See the Pen
CSS Stacking, Absolute 1
by Sarah Drasner (@sdras)
on CodePen.

But this is very brittle! What if you were to place something on the page and then something else comes along after it? Maybe you have an icon within a navigation that you always want in the top-left corner, but a third party comes in and puts in a banner ad. (I’m not advocating for banner ads, but they do exist.) This pushes the navigation down and now the icon is out of place.

Or, let’s say you want to make a self-contained component that you can use in multiple places. You need it to be reusable and work within its own context, no matter where you use it.

If we put position: relative; on the parent element, anything inside of it with position: absolute; will be placed absolutely, relative to that containing unit!

.child {   /* ... */   position: absolute;   top: 0;   left: 0; }  .parent {   position: relative; }

See the Pen
CSS Stacking, Absolute 2
by Sarah Drasner (@sdras)
on CodePen.

Nice.

We can use this same premise if we wanted to stack two elements on top of each other. Here, we’ll have two child elements stacked on top of one another and set apart by 150 pixels. We’ll see that they’re now contained in that same parent and stay positioned inside it.

<div class="parent">   <h2>Parent</h2>    <div class="child child-1">     <h2>Child 1</h2>   </div>    <div class="child child-2">     <h2>Child 2</h2>   </div> </div>
.child {   position: absolute;   top: 0; }  .child-1 {   left: 0; }  .child-2 {   left: 150px; }  .parent {   position: relative; }

See the Pen
CSS Stacking, Absolute 3
by Sarah Drasner (@sdras)
on CodePen.

This is a little old school, but I’ve been using it for years and I still reach for it. It works consistently across browsers and can help you achieve even the strangest and unique placements.

Method 2: Using CSS Grid

Another nice way of overlapping elements, stacking them, or modifying their placement is CSS Grid, depending on how far back you need to support (which you can check with caniuse).

We can place something where we need it in the container like this:

.parent {   display: grid;   grid-template-columns: 250px 1fr;   grid-template-rows: 150px 1fr; }  .child {   grid-area: 1 / 1 / 2 / 2; }

See the Pen
CSS Stacking, Grid 1
by Sarah Drasner (@sdras)
on CodePen.

And if one element should stack on the other, we can put them in the exact same grid area. Let’s also offset them slightly by using a margin.

.parent {   display: grid;   grid-template-columns: 250px 1fr;   grid-template-rows: 150px 1fr; }  .child {   grid-area: 1 / 1 / 2 / 2; }  .child-2 {   margin-left: 200px; }

See the Pen
CSS Stacking, Grid 2
by Sarah Drasner (@sdras)
on CodePen.

If you find this technique difficult to visualize, I’ve created a CSS Grid Generator that hopefully helps see things more clearly.


There are so many places to use these techniques! You can stack, layer and offset elements. You can make navigations, footers. You can create just about any type of layout where you want to have more fine-grain control of how elements are placed on a page.

The post How to Stack Elements in CSS appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

What Does it Mean to Be “Full Stack”?

I was asked this recently by a fellow developer who was at the same web tech conference I was at. This developer had met a lot of new people who literally introduced themselves as full-stack developers sort of the way Bob Vance, Vance Refrigeration would on The Office, but it was Tony Frank, Full-Stack Developer instead.

I suspect the developer asking the question taken from the title of this post already knew the basic idea of what people mean by “full-stack developer,” but was wondering what the heck it’s all about. There was a tone in the question. A tone that suggested this person isn’t exactly in love with the term.

These days, probably a bit of DevOps (e.g. Git, testing, and getting sites to production). The “stack” is all these things combined, so a full-stack developer is shorthand for: when it comes to building websites, I can do it all.

There are some stacks that have achieved notoriety over the years. Maybe you’ve heard of the LAMP stack?

Linux Apache MySQL PHP

A full-stack developer on that stack means you know Linux, Apache, MySQL, and PHP. (Abstractly: server software, web server, database, back-end language.) This site runs on that stack, and I’m solely responsible for its development, so I guess I’m a full-stack developer in some loose sense.

But “loose” is a generous interpretation. I don’t know the first thing about Linux, except that’s what runs my web servers. I don’t know much about Apache, except that I sometimes use HTAccess directives to do things. I could count the number of MySQL queries I’ve written on my two hands, and I only really know PHP in the context of WordPress.

Looked at that way, I’m barely a developer at all. Full stack, on the other hand, generally refers to tossing front-end tasks into the mix and I’m competent enough in that space that my front-end skill set alone, has allowed me to build dozens (or hundreds!) of sites throughout my career. Full-stack-enough, anyway.

There are loads of other stacks.

LAMP isn’t particularly prescriptive about how you build the front-end. It came from an era where it was assumed you’d build a back end to spit out HTML and that’s your front end.

Another stack that’s achieved notoriety since the Grand Arrival of JavaScript is the MEAN stack.

MongoDB Express Angular Node

It is perfectly plausible to replace parts of a stack. Perhaps you’d use Nginx instead of Apache, or PostgreSQL instead of MySQL in what’s otherwise LAMP stack. MEAN is notable in that every layer of the stack was replaced with new technology. Node brought JavaScript to the back end, which could power web servers, handle routing, connect data sources, run build processes, compile code, and more.

A full-stack developer in this world is writing nearly everything in JavaScript. No wonder there is somewhat of an explosion of people considering themselves “full” stack. A single language, like JavaScript, that runs in browsers itself and is a paramount front-end technology is a widely transferrable skill.

The MEAN stack can have layers swapped out just as easily as LAMP. Perhaps you use a data store like Fauna or Firebase instead. Perhaps you use Vue or React instead of Angular. Perhaps you don’t need Express because you leave your routing to a framework or do it client-side.

Shawn Wang calls another a popular stack STAR:

Design Systems TypeScript Apollo React

That’s JavaScript all the way down.

It’s notable that, while we’re still thinking of this as a stack, we’re thinking less about our servers and server software to the point they aren’t really a key part of the stack. Not that developers and companies don’t take it seriously, but it’s more abstracted now than it has traditionally been. I’d point to the world of serverless as a case in point. The questions aren’t about what operating system our servers should use; it’s what platform is the most cost-effective to run our JavaScript functions.

So, stacks evolve over time. But it’s not just what technologies they use, but what technology we even consider a part of a stack. What full-stack means morphs over time.. We’re in a place right now where knowing JavaScript grants you a full-stack merit badge. You can work with client site frameworks, architect components and piece them together to build an entire front end. You can write web servers. You can write back-end code that talks to APIs. You can do all the state management you need. You can construct build processes and deployment pipelines. You can even bring CSS into JavaScript if you’re so inclined.

Even if you’re largely focused on JavaScript, people’s skillsets are generally wider than that. Throw in some HTML and CSS competency, Git foo, and a little DevOps hobby and you’re a real web powerhouse. You can do it all! A renaissance man! Lord of the seven kingdoms!

I think that’s kinda awesome, actually. It truly empowers developers. While it’s worth considering where the barriers of entrance for front-end development or high, it’s also interesting to consider all the places where that bar has been lowered. It’s particularly cool for me to see front-end development grow and grow to the point of nearly swallowing up the entire stack. The All-Powerful Front-End Developer, as it were.

It reminds me an awful lot of how powerful being a WordPress site-slinger feels. You can do a lot, even if you don’t deeply understand every little bit of it.

My conference acquaintance went on:

Why are some developers so proud of being a full stack? Many of them say it with a prideful smile. They, for some reason, feel the need to emphasize full stack when introducing themselves.

I suspect it’s just that: Pride.

Pride is a tricky thing. It meant the world to me when my parents ceaselessly told me they were proud of me or something I did. A positive thing on both sides. But, strangely enough, pride is also one of the seven deadly sins and one, as they say, that might be the root of all the rest. I don’t want to over-blow things, but I think there is some connection here. It’s one thing to be empowered and to feel strong and capable, but it’s another to be boastful and not sense the edges of your ability.

We’ve all got plenty of edges, particularly when it comes to doing an exemplary job versus merely getting the job done. Standing out these days requires being exemplary. How is your visual design skill? Are you building design systems or implementing existing ones? How many years have you maintained systems? Do you have a good eye for the most painful kinds of technical debt? How are you at helping co-workers succeed? Can you facilitate a user testing session? How good are you at diagnosing performance bottlenecks? What if there are serious server problems? Does your full stack moniker help you comprehend server logs? Are you versed in accessibility audits? Have you ever dealt with tricky relational data and slow queries?

I’m not trying to convince anyone they aren’t a full-stack developer or don’t deserve that particular merit badge — just that the web is a big place with divergent needs and ever-morphing stacks that all require different sets of skills. If you’re interviewing for a job asking for a full-stack developer, by all means, tell them how full-stack-y you are.

The post What Does it Mean to Be “Full Stack”? appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Swipeable card stack using Vue.js and interact.js

I recently had an opportunity to work on a fantastic research and development project at Netguru. The goal of project (codename: “Wordguru”) was to create a card game that anyone can play with their friends. You can see the outcome here.

One element of the development process was to create an interactive card stack. The card stack had a set of requirements, including:

  • It should contain a few cards from the collection.
  • The first card should be interactive.
  • The user should be able to swipe the card in different directions that indicate an intent to accept, reject or skip the card.

This article will explain how to create that and make it interactive using Vue.js and interact.js. I created an example for you to refer to as we go through the process of creating a component that is in charge of displaying that card stack and a second component that is responsible for rendering a single card and managing user interactions in it.

View Demo

Step 1: Create the GameCard component in Vue

Let’s start by creating a component that will show a card, but without any interactions just yet. We’ll call this file GameCard.vue and, in the component template, we’ll render a card wrapper and the keyword for a specific card. This is the file we’ll be working in throughout this post.

// GameCard.vue <template>   <div     class="card"     :class="{ isCurrent: isCurrent }"   >     <h3 class="cardTitle">{{ card.keyword }}</h3>   </div> </template>

In the script section of the component, we receive the prop card that contains our card content as well as an isCurrent prop that gives the card a distinct look when needed.

export default {   props: {     card: {       type: Object,       required: true     },     isCurrent: {       type: Boolean,       required: true     }   } },

Step 2: Create the GameCardStack component in Vue

Now that we have a single card, let’s create our card stack.

This component will receive an array of cards and render the GameCard for each card. It’s also going to mark the first card as the current card in the stack so a special styling is applied to it.

// GameCardsStack.vue <template>   <div class="cards">     <GameCard       v-for="(card, index) in cards"       :key="card"       :card="card"       :is-current="index === 0"     />   </div> </template>  <script>   import GameCard from "@/components/GameCard";   export default {     components: {       GameCard     },     props: {       cards: {         type: Array,         required: true       }     }   }; </script>

Here’s what we’re looking at so far, using the styles pulled from the demo:

At this point, our card looks complete, but isn’t very interactive. Let’s fix that in the next step!

Step 3: Add interactivity to GameCard component

All our interactivity logic will live in the GameCard component. Let’s start by allowing the user to drag the card. We will use interact.js to deal with dragging.

We’ll set the interactPosition initial values to 0 in the script section. These are the values that indicate a card’s order in the stack when it’s moved from its original position.

<script> import interact from "interact.js";  data() {   return {     interactPosition: {       x: 0,       y: 0     },   }; }, // ... </script>

Next, we create a computed property that’s responsible for creating a transform value that’s applied to our card element.

// ... computed: {   transformString() {     const { x, y } = this.interactPosition;     return `translate3D($ {x}px, $ {y}px, 0)`;   } }, // ...

In the mounted lifecycle hook, we make use of the interact.js and its draggable method. That method allows us to fire a custom function each time the element is dragged (onmove). It also exposes an event object that carries information about how far the element is dragged from its original position. Each time user drags the card, we calculate a new position of the card and set it on the interactPosition property. That triggers our transformString computed property and sets new value of transform on our card.

We use the interact onend hook that allows us to listen when the user releases the mouse and finishes the drag. At this point, we will reset the position of our card and bring it back to its original position: { x: 0, y: 0 }.

We also need to make sure to remove the card element from the Interactable object before it gets destroyed. We do that in the beforeDestroy lifecycle hook by using interact(target).unset(). That removes all event listeners and makes interact.js completely forget about the target.

// ... mounted() {   const element = this.$ refs.interactElement;   interact(element).draggable({     onmove: event => {       const x = this.interactPosition.x + event.dx;       const y = this.interactPosition.y + event.dy;       this.interactSetPosition({ x, y });     },     onend: () => {       this.resetCardPosition();     }   }); }, // ... beforeDestroy() {   interact(this.$ refs.interactElement).unset(); }, // ... methods: {   interactSetPosition(coordinates) {      const { x = 0, y = 0 } = coordinates;     this.interactPosition = {x, y };   },      resetCardPosition() {     this.interactSetPosition({ x: 0, y: 0 });   }, }, // ...

We need to add one thing in our template to make this work. As our transformString computed property returns a string, we need to apply it to the card component. We do that by binding to the :style attribute and then passing the string to the transform property.

<template>   <div      class="card"     :class="{ isCurrent: isCurrent }"     :style="{ transform: transformString }"   >     <h3 class="cardTitle">{{ card.keyword }}</h3>   </div> </template>

With that done, we have created interaction with our card — we can drag it around!

You may have noticed that the behavior isn’t very natural, specifically when we drag the card and release it. The card immediately returns to its original position, but it would be more natural if the card would go back to initial position with animation to smooth the transition.

That’s where transition comes into play! But adding it to our card introduces another issue: there’s a lag in the card following as it follows the cursor because transition is applied to the element at all times. We only want it applied when the drag ends. We can do that by binding one more class (isAnimating) to the component.

<template>   <div     class="card"     :class="{       isAnimating: isInteractAnimating,       isCurrent: isCurrent     }"   >     <h3 class="cardTitle">{{ card.keyword }}</h3>   </div> </template>

We can add and remove the animation class by changing the isInteractAnimating property.

The animation effect should be applied initially and we do that by setting our property in data.

In the mounted hook where we initialize interact.js, we use one more interact hook (onstart) and change the value of isInteractAnimating to false so that the animation is disabled when the during the drag.

We’ll enable the animation again in the onend hook, and that will make our card animate smoothly to its original position when we release it from the drag.

We also need to update transformString computed property and add a guard to recalculate and return a string only when we are dragging the card.

data() {   return {   // ...   isInteractAnimating: true,   // ...   }; },  computed: {   transformString() {     if (!this.isInteractAnimating) {       const { x, y } = this.interactPosition;       return `translate3D($ {x}px, $ {y}px, 0)`;     }     return null;   } },  mounted() {   const element = this.$ refs.interactElement;   interact(element).draggable({     onstart: () => {       this.isInteractAnimating = false;     },     // ...     onend: () => {       this.isInteractAnimating = true;     },   }); },

Now things are starting to look nice!

Our card stack is ready for second set of interactions. We can drag the card around, but nothing is actually happening — the card is always coming back to its original place, but there is no way to get to the second card.

This will change when we add logic that allows the user to accept and rejecting cards.

Step 4: Detect when the card is accepted, rejected, or skipped

The card has three types of interactions:

  • Accept card (on swipe right)
  • Reject card (on swipe left)
  • Skip card (on swipe down)

We need to find a place where we can detect if the card was dragged from its initial position. We also want to be sure that this check will happen only when we finish dragging the card so the interactions do not conflict with the animation we just finished.

We used that place earlier smooth the transition during animation — it’s the onend hook provided by the interact.draggable method.

Let’s jump into the code.

First, we need to store our threshold values. Those values are the distances as the card is dragged from its original position and allows us to determine if the card should be accepted, rejected, or skipped. We use X axis for right (accept) and left (reject), then use the Y axis for downward movement (skip).

We also set coordinates where we want to place a card after it gets accepted, rejected or skipped (coordinates out of user’s sight).

Since those values will not change, we will keep them in the static property of our component, which can be accessed with this.$ options.static.interactYThreshold.

export default {   static: {     interactYThreshold: 150,     interactXThreshold: 100   },

We need to check if any of our thresholds were met in our onend hook and then fire the appropriate method that happened. If no threshold is met, then we reset the card to its initial position.

mounted() {   const element = this.$ refs.interactElement;   interact(element).draggable({     onstart: () => {...},     onmove: () => {...},     onend: () => {       const { x, y } = this.interactPosition;       const { interactXThreshold, interactYThreshold } = this.$ options.static;       this.isInteractAnimating = true;                  if (x > interactXThreshold) this.playCard(ACCEPT_CARD);       else if (x < -interactXThreshold) this.playCard(REJECT_CARD);       else if (y > interactYThreshold) this.playCard(SKIP_CARD);       else this.resetCardPosition();     }   }); }

OK, now we need to create a playCard method that’s responsible for handling those interactive actions.

Step 5: Establish the logic to accept, reject, and skip cards

We will create a method that accepts a parameter telling us the user’s intended action. Depending on that parameter, we will set the final position of the current card and emit the accept, reject, or skip event. Let’s go step by step.

First, our playCard method will remove the card element from the Interactable object so that it stops tracking drag events. We do that by using interact(target).unset().
Secondly, we set the final position of the active card depending on the user’s intention. That new position allows us to animate the card and remove it from the user’s view.

Next, we emit an event up to the parent component so we can deal with our cards (e.g. change the current card, load more cards, shuffle the cards, etc.). We want to follow the DDAU principle that states a component should refrain from mutating data it doesn’t own. Since our cards are passed down to our component, it should emit an event up to the place from where those cards come.

Lastly, we hide the card that was just played and add a timeout that allow the card to animate out of view.

methods: {   playCard(interaction) {     const {       interactOutOfSightXCoordinate,       interactOutOfSightYCoordinate,     } = this.$ options.static;      this.interactUnsetElement();      switch (interaction) {       case ACCEPT_CARD:         this.interactSetPosition({           x: interactOutOfSightXCoordinate,         });         this.$ emit(ACCEPT_CARD);         break;       case REJECT_CARD:         this.interactSetPosition({           x: -interactOutOfSightXCoordinate,         });         this.$ emit(REJECT_CARD);         break;       case SKIP_CARD:         this.interactSetPosition({           y: interactOutOfSightYCoordinate         });         this.$ emit(SKIP_CARD);         break;     }      this.hideCard();   },    hideCard() {     setTimeout(() => {       this.isShowing = false;       this.$ emit("hideCard", this.card);     }, 300);   },      interactUnsetElement() {     interact(this.$ refs.interactElement).unset();     this.interactDragged = true;   }, }

And, there we go!

Summary

Let’s recap what we just accomplished:

  • First we created a component for a single card.
  • Next we created another component that renders the cards in a stack.
  • Thirdly, we implemented interact.js to allow interactive dragging.
  • Then we detected when the user wants takes an action with the current card.
  • Finally, we established the to handle those actions.

Phew, we covered a lot! Hopefully this gives you both a new trick in your toolbox as well as a hands-on use case for Vue. And, if you’ve ever had to build something similar, please share in the comments because it would be neat to compare notes.

The post Swipeable card stack using Vue.js and interact.js appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]