Front End Web Development

Breaking Out with CSS Grid Explained

Css Tricks - Tue, 06/06/2017 - 2:26am

Tyler Sticka shared a slick technique for breaking out content in a CSS Grid layout, but Rachel Andrew goes the extra mile to explain why the technique works:

When you name lines, you can optionally name them as *-start and *-end and this gives you a little more grid magic. We get a named grid area of the main name used. Sounds odd? Take a look at the diagram below, it shows 4 named grid lines, main-start and main-end both for columns and rows. The area marked out by the intersection of these lines can now be referenced by the name main. If we had named the lines foo-start and foo-end then we would have a named area called foo.

Rachel's post stood out to me for a number of reasons. First, I love blog posts as responses to other blog posts. Second, it's an excellent reminder that sharing how a concept works is equally as important as showing that it works. Lastly, the concept of implicitly named grid areas based on named grid lines is as good a reason as any to roll up our sleeves and get cozy with the spec. In fact, following Rachel's series on the CSS Grid spec is a good starting point.

As a side note, Tyler's clever use of named Grid lines reminded me of Dave Rupert's equally crafty use of :not to achieve a similar full bleed effect.

Direct Link to ArticlePermalink

Breaking Out with CSS Grid Explained is a post from CSS-Tricks

Fun with Viewport Units

Css Tricks - Mon, 06/05/2017 - 2:50am

Viewport units have been around for several years now, with near-perfect support in the major browsers, but I keep finding new and exciting ways to use them. I thought it would be fun to review the basics, and then round-up some of my favorite use-cases.

What are viewport units?

Four new "viewport-relative" units appeared in the CSS specifications between 2011 and 2015, as part of the W3C's CSS Values and Units Module Level 3. The new units – vw, vh, vmin, and vmax - work similarly to existing length units like px or em, but represent a percentage of the current browser viewport.

  • Viewport Width (vw) – A percentage of the full viewport width. 10vw will resolve to 10% of the current viewport width, or 48px on a phone that is 480px wide. The difference between % and vw is most similar to the difference between em and rem. A % length is relative to local context (containing element) width, while a vw length is relative to the full width of the browser window.
  • Viewport Height (vh) – A percentage of the full viewport height. 10vh will resolve to 10% of the current viewport height.
  • Viewport Minimum (vmin) – A percentage of the viewport width or height, whichever is smaller. 10vmin will resolve to 10% of the current viewport width in portrait orientations, and 10% of the viewport height on landscape orientations.
  • Viewport Maximum (vmax) – A percentage of the viewport width or height, whichever is larger. 10vmin will resolve to 10% of the current viewport height in portrait orientations, and 10% of the viewport width on landscape orientations. Sadly, and strangely, vmax units are not yet available on Internet Explorer or Edge.

While these units are derived from viewport height or width, they can all be used everywhere lengths are accepted – from font-size to positioning, margins, padding, shadows, borders, and so on. Let's see what we can do!

Responsive Typography

It's become very popular to use viewport units for responsive typography – establishing font-sizes that grow and shrink depending on the current viewport size. Using simple viewport units for font-size has an interesting (dangerous) effect. As you can see, fonts scale very quickly – adjusting from unreadably small to extra large in a very small range.

This direct scaling is clearly too dramatic for daily use. We need something more subtle, with minimums and maximums, and more control of the growth rate. That's where calc() becomes useful. We can combine a base size in more steady units (say 16px) with a smaller viewport-relative adjustment (0.5vw), and let the browser do the math: calc(16px + 0.5vw)

See the Pen partially-Responsive Type by Miriam Suzanne (@mirisuzanne) on CodePen.

By changing the relationship between your base-size and viewport-relative adjustment, you can change how dramatic the growth-rate is. Use higher viewport values on headings, and watch them grow more quickly than the surrounding text. This allows for a more dynamic typographic scale on larger screens, while keeping fonts constrained on a mobile device - no media-queries required. You can also apply this technique to your line-height, allowing you to adjust leading at a different rate than the font-size.

body { // font grows 1px for every 100px of viewport width font-size: calc(16px + 1vw); // leading grows along with font, // with an additional 0.1em + 0.5px per 100px of the viewport line-height: calc(1.1em + 0.5vw); }

For me, this is enough complexity. If I need to constrain the top-end for rapid-growth headings, I can do that with one single media-query wherever the text becomes too large:

h1 { font-size: calc(1.2em + 3vw); } @media (min-width: 50em) { h1 { font-size: 50px; } }

Suddenly I wish there was a max-font-size property.

Others have developed more complex calculations and Sass mixins to specify the exact text-size ranges at specific media-queries. There are several existing CSS-Tricks articles that explain the technique and provide snippets to help you get started:

I think that's overkill in most cases, but your milage will absolutely vary.

Full-Height Layouts, Hero Images, and Sticky Footers

There are many variations on full-height (or height-constrained) layouts – from desktop-style interfaces to hero images, spacious designs, and sticky footers. Viewport-units can help with all of these.

In a desktop-style full-height interface, the page is often broken into sections that scroll individually – with elements like headers, footers, and sidebars that remains in place at any size. This is common practice for many web-apps these days, and vh units make it much simpler. Here's an example using the new CSS Grid syntax:

See the Pen Full-height CSS Grid by Miriam Suzanne (@mirisuzanne) on CodePen.

A single declaration on the body element, height: 100vh, constrains your application to the height of the viewport. Make sure you apply overflow values on internal elements, so your content isn't cut off. You can also achieve this layout using flexbox or floats.Note that full-height layouts can cause problems on some mobile browsers. There's a clever fix for iOs Safari, that we use to handle one of the most noticeable edge-cases.

Sticky-footers can be created with a similar technique. Change your body height: 100vh to min-height: 100vh and the footer will stay in place at the bottom of your screen until it's pushed down by content.

See the Pen Sticky-Footer with CSS Grid by Miriam Suzanne (@mirisuzanne) on CodePen.

Apply vh units to the height, min-height, or max-height of various elements to create full-screen sections, hero images, and more. In the new OddBird redesign, we constrained our hero images with max-height: 55vh so they never push headlines off the page. On my personal website, I went with max-height: 85vh for a more image-dominated look. On other sites, I've applied min-height: 90vh to sections.

Here's an example showing both a max-height heroic kitten, and a min-height section. Combining all these tricks can give you some powerful control around how your content fills a browser window, and responds to different viewports.

Fluid Aspect Ratios

It can also be useful to constrain the height-to-width ratio of an element. This is especially useful for embeded content, like videos. Chris has written about this before. In the good-old-days, we would do that with %-based padding on a container element, and absolute positioning on the inner element. Now we can sometimes use viewport units to achieve that effect without the extra markup.

If we can count on the video being full-screen, we can set our height relative to the full viewport width:

/* full-width * aspect-ratio */ .full-width { width: 100vw; height: calc(100vw * (9/16)); }

That math doesn't have to happen in the browser with calc. If you are using a pre-processor like Sass, it will work just as well to do the math there: height: 100vw * (9/16). If you need to constrain the max-width, you can constrain the max-height as well:

/* max-width * aspect-ratio */ .full-width { width: 100vw; max-width: 30em; height: calc(100vw * (9/16)); max-height: calc(30em * (9/16)); }

Here's a demonstration showing both options, with CSS custom properties (variables) to make the math more semantic. Play with the numbers to see how things move, keeping the proper ratio at all times:

See the Pen Fluid Ratios with Viewport Units by Miriam Suzanne (@mirisuzanne) on CodePen.

Chris takes this one step farther in his pre-viewport-units article, so we will too. What if we need actual HTML content to scale inside a set ratio - like presentation slides often do?

We can set all our internal fonts and sizes using the same viewport units as the container. In this case I used vmin for everything, so the content would scale with changes in both container height and width:

See the Pen Fluid Slide Ratios with Viewport Units by Miriam Suzanne (@mirisuzanne) on CodePen.

Breaking the Container

For years now, it's been popular to mix constrained text with full-width backgrounds. Depending on your markup or CMS, that can become difficult. How do you break content outside of a restricted container, so that it fills the viewport exactly?

Again, viewport units can come in handy. This is another trick we've used on the new OddBird site, where a static-site generator sometimes limits our control of the markup. It only takes a few lines of code to make this work.

.full-width { margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }

There are more in-depth articles about the technique, both at Cloud Four and here on CSS Tricks.

Getting Weird

Of course, there's much more you can do with viewport units, if you start experimenting. Check out this pure CSS scroll-indicator (made by someone named Mike) using viewport units on a background image:

See the Pen CSS only scroll indicator by Mike (@MadeByMike) on CodePen.

What else have you seen, or done with viewport units? Get creative, and show us the results!

Fun with Viewport Units is a post from CSS-Tricks

Using Filters in Vue.js

Css Tricks - Sat, 06/03/2017 - 1:06am

Filters are an interesting way to deal with data rendering in Vue but are only useful in a small amount of cases. The first thing to understand about filters is that they aren't replacements for methods, computed values, or watchers, because filters don't transform the data, just the output that the user sees. As of Vue 2.0, there are no built-in filters, we need to construct them ourselves.

We can use filters locally or globally, but it's worth mentioning that if you declare a Vue filter globally it should come before the Vue instance. In both cases, we would pass the value in as a parameter.

//global Vue.filter('filterName', function(value) { return // thing to transform }); //locally, like methods or computed filters: { filterName(value) { return // thing to transform } }

Filters are used with a pipe, following the piece of data you'd like to be altered upon render. So we would show the piece of data we want to alter, followed by the filter

{{ data | filter }}

Here's a small example, with a tip calculator:

See the Pen Filters by Sarah Drasner (@sdras) on CodePen.

new Vue({ el: '#app', data() { return { customer1total: 35.43 } }, filters: { tip15(value) { return (value*.15).toFixed(2) }, tip20(value) { return (value*.2).toFixed(2) }, tip25(value) { return (value*.25).toFixed(2) } } }); <div id="app"> <h2>Tip Calculator</h2> <p><strong>Total: {{ customer1total }}</strong></p> <p>15%: {{ customer1total | tip15 }}</p> <p>20%: {{ customer1total | tip20 }}</p> <p>25%: {{ customer1total | tip25 }}</p> </div>

You can also use filters in v-bind directives rather than just the mustache template. Filters can also be chained. Keep in mind if you're going to chain filters: ordering matters. The first filter will be applied first, the second will be applied to the completed first, and so on.

{{ data | filterA | filterB }}

We can also pass additional arguments into filters like so:

{{ data | filterName(arg1, arg2) }} // locally, like methods or computed filters: { filterName(value, arg1, arg2) { return //thing to transform } }

Now, you might think, based on the name, that filters would be great for forms when we want to show only some bits of data and not others. However, filters need to rerun on every single update, so if you have something like an input that updates every time you type, it's not very performant. Better to use computed for something like this as it's less overhead. The results will be cached based on their dependencies and won't be rerun on every update. Computed properties will only be reevaluated when those dependencies change, but can also handle complex logic. This makes them excellent candidates for filtering information based on input. There are, however, circumstances where you do need to update based on changes in time, and for these instances, better to use a method.

Using Filters in Vue.js is a post from CSS-Tricks

Intro to Firebase and React

Css Tricks - Fri, 06/02/2017 - 3:16am

Let's take a look at building something using Firebase and React. We'll be building something called Fun Food Friends, a web application for planning your next potluck, which hopefully feels like something rather "real world", in that you can imagine using these technologies in your own production projects. The big idea in this app is that you and your friends will be able to log in and be able to see and post information about what you're planning to bring to the potlock.

When we're finished, it will look like this:

Our example app: Fun Food Friends

This article assumes you already have some basic knowledge of how React works and maybe built a few small apps with React. If you haven't, I would recommend checking out a series like Wes Bos' React for Beginners first before continuing on.

What is Firebase?

Google's Firebase is a cloud-based database hosting service that will set up a database for you and host it, as well as offer you the tools to interact with it. You can use it to store and retrieve data in real time. That's not all Firebase does, it can do more things like handle user authentication and store files, but we'll be mainly focusing on data storage.

The data storage ability of Firebase make it a perfect fit for React. A persistent, real-time backend for your application to plug in to!

How does Firebase store data?

Firebase stores data as a giant object with key-value pairs. Unlike JSON or JavaScript objects, there are no arrays in Firebase.

A Firebase database might look something like this:

{ "groceries": { "-KjQTqG3R2dPT8s2jylW": "tomato", "-KjQTrds1feHT3GH_29o": "pasta", "-KjQTsmfBR8zN1SwPPT8": "milk", "-KjQTtnzt_jJZPoCHWUM": "sugar" }, "users": { "name": { "-KjQTyIfKFEVMYJRZ09X": "simon", "-KjQU-Xuy5s7I-On9rYP": "ryan", "-KjQU0MYVeKRsLuIQCYX": "sylvia" } } }

For more information on the nuances of structuring data in Firebase, you can read the amazing Firebase documentation.

Ready to start? Let's dig in!

Getting Started: Setting up Our App

We'll start by using the incredibly handy `create-react-app` package in order to quickly set up a new React project without having to worry about any build configuration. Open up your command line, and type the following:

npm install -g create-react-app create-react-app fun-food-friends cd fun-food-friends yarn add firebase --dev yarn start

This will boot up your app in the browser, and start a watch task in your terminal so that we can begin hacking away at the project. We're also installing the `firebase` package here as we'll need it for the next step.

Creating our Firebase Database

Now that our app is set up, we'll need to create an account and database on Firebase so that we can link up our application to it.

Head on over to Firebase's website, and click Get Started.

This will take you to a page where you’ll be asked to authenticate with your Google account. Select the account that you’d like this project to be affiliated with, and press OK.

This should take you to the Firebase console, which looks something like this:

Now let's create our project's database. Click Add Project. Let's call it "fun-food-friends" and press OK.

This will take you to your app's dashboard, which looks like this:

Since we'll be building a web app, select Add Firebase to your web app. This will trigger a popup with some code that looks like this:

<script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script> <script> // Initialize Firebase var config = { apiKey: "AIzaSyDblTESEB1SbAVkpy2q39DI2OHphL2-Jxw", authDomain: "fun-food-friends-eeec7.firebaseapp.com", databaseURL: "https://fun-food-friends-eeec7.firebaseio.com", projectId: "fun-food-friends-eeec7", storageBucket: "fun-food-friends-eeec7.appspot.com", messagingSenderId: "144750278413" }; firebase.initializeApp(config); </script>

Since we'll be importing Firebase into our project using ES6 modules, we won't need those script tags. That config object is important though: it's how we authenticate our React application with our Firebase database.

Hooking up our App to Firebase

Copy that whole config object, and head back over to your React project. Find your `src` folder, and create a file called `firebase.js`. Inside of it, let's import firebase, our config, and initialize our app:

// src/firebase.js import firebase from 'firebase' const config = { apiKey: "AIzaSyDblTESEB1SbAVkpy2q39DI2OHphL2-Jxw", authDomain: "fun-food-friends-eeec7.firebaseapp.com", databaseURL: "https://fun-food-friends-eeec7.firebaseio.com", projectId: "fun-food-friends-eeec7", storageBucket: "fun-food-friends-eeec7.appspot.com", messagingSenderId: "144750278413" }; firebase.initializeApp(config); export default firebase;

One last thing we'll need to do before we can dive into roughing out our App. We need to temporarily disable authentication requirements on our app so that we can add and remove items without needing to have any kind of user authentication flow.

From the Firebase Dashboard, on the left-hand side of the screen, you'll notice that there is a Database tab. Click on it. Then, on the right-hand side, under the subheading Realtime Database, you'll see a Rules tab. This will cause an object to appear that looks something like this:

{ "rules": { ".read": "auth != null", ".write": "auth != null" } }

We need to set .read and .write to both be equal to true, otherwise later, when we try to add data to our database from our application, Firebase won't let us. When you're finished, it should look something like this:

Make sure to click the Publish button.

And that's all there is to hooking up our database! Anytime we need a component of our application to connect with our Firebase database, we simply need to import our firebase module and we'll have direct reference to it.

Building out our App's Rough Skeleton

Let's build out a rough HTML skeleton for our application. We'll build a simple form with two inputs:

  1. A field where the user can submit their name
  2. A field where the user can enter what food they're bringing to the potluck.

Since our app is quite simple, we'll keep everything inside of one main component, `App.js`. Open up `src/App.js`, and remove the `App` component, replacing it with this basic skeleton:

import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; class App extends Component { render() { return ( <div className='app'> <header> <div className='wrapper'> <h1>Fun Food Friends</h1> </div> </header> <div className='container'> <section className='add-item'> <form> <input type="text" name="username" placeholder="What's your name?" /> <input type="text" name="currentItem" placeholder="What are you bringing?" /> <button>Add Item</button> </form> </section> <section className='display-item'> <div className='wrapper'> <ul> </ul> </div> </section> </div> </div> ); } } export default App; Get the CSS

I've prepared a little bit of CSS for you to paste into the `App.css` file, just so that our app doesn't look totally bland. If you want to grab it, just go here and copy and paste the raw contents you find there into your `src/App.css` file!

We'll also need to embed a link to Google Fonts and Font Awesome, so go ahead and open up `public/index.html` and add the following lines below the favicon:

<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <!-- add the lines below --> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

At this point, your app should look like this:

Connecting our Form to Component State

Before we can start adding data into our Firebase database, we need to connect our inputs to our component’s state, so that React can keep track of them.

First, let's carve out some space in our component's state - a space to keep track of the user using our app (username) and the item they intend to bring (currentItem). We'll do this by creating a constructor() hook for our app and setting a default value for our input's state there:

class App extends Component { constructor() { super(); this.state = { currentItem: '', username: '' } } // ....

We'll add a onChange event handlers to our inputs, as well as providing them with a value derived from our state (this is called a "controlled input"), like this:

<section className="add-item"> <form> <input type="text" name="username" placeholder="What's your name?" onChange={this.handleChange} value={this.state.username} /> <input type="text" name="currentItem" placeholder="What are you bringing?" onChange={this.handleChange} value={this.state.currentItem} /> <button>Add Item</button> </form> </section>

And finally, we'll create a catch-all handleChange method that receives the event from our inputs, and updates that input's corresponding piece of state:

handleChange(e) { this.setState({ [e.target.name]: e.target.value }); }

If you aren't familiar with using brackets to dynamically determine key name in an object literal, check out the MDN docs on computed properties.

Since we're using ES6 classes and need access to this in our handleChange method, we'll also need to bind it back in our constructor() component like this:

constructor() { super(); this.state = { username: '', currentItem: '' } this.handleChange = this.handleChange.bind(this); }

If you now use the React DevTools to inspect your App component's state, you'll see that both of your inputs are now successfully hooked up and being tracked in your component's state:

Adding a new Potluck Item to your Database

Now that we're tracking our inputs, let's make it so that we can add a new item to our database so that Firebase can keep track of it.

First we'll need to connect to Firebase in order to do this, we'll start by importing our firebase module that we created earlier. We'll also delete the logo.svg import, since it's just an unneeded part of the create-react-app boiler plate and will cause warnings if we don't:

import React, { Component } from 'react'; import logo from './logo.svg'; // <--- remove this line import './App.css'; import firebase from './firebase.js'; // <--- add this line

Once that's done, we'll need to make our 'Add Item' button let Firebase know what we'd like to add to our database and where we'd like to put it.

First we'll attach a submit event listener for our form, and have it call a handleSubmit method we'll write in a minute:

<form onSubmit={this.handleSubmit}> <input type="text" name="username" placeholder="What's your name?" onChange={this.handleChange} value={this.state.username} /> <input type="text" name="currentItem" placeholder="What are you bringing ?" onChange={this.handleChange} value={this.state.currentItem} /> <button>Add Item</button> </form>

Don't forget to bind it in the constructor!

constructor() { super(); this.state = { currentItem: '', username: '' } this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); // <-- add this line }

And now add the handleSubmit method to your component:

handleSubmit(e) { e.preventDefault(); const itemsRef = firebase.database().ref('items'); const item = { title: this.state.currentItem, user: this.state.username } itemsRef.push(item); this.setState({ currentItem: '', username: '' }); }

Let's break down what's going here:

  • e.preventDefault() - we need to prevent the default behavior of the form, which if we don't will cause the page to refresh when you hit the submit button.
  • const itemsRef = firebase.database().ref('items'); - we need to carve out a space in our Firebase database where we'd like to store all of the items that people are bringing to the potluck. We do this by calling the ref method and passing in the destination we'd like them to be stored (items).
  • const item = { /* .. */ } here we grab the item the user typed in (as well as their username) from the state, and package it into an object so we ship it off to our Firebase database.
  • itemsRef.push(item) similar to the Array.push method, this sends a copy of our object so that it can be stored in Firebase.
  • Finally this.setState({ currentItem: '', username: '' }); is just so that we can clear out the inputs so that an additional item can be added.

Now try adding a new item, and hitting submit! If you don't have any errors in your console, you should be able to head on over to the Firebase dashboard, where you'll see something like this inside your Database tab:

If you click the little + next to items you'll be able to look inside, like this:

That strange looking -Kk8lHSMqC5oP6Qai0Vx key you see is a programmatically generated key created by Firebase when we called the push method, but inside you'll find whatever item you added to the Potluck.

You'll notice that all of our records are stored as objects with properties that have the generated names you see above - just another quick reminder that there are no arrays in Firebase!

Try adding more items and see what happens.

Way to go! We're almost there, but we still have one more step: getting our potluck items to appear on the page.

Retrieving our Potluck Items from the database

Just like in a traditional React app, we need to find some way to keep track of all of the potluck dishes so that we can display what people are planning to bring on to the page.

Without a database, this poses an issue, since every time we refresh the page any new dishes that were added to the potluck would get lost. But with Firebase, this is a snap to fix!

First, let's create a variable called items inside of default state. This will eventually hold all of the potluck items that are currently being tracked inside of our Firebase database.

constructor() { super(); this.state = { currentItem: '', username: '', items: [] } this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); }

Next, we need to actually grab those items from our Firebase database so that we can store them into our state.

The Firebase API offers us an incredibly easy way to not only grab this kind information from our database, but also to update us when new values get added to our database. It accomplishes this using the value custom event listener.

It looks like this:

itemsRef.on('value', (snapshot) => { console.log(snapshot.val()); });

The callback here, which we've called snapshot, provides you with a bird's eye overview of the items ref inside of your database. From here, you can easily grab a list of all of the properties inside of that items ref, using the .val() method which you can call on the snapshot.

This value automatically fires on two occassions:

  1. Any time a new item is added or removed from our items reference inside of our database
  2. The first time the event listener is attached

This makes it especially useful for initially grabbing a list of all of the items inside of our database, and then subsequently tracking when new items get added and removed.

We'll attach this event listener inside of our componentDidMount, so that we start tracking our Potluck items as soon as our component loads on to the page:

componentDidMount() { const itemsRef = firebase.database().ref('items'); itemsRef.on('value', (snapshot) => { let items = snapshot.val(); let newState = []; for (let item in items) { newState.push({ id: item, title: items[item].title, user: items[item].user }); } this.setState({ items: newState }); }); }

Here, we instantiate a new array and populate it with the results that come back from our value listener. We for…in over each key, and push the result into an object inside our newState array. Finally, once all the keys are iterated over (and therefore all items are grabbed from our database), we update the state with this list of items from our database.

Inspect your App using the React Dev Tools - you'll notice that you now have an items property inside of your state with all of the items people have submitted for your potluck!

Displaying Potluck Items on the Page

Now let's get these potluck items to actually display on the page. This is relatively easy, now that we have a list of all of our items being grabbed from Firebase and stored inside of our state. We just map over it and print the results on to the page, like so:

<section className='display-item'> <div className="wrapper"> <ul> {this.state.items.map((item) => { return ( <li key={item.id}> <h3>{item.title}</h3> <p>brought by: {item.user}</p> </li> ) })} </ul> </div> </section>

Try adding a new item through your form. You'll notice that it automatically causes a new list item to appear on the page!

It's not magic, Firebase's value event is firing when you push the new item into your database, and sending back a new snapshot with a list of all of the items currently in your database, which ultimate updates your component through a setState which triggers a re-render and displays the new item on the page.

But we digress. There's still one more step! We need to make it so that we can remove an item from the page.

Removing Items from the Page

We'll need to create a new method on our component for this: removeItem. This method will need to be passed that unique key which serves as the identifier for each one of the items inside of our Firebase database.

It's very simple, and looks like this:

removeItem(itemId) { const itemRef = firebase.database().ref(`/items/${itemId}`); itemRef.remove(); }

Here, instead of grabbing all of the items as we did before when adding a new item, we instead look up a specific item by its key (that strange -Kk8lHSMqC5oP6Qai0Vx key from before). We can then call firebase.database()'s remove method, which strips it from the page.

Finally, we'll need to add a button to our UI with an onClick that calls our removeItem method and passes it the item's key, like follows:

{this.state.items.map((item) => { return ( <li key={item.id}> <h3>{item.title}</h3> <p>brought by: {item.user}</p> <button onClick={() => this.removeItem(item.id)}>Remove Item</button> </li> ) }) }

And that's all there is to it! Just like our addItem method, our UI and component state automatically update when an item is removed from the database.

Here's what our completed `App.js` should look like:

import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; import firebase from './firebase.js'; class App extends Component { constructor() { super(); this.state = { currentItem: '', username: '', items: [] } this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(e) { this.setState({ [e.target.name]: e.target.value }); } handleSubmit(e) { e.preventDefault(); const itemsRef = firebase.database().ref('items'); const item = { title: this.state.currentItem, user: this.state.username } itemsRef.push(item); this.setState({ currentItem: '', username: '' }); } componentDidMount() { const itemsRef = firebase.database().ref('items'); itemsRef.on('value', (snapshot) => { let items = snapshot.val(); let newState = []; for (let item in items) { newState.push({ id: item, title: items[item].title, user: items[item].user }); } this.setState({ items: newState }); }); } removeItem(itemId) { const itemRef = firebase.database().ref(`/items/${itemId}`); itemRef.remove(); } render() { return ( <div className='app'> <header> <div className="wrapper"> <h1>Fun Food Friends</h1> </div> </header> <div className='container'> <section className='add-item'> <form onSubmit={this.handleSubmit}> <input type="text" name="username" placeholder="What's your name?" onChange={this.handleChange} value={this.state.username} /> <input type="text" name="currentItem" placeholder="What are you bringing?" onChange={this.handleChange} value={this.state.currentItem} /> <button>Add Item</button> </form> </section> <section className='display-item'> <div className="wrapper"> <ul> {this.state.items.map((item) => { return ( <li key={item.id}> <h3>{item.title}</h3> <p>brought by: {item.user} <button onClick={() => this.removeItem(item.id)}>Remove Item</button> </p> </li> ) })} </ul> </div> </section> </div> </div> ); } } export default App; Conclusion

Now you can truly see how Firebase and React play beautifully together. Firebase's ability to persist data on the fly, coupled with React's component lifecycle, makes for an incredibly simple and powerful way to quickly build up simple applications.

This article just scratches the surface of what the Firebase API can provide us. For example, with just a few more steps (and perhaps we will go over this in a future article), it would be incredibly easy to expand this application so that users could log in and out, be able to have a display photo next to the item that they are bringing, and only be able to remove their own items.

Happy Firebasing!

Intro to Firebase and React is a post from CSS-Tricks

Componentizing a Framework

Css Tricks - Fri, 06/02/2017 - 3:10am

I'm sure most of you understand how you work with a framework like Bootstrap, Foundation, or Materialize. You use their CSS and JavaScript. You also use their chunks of HTML, piecing together and applying classes as needed to do what you need to do.

You're on your own piecing the HTML together. That's good, because it's flexible. People use frameworks like this in all kinds of CMS's and backend systems. But what if you want to apply some structure to this, making actual components out of the components given to you in the framework?

That's exactly what Morgan Feeney did in Component-Led Design Patterns with Nunjucks & Grunt last year.

For example, Bootstrap gives you some HTML for alert messages, that are like this:"

<div class="alert alert-success" role="alert">...</div> <div class="alert alert-info" role="alert">...</div> <div class="alert alert-warning" role="alert">...</div> <div class="alert alert-danger" role="alert">...</div>

We could abstract that into a reusable component by:

  1. Pass in the type of alert (second half of the second class)
  2. Pass in the content inside the alert

I'm sure you could imagine doing that in the backend or templating language of your choice. A single PHP file in which you set variables representing those things before you include it. A Rails partial in which you pass locals to it. A literal React component in JSX where you pass the stuff as props. This kind of thing makes these patterns a lot easier to reuse.

Morgan did this with Nunjucks:

{% macro alert(class="success", text="<strong>Well done!</strong> You successfully read this important alert message.") %} <div class="alert alert-{{ class }}" role="alert"> {{ text | safe }} </div> {% endmacro %}

I think this is super compelling and the kind of thing we'll be doing more and more as design systems are becoming more of a standard practice.

I also think Nunjucks is pretty darn cool.

I ported Morgan's idea (which is already a repo) over to a CodePen Project if you'd like to have a play there.

Componentizing a Framework is a post from CSS-Tricks

Introducing Halyard from Darden Studio, plus more fonts for sync

Nice Web Type - Thu, 06/01/2017 - 8:30am

Darden Studio is based in Brooklyn and brought us Omnes, the original typeface of choice for the Typekit logo. The foundry has just released their newest typeface, Halyard — which we’re delighted to offer on Typekit.

Conceived and designed by Joshua Darden, Eben Sorkin, and Lucas Sharp, Halyard comprises three optical sizes — Display, Text, and Micro — each with eight weights and italics. The specimens on the foundry’s microsite for the typeface do a spectacular job of illustrating how these different sizes can be put to good use in all kinds of design work.

Halyard Micro, shown big.

Given the enormous flexibility on offer here, we won’t be surprised if Halyard becomes a new favorite sans-serif typeface for a lot of people. It’s made to perform exceptionally well in a number of different typesetting situations thanks to those optical sizes, and it’s fun to work with — especially Micro, whose creative letter and number shapes are worth seeing at larger sizes, too.

Micro for the body text, Display for headlines, and Text for graph labels and nameplates. All artwork by Darden Studio.

All weights and styles of Halyard are available for purchase from Typekit Marketplace, which you do not need a paid Creative Cloud subscription to use. All you need is an Adobe ID so that you can sync the fonts via the Creative Cloud desktop app. The fonts you purchase are then yours to use for as long as you keep the CC app running.

If you’ve already got a paid plan with Creative Cloud or with us, you now have access to the Regular and Bold weights (with italics) for all three sub-families of Halyard. Look for these in the library today. You might also want to poke around and see some of the other great typefaces from Darden Studio — all of which are now available for sync in addition to web use.

Congrats to Darden Studio on another fantastic design.


HelloSign: The Industry’s Fastest eSignature API Integration

Css Tricks - Thu, 06/01/2017 - 1:57am

My favorite kind of software products are the ones that very clearly make life simpler. Being able to legally sign a document by clicking a button in an email and squiggling my mouse to make my signature is definitely one of those things.

You can provide that to your users with HelloSign! You can set up your documents there (it supports all the formats you'd need, like PDF, Microsoft Word, Powerpoint, etc) and start collecting the signatures you need very easily. Set up templates of your commonly used documents. Make sure your branding is present during the signing process. Get notifications when documents are reviewed and signed.

There are a bunch more killer features you should be aware of. For example, like I mentioned, you can sign documents without ever leaving your email with their Chrome browser extension for Gmail. Same with Google Docs and Salesforce!

Perhaps most importantly, you can use HelloSign right from your own interface through their API. That's great for all us developers interested in building seamless useful experiences right in our own products. You can embed documents directly on your website with just a few lines of code!

Direct Link to ArticlePermalink

HelloSign: The Industry’s Fastest eSignature API Integration is a post from CSS-Tricks

Deletability

Css Tricks - Thu, 06/01/2017 - 1:53am

Kelly Sutton has written a post called Deletability and I've been thinking about it all day and how his ideas relate to writing CSS:

By working with code, we see that modularity and deletability are closely related. Properly modularized code is easy to delete.

Writing deletable code is writing good code.

Apparently, this is a common approach to writing software although I've never heard of this concept when taken to the front-end side of things. But! I think it should be a goal for us to have in mind when we’re naming classes or building complex layouts. And after mulling over this idea all day I think that questions like "can I throw this code away easily?" should be a measuring stick for whether we're doing a good job at writing CSS.

For example, a while back I was working on a project where the style of one checkbox element impacted the styling of another, completely unrelated checkbox. The code for each was splintered across multiple files and directories so designers on the team would constantly push back and forth, undoing each other's work in a mad attempt to solve their own problem without thinking about the much larger problems of inheritance and CSS design. They'd notice an issue in their own part of the app, change the CSS and move on with their lives. And I'm not trying to be a jerk here – some applications have tens of thousands of lines of CSS and apps can be devilishly complex so it's no wonder that they didn't see this problem coming up.

But if the original design of those checkboxes had been built with the concept of deletability in mind I think we'd have avoided this problem altogether. The line-height and font-size, color and background-color properties would've been isolated in the correct files. And so looking at one file we'd be able to see all of the code for this one specific element. In other words, the system would have made itself clear to us in an instant.

If in the future, we can begin to ditch large portions of our codebase without impacting unrelated components, then we deserve to raise a glass to ourselves for being so gosh darn smart this whole time.

Direct Link to ArticlePermalink

Deletability is a post from CSS-Tricks

Build a Style Guide Straight from Sass

Css Tricks - Thu, 06/01/2017 - 1:43am

Last fall, our dev team wanted to get started with style guides. We had added a new member to the team, and as he was getting up to speed, we realized how lacking our project documentation was. If you've ever been a new developer on a team with weak documentation, you know how confusing it can be to try to familiarize yourself with a dozen projects without documentation.

In deciding on a style guide method, we came up with two main requirements:

  1. Low Friction

    The style guide should be easy to find, easy to read, and easy to maintain.

    Something that fit into our existing development workflow would be awesome. Adding new directories for sample markup and documentation files would not be awesome.

  2. Platform Agnostic

    We work in WordPress, Drupal, and CakePHP most often, and we wanted something that would work the same way across all three platforms.

    We wanted this to be easily maintainable, and for us that meant keeping the documentation alongside the CSS.

The Basics of Node-KSS

To achieve our goals of a platform agnostic, low-friction style guide, we landed on kss-node, which is itself a Node.js implementation of Knyle Style Sheets (KSS), a Ruby library that:

... provides a methodology for writing maintainable, documented CSS within a team. Specifically, KSS is a documentation specification and styleguide format.

The basic principle is that your style guide is generated via comments you create in your CSS, SCSS, Sass, LESS, etc.

You write some CSS like this:

// Bold Button // // Use this class for a bolder, stronger looking button. // // Markup: // <button class="btn btn-bold">Click Me</button> // // Styleguide Components.Buttons.bold .btn.btn-bold { position: relative; font-weight: bold; text-transform: uppercase; }

And get this lovely output:

Screenshot of the generated documentation for the bold button

You are able to organize your documentation however you like and it generates a nice little navigation and document structure for you as well:

Because it lives inside your CSS, updating it fits naturally in existing development workflows. If you update some CSS properties, the style guide is automatically updated. If you need to update the documentation, the documentation text is sitting right on top of the component you are working on. Even if you never visit the generated style guide, you will see the style guide any time you open a CSS file. Low friction? Check.

Additionally, since we use CSS and build processes in all our web projects, it's as platform agnostic as we need it to be.

Let's get started!

Initial Setup

In your project directory, you want to install kss-node as a project dependency. We're also going to install michelangelo, a nice theme for the style guide:

$ npm install --save-dev kss michelangelo

You can verify that it was installed by running

$ ./node_modules/.bin/kss --version

We'll create a file named kss-config.json to configure our KSS settings.

Inside your file, create an object like this:

{ "title": "Title of the Style Guide", // Source tells KSS where the CSS, Sass, or SCSS is that it should parse for documentation comments. // Here we are assuming your sass is in a directory at the root level of your project. "source": "sass/", // Destination tells KSS where to compile your style guide to. "destination": "styleguide/", // Builder tells KSS where to look for a theme. // If you aren't using michelangelo, you don't need this. "builder": "node_modules/michelangelo/kss_styleguide/custom-template/", // CSS gives KSS the path to your CSS, so it can pull your styles into the style guide. // The path needs to be relative to your style guide destination. // Here, our style guide is in /styleguide and our compiled css is at our project root. "css": [ "../main.css" ] // If you want to include any javascript files, add this block, with the path to your javascript file. // Also relative to your style guide destination. // Optional. "js" : [ "../bundle.js" ] }

This assumes a simple project directory tree that looks like this:

js/ sass/ bundle.js index.html main.css

You can try compiling your style guide by running:

$ ./node_modules/.bin/kss --config kss-config.json

If you want a cleaner command to run, add a script to the scripts block in your package.json:

"scripts": { "kss": "kss --config kss-config.json" },

Now you can run $ npm run kss to compile your style guide. (I'll use this method going forward, but you can use $ ./node_modules/.bin/kss --config kss-config.json if you want).

Since we haven't written any documentation yet though, you will likely receive a message like:

Error: No KSS documentation discovered in source files.

Let's fix that by documenting our first component!

Create and Document a Simple Component

We'll create a sample post title component.

Here's our CSS:

.post-title { font-size: 3em; text-align: center; font-family: fantasy; }

To create our documentation, we'll create a comment:

// Post Title (this will be the title of your component) // // Large, **in charge**, and centered. (this is the description of your component. you can use markdown in here.) // // Markup (define the markup to be used in your styleguide): // // <h1 class="post-title">A Post Title</h1> // // Styleguide Components.article.post-title // (? this controls the organization of your style guide. Here, I'm filing this component inside Components / Article / Post Title) .post-title { font-size: 3em; text-align: center; font-family: fantasy; }

Run $ npm run kss and your style guide should compile! You can access it based on the destination path you gave it. In this example, we have a static site and I compiled it in /styleguide, so that's the url I will use to find it. Here's what it should look like if you are using the michelangelo theme (I've removed the comments in parentheses):

Post Title Documentation

Here's what happened:

  1. KSS created a documentation section for our post title, complete with the title, description, markup, and CSS that we provided. You can see the rendered HTML and CSS as well as the raw HTML.
  2. KSS saw that we nested our post title underneath Components / Article, so it created a Components top-level section and a Components.article section. Our post title is nested underneath both of these.
  3. KSS generated a navigation based on this hierarchy.

If you wanted to provide more information about Components, you could provide a documentation block (anywhere in your CSS, really) like this:

// Components // // Components are ingredients of our design system. They may be made up of smaller groups of styles. // // Styleguide Components

Likewise, you could provide more information about the article component by defining a documentation block that targets that item via the Styleguide Components.article method:

// Article // // An article is made up of a title, featured image, and some default // typographic settings for links, italics, bold, and blockquotes. // // Styleguide Components.article

With those new documentation blocks, compile your style guide again ($ npm run kss) and you will see your outline filled out a little more:

Components and article documentation Documenting Component States and Variations

Our post title component is very simple, but we'll need to display more complex information in our style guide. KSS can easily handle variations on components as well as interactive states like :hover or :focus. We'll document a button to show this.

Our button will have different styles for :focus and :hover, as well as a small variation and a large variation. Here is the CSS we'll start with:

.button { padding: 1em 2em; margin: .5em; display: inline-block; font-size: .9em; font-family: Helvetica, sans-serif; font-weight: bold; text-transform: uppercase; color: #f56476; background-color: #fff; border: 2px solid #f56476; transition: .2s color, .2s background-color, .2s border-color; } .button:hover { color: #fff; background-color: #f56476; } .button:focus { color: #3ddc97; border-color: currentColor; } .button--small { font-size: .5em; } .button--large { font-size: 1.5em; }

We'll format our documentation the same as we did for our post title with 2 additions: we're going to add a placeholder class of {{modifier_class}} to all of our elements that will get the modifier, and we'll define our states / variations directly underneath our markup. Our comment block will look like this (I've added some notes in parentheses):

// Buttons (title, same as before) // // Various button styles. (description, just as before) // // Markup: (we add the `{{modifier_class}}` to every element that has a modifier) // <a class="button {{modifier_class}}">Link Button</a> // <button class="button {{modifier_class}}">Button Element</button> // <input class="button {{modifier_class}}" type="button" value="Input Button" /> // // (a new modifiers section) // :hover - When user hovers over button. // :focus - When button is focused. // .button--small - A small button. // .button--large - A large button. // // Styleguide Components.button (organization, just as before)

You can see that I've added a variation for each of the variations I declared in my CSS. The format is:

// .class-name - Description

or

// :state - Description

When the styleguide is compiled, you get this new documentation:

Generated documentation for buttons

You can see that you now have an example of each of the states and variations that you described in the modifiers section, with the appropriate CSS applied.

This technique also works for more complex components than this button. Say you have a .card component with children elements inside that need to change when a user hovers over the card. To document that, you would add the {{modifier_class}} only to the .card element and specify the hover state just as we did above.

Organization

By default, sections will be organized alphabetically by their title. For instance, our button component will come after our article component in the examples above. However, if you want to change the order of components or other sections, you can provide a weight to the component. A higher weight will bring the component lower in its section. A lower weight will move the component higher in the section.

When using Sass or SCSS, I put my organizational comments inside my main.sass or wherever I am importing my partials. For example, on a recent project, I had a Typography section and Elements section both filed underneath a Base top-level section. Naturally, KSS would organize these sections alphabetically, but I wanted Typography to come first. Here's how I changed the weight in my main.sass file:

// Typography // // Weight: 1 // // Styleguide base.typography @import "base/typography" // Elements // // Weight: 2 // // Styleguide base.elements @import "base/elements" Color Palettes

The Michelangelo theme that we are using provides a cool color palette generator. If you are using Sass or SCSS, you can document your color variable names and KSS will format a little color palette block.

With a comment like this:

// Highlight Colors // // Colors we use for higlighting states. // // $highlight-blue - #1460aa, primary blue // $highlight-purple - #674172, secondary purple // $highlight-red - #d50000, danger red // // Styleguide Base.colors

KSS will create a color palette for easy reference like this:

Auto Compiling the Style Guide

Instead of running $ npm run kss every time we make a change to the CSS, we can add a watch task to regenerate the style guide every time our CSS files change. I'll document how to do it with npm Scripts and via Grunt next.

npm Scripts

We are already using npm scripts to build the style guide, we just need to add a script that will watch our style guide.

We'll use the onchange package. First install it:

$ npm install onchange --save-dev

Then add a new script in our scripts object:

"scripts": { "watch": "onchange 'sass/**/*.sass' -- npm run kss", "kss": "kss --config kss-config.json" },

The watch task tells onchange to watch the files we specified in our glob pattern ('sass/**/*.sass') and when it detects a change, run the command we specify after the --: npm run kss.

Now running $ npm run watch will watch our .sass files and regenerate our style guide every time it detects a change in our Sass.

Grunt

There is an official Grunt plugin for KSS, grunt-kss. You can configure it to watch your .sass or .scss files for changes and recompile the style guide as you develop it.

Here's a sample Grunt configuration. With this setup, you don't need a separate kss-config.json file, all the configuration can happen in your Gruntfile.

module.exports = function(grunt) { grunt.initConfig({ kss: { options: { title: 'Title of the Style Guide', builder: "./node_modules/michelangelo/kss_styleguide/custom-template/", css: [ "../path/to/compiled/css.css", ], js: [ "../path/to/compiled/javascript.js", ] }, dist: { src: "path/to/css/src", dest: "styleguide/", } }, watch: { sass: { files: [ './path/to/**/*.sass' ], tasks: ['kss'] }, } }); grunt.loadNpmTasks('grunt-kss'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('dev', ['kss', 'watch']); }

Running $ grunt dev will first generate the style guide, and then watch our .sass for changes and regenerate the style guide when it detects a change.

Wrap Up

There are more details regarding the comment parsing and other features I haven't mentioned here at the official KSS repo. You have more than enough to get started here but there are some things I didn't go into, including a custom home page, experimental/deprecation flags and helpers for preprocessors.

If you want to go even further, you can develop your own style guide in place of the Michelangelo theme we used. Check out the docs on using custom templates for more information.

Build a Style Guide Straight from Sass is a post from CSS-Tricks

Why the political hackers and algorithm stories are bullshit

QuirksBlog - Mon, 05/08/2017 - 5:16am

Now that the fascists singularly failed to carry France despite a last-minute attempt at one of those terrifying, democracy-destroying “hacker” jobs against Macron it’s time to call out the hacker and algorithm stories for the bullshit they are.

It was clear from the outset that the Macron leak contained many false documents. What I didn’t find out until today was that many (all?) of those false documents were planted by the Macron campaign itself (scroll down to last paragraphs) in an apparent counter-phishing attempt. That proves the hackers aren’t terribly clever (and didn’t read French).

Let’s look at what those terrifying hackers actually achieved:

  1. Clinton. The Clinton email revelations likely did have some influence on the US election outcome, but it is important to realise that it merely reinforced an already-existing story and was powerfully supported by the US press and the FBI director. In the absence of these occurrences, would the hackers have had the same success? I’m not sure they would have.
  2. Fillon. The Fillon corruption revelations clearly did influence the French elections, and, as far as I know, the data was new and genuine.
    Point is: if we assume the hackers are in Putin’s pay and advance his political agenda, they did a thoroughly lousy job. Fillon is a typical example of a “moderate right-wing” politician who can be made to coopt fascism, and who was genuinely pro-Russian (or, at least, anti-sanctions). The revelations destroyed his chance to win the presidency, and with Le Pen never a serious contender Fillon was exactly what Russia should have hoped for.
    So despite their apparent success the hackers failed in France.

And this, as far as I can see, is the total roster of successes for the hackers. One success thanks to powerful support from within US politics, and one apparent success that was a serious strategic error. To me, that doesn’t seem like evidence of a serious threat to democracy.

There are murky rumours surrounding the Brexit vote, but nothing has been conclusively proven, and I tend to look at the polls themselves as the main culprits. Though the vote was expected to be close, poll after poll after poll showed the Remain camp squeaking in a narrow victory. Thus, if you’re a moderate Remain supporter but are angry at the political caste, you could easily be led to believe that you can cast a protest vote with impunity because Remain is going to win anyway. Except that too many people made this decision, and the tables were turned and Brexit won.

To me, this is a MUCH more convincing explanation than shady conspiracy theories featuring billionaires, tech geniuses, and algorithms — especially when techies and moderate right-wing voters have a vested interest in pushing these stories.

Why do we believe it?

This leads to the question why we so desperately want to believe these stories of high-tech voter manipulation. As far as I can see there are two reasons.

First, it strokes our ego as technologists.

The tech sector is on the defense nowadays, with Facebook and Twitter refusing to do anything about fake news (except for “algorithms” and flags that aren’t going to solve anything — hire human editors, guys!), and with especially Uber under fire for extorting its employees who aren’t really employees. It is becoming clear that technology is not the instrument for salvation we’ve believed it to be for the past twenty years.

It may be that Silicon Valley’s dominance is coming to an end, and even if it isn’t the Valley needs to convince the rest of the world it’s worth keeping around. It needs to restore its magical appeal.

In that light, dark mutterings about hackers and genius algorithms that can throw entire elections are a gift from heaven. They prove tech’s continuing vital role in the world, and prove technology can do anything it sets its mind to. And we as techies have every reason in the world to reinforce this narrative, since it enhances our position as grand imperial wizards of the most important force in the universe.

Bull. Shit. But it strokes our egos and fills our wallets, so we fall for it.

Also, the evil geniuses with their algorithms are supposed work with Big Data, and if there’s anything that’s overrated right now in the tech scene it’s Big Data. But hey, these people can throw entire elections, so you’d better invest in that Big Data company, right? So the Big Data people have a vested interest in hyping these stories.

Second, it serves to absolve voters from responsibility.

Remember: fascism can only win if it is supported by the moderate right wing. This happened in the US back in November, and it will likely happen in the UK next month. But if you can say that you’re a soulless slave of genius algorithms, hey, then the responsibility is not yours. (Also, if you’re a soulless slave, should you have the vote?)

Bull. Shit. If you vote for a fascist party it’s your responsibility, and no one else’s.

The hacks are unimportant

So let’s pierce the bullshit and clearly state that these vaunted “hackers” are a relatively unimportant force that can only strengthen genuine trends that already exist in the political realm. The rest is all smoke and mirrors aimed at reinforcing the societal status of technologists, and of protecting the sensivities of “moderate” right-wing voters.

Also, these categories overlap in the upper reaches of Silicon Valley. I mean, libertarianism is also a part of fascism, though only for the upper classes who have achieved success and can therefore do anything they like. Triumph of the Will and all that. (The commoners should serve and obey, and combat the immigrants. Libertarianism is not for them; only for us.)

So there. Smoke and mirrors, nothing more. The current fascist crisis is not caused by tech geniuses, hackers, and algorithms, but by moderate right-wing voters in the US and the UK, where the outdated and silly political system forces them to vote either extreme right or moderate left. And they pick extreme right of their own free will.

Keep calm and perform historical analysis.

We techies should stop hyping and supporting bullshit articles about dangerous hackers and genius algorithms. Also, we should consider the possibility that the modern tech gospel has some fascist components at its heart — especially the myth of the genius innovator.

Wed, 12/31/1969 - 2:00pm
Syndicate content
©2003 - Present Akamai Design & Development.