Tag: Many

The Many Bad (and Good!) Patterns for Close Buttons

Manuel Matuzović details 10 bad HTML patterns for a close button. You know, stuff like this:

<a class="close" onclick="close()">×</a>

Why is that bad? There is no href there, so it really isn’t a link (close buttons aren’t links). Not to mention the missing href makes this “placeholder link” unfocusable. Plus, that symbol will be read as “multiplication” or “times”, which is not helpful (an “x” isn’t either).

What do you use instead?

There are plenty of good patterns too. If you prefer the visual look of a ×, then…

<button type="button">   <span class="sr-only">Close</span>   <span aria-hidden="true">×</span> </button>

…making sure you are accessibly hiding that close button.

Direct Link to ArticlePermalink

The post The Many Bad (and Good!) Patterns for Close Buttons appeared first on CSS-Tricks.

CSS-Tricks

, , , ,

How many CSS properties are there?

Tomasz Łakomy posted a joke tweet about naming all the CSS attributes and Tejas Kumar replied with a joke answer, going as far as making an npm module. You can even run a terminal command to see them:

npx get-all-css-properties

You’ll get 259 of them. The source code uses the website quackit.com for the data, which I’d never heard of. 🤷‍♂️

I would have probably looked at MDN, where some quick querySelectorAll handiwork in the console yields a different number: 584. But ooops, that’s full of selectors, at-rules, and other stuff. Their reference only lists 72, but says it’s incomplete.

W3Schools lists 228 of them. HTML Dog lists 125. Our almanac has 176, and I know we omit stuff on purpose (e.g. we file margin-left under margin instead of making its own entry).

The horse’s mouth?

520 distinct property names from 66 technical reports and 66 editors’ drafts.

The post How many CSS properties are there? appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

So Many Color Links

There’s been a run of tools, articles, and resources about color lately. Please allow me to close a few tabs by rounding them up here for your enjoyment.

Curated colors in context

Happy Hues demonstrates a bunch of color palettes in the context of the site itself. That’s a nice way to do it, because choosing nice colors isn’t enough — it’s all about context. It can go bad, as the Refactoring UI blog demonstrates.

Dynamic, Date-Based Color with JavaScript, HSL, and CSS Variables

Rob Weychert shows off how he created date-based color schemes (so that every single day of the past 30 years would have a unique color scheme, each day looking slightly different than the day before).

Calculating Color: Dynamic Color Theming with Pure CSS.

Una Kravets creates color themes just with CSS. No JavaScript. No CSS preprocessing. Just Custom Properties, HSL colors, and some calc() in Calculating Color: Dynamic Color Theming with Pure CSS.

Color Tools

We’ve tweeted about color tools a lot. We’ve even threaded them up from time-to-time.

Visualizing Every Pantone Color of the Year

Adam Fuhrer took 20 years of top Pantone colors and matched them with wonderful photos. I love that the photos link to the personal sites of the actual photographers. It weirdly reminds me that you can browse Dribbble by color.

A Handy Sass-Powered Tool for Making Balanced Color Palettes

Stephanie Eckles blogged about using Sass to do math on colors to calculate and graph their luminance, saturation, and lightness, which can give you a by-the-numbers look to see if your color scheme is cohesive or not.

Leonardo

Leonardo is an interactive color palette tool that helps interpolate colors and generate variations based on contrast ratio.

Color Puns

Nice.

The post So Many Color Links appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

How Many Websites Should We Build?

Someone emailed me:

What approach to building a site should I take?

  1. Build a single responsive website
  2. Build a site on a single domain, but detect mobile, and render a separate mobile site
  3. Build a separate mobile site on a subdomain

It’s funny how quickly huge industry-defining conversations fade from view. This was probably the biggest question in web design and development1 this past decade, and we came up with an answer: It’s #1, you should build a responsive website. Any other answer and you’re building multiple websites and the pain from that comes from essentially doubling the workload, splitting teams, communication problems across those teams, inconsistencies across the sites, and an iceberg of other pain points this industry has struggled with for ages.

But, the web is a big place.

This emailer specifically mentioned imdb.com as their example. IMDB is an absolutely massive site with a large team (they are owned by Amazon) and lots of money flying around. If the IMDB team decides they would be better off building multiple websites, well that’s their business. They’ve got the resources to do whatever the hell they want.

The post How Many Websites Should We Build? appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

The Many Ways to Link Up Shapes and Images with HTML and CSS

Different website designs often call for a shape other than a square or rectangle to respond to a click event. Perhaps your site has some kind of tilted or curved banner where the click area would be awkwardly large as a straight rectangle. Or you have a large uniquely shaped logo where you only want that unique shape to be clickable. Or you have an interactive image that responds differently when different regions of it are clicked.

You can surround those assets with an un-styled <a> tag to get a clickable rectangle that’s approximately the right size. However, you can also control the shape of that region with different techniques, making sure the target for your click area exactly matches what’s visible on the screen.

SVG shapes

If your click target is an image or a portion of an image, and you have the ability to choose SVG as its format, you already have a great deal of control over how that element will behave on your page. The simplest way to make a portion of an SVG clickable is to add an an SVG hyperlink element to the markup. This is as easy as wrapping the target with an <a> tag, just as you would a nested html element. Your <a> tag can surround a simple shape or more complex paths. It can surround a group of SVG elements or just one. In this example the link for the bullseye wraps a single circle element, but the more complex arrow shape is made up of two polygons and a path element.

See the Pen
target svg
by Bailey Jones (@bailey_jones)
on CodePen.

Note that I’ve used the deprecated xlink:href property in this demo to ensure that the link will work on Safari. The href alone would have worked in Internet Explorer, Chrome, and Firefox.

The only trick here is to make sure the <a> tag is inside the SVG markup and that the tag wraps the shape you want to be clickable. The viewbox for this SVG is still a rectangle, so wrapping the entire SVG element wouldn’t have the same effect.

Image maps

Let’s say you don’t have control over the SVG markup, or that you need to add a clickable area to a raster image instead. It’s possible to apply a clickable target to a portion of an <img> tag using an image map.

Image maps are defined separately from the image source. The map will effectively overlay the entire image element, but it’s up to you to define the clickable area. Unlike the hyperlink element in the SVG example, the coordinates in the image map don’t have anything to do with the definition of the source image. Image maps have been around since HTML 3, meaning they have excellent browser support. However, they can’t be styled with CSS alone to provide interactive cues, like we were able to do with SVG on hover — the cursor is the only visual indicator that the target area of the image can be clicked. There are, however, options for styling the areas with JavaScript.

W3 Schools has an excellent example of an image map using a picture of the solar system where the sun and planets are linked to close-up images of those targets — everywhere else in the image is un-clickable. That’s because the coordinates of the areas defined in their image map match the locations of the sun and planets in the base image.

Here’s another example from Derek Fogge that uses uses maps to create more interesting click targets. It does use jQuery to style the areas on click, but notice the way a map overlays the image and coordinates are used to create the targets.

See the Pen
responsive image map demo
by Derek Fogge (@PositionRelativ)
on CodePen.

You can implement image maps on even more complex shapes too. In fact, let’s go back to the same target shape from the SVG example but using a raster image instead. We still want to link up the arrow and the bullseye but this time do not have SVG elements to help us out. For the bullseye, we know the X and Y coordinates and its radius in the underlying image, so it’s fairly easy to define a circle for the region. The arrow shape is more complicated. I used https://www.image-map.net to plot out the shape and generate the area for the image map — it’s made up of one polygon and one circle for the rounded edge at the top.

See the Pen
target image map
by Bailey Jones (@bailey_jones)
on CodePen.

Clip-path

What if you want to use CSS to define the shape of a custom click region without resorting to JavaScript for the styling? The CSS clip-path property provides considerable flexibility for defining and styling target areas on any HTML element.

Here we have a click area in the shape of a five-pointed star. The star is technically a polygon, so we could use a star-shaped base image and an image map with corresponding coordinates like we did in the previous image map example. However, let’s put clip-path to use. The following example shows the same clip-path applied to both a JPG image and an absolutely positioned hyperlink element.

See the Pen
Clip-path
by Bailey Jones (@bailey_jones)
on CodePen.

Browser support for clip-path has gotten much better, but it can still be inconsistent for some values. Be sure to check support and vendor prefixes before relying on it.

We can also mix and match different approaches depending on what best suits the shape of a particular click target. Here, I’ve combined the “close” shape using Bennet Freely’s clippy with an SVG hyperlink element to build the start of a clickable tic-tac-toe game. SVG is useful here to make sure the “hole” in the middle of the “O” shape isn’t clickable. For the “X” though, which is a polygon, a single clip-path can style it.

See the Pen
tic tac toe
by Bailey Jones (@bailey_jones)
on CodePen.

Again, beware of browser support especially when mixing and matching techniques. The demo above will not be supported everywhere.

CSS shapes without transparent borders

The clip-path property allowed us to apply a predefined shape to an HTML element of our choice, including hyperlink elements. There are plenty of other options for creating elements HTML and CSS that aren’t squares and rectangles — you can see some of them in The Shapes of CSS. However, not all techniques will effect the shape of the click area as you might expect. Most of the examples in the Shapes of CSS rely on transparent borders, which the DOM will still recognize as part of your click target even if your users can’t see them. Other tricks like positioning, transform, and pseudo elements like ::before and ::after will keep your styled hyperlink aligned with its visible shape.

Here’s a CSS heart shape that does not rely on transparent borders. You can see how the the red heart shape is the only clickable area of the element.

See the Pen
Clickable heart
by Bailey Jones (@bailey_jones)
on CodePen.

Here’s another example that creates a CSS triangle shape using transparent borders. You can see how the click area winds up being outside the actual shape. Hover over the element and you’ll be able to see the true size of the click area.

See the Pen
clickable triangle
by Bailey Jones (@bailey_jones)
on CodePen.


Hopefully this gives you a good baseline understanding of the many ways to create clickable regions on images and shapes, relying on HTML and CSS alone. You may find that it’s necessary to reach for JavaScript in order to get a more advanced interactive experience. However, the combined powers of HTML, CSS, and SVG provide considerable options for controlling the precise shape of your click target.

The post The Many Ways to Link Up Shapes and Images with HTML and CSS appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

The Many Ways to Include CSS in JavaScript Applications

Welcome to an incredibly controversial topic in the land of front-end development! I’m sure that a majority of you reading this have encountered your fair share of #hotdrama surrounding how CSS should be handled within a JavaScript application.

I want to preface this post with a disclaimer: There is no hard and fast rule that establishes one method of handling CSS in a React, or Vue, or Angular application as superior. Every project is different, and every method has its merits! That may seem ambiguous, but what I do know is that the development community we exist in is full of people who are continuously seeking new information, and looking to push the web forward in meaningful ways.

Preconceived notions about this topic aside, let’s take a look at the fascinating world of CSS architecture!

Let us count the ways

Simply Googling “How to add CSS to ” yields a flurry of strongly held beliefs and opinions about how styles should be applied to a project. To try to help cut through some of the noise, let’s examine a few of the more commonly utilized methods at a high level, along with their purpose.

Option 1: A dang ol’ stylesheet

We’ll start off with what is a familiar approach: a dang ol’ stylesheet. We absolutely are able to <link> to an external stylesheet within our application and call it a day.

<link rel="stylesheet" href="styles.css">

We can write normal CSS that we’re used to and move on with our lives. Nothing wrong with that at all, but as an application gets larger, and more complex, it becomes harder and harder to maintain a single stylesheet. Parsing thousands of lines of CSS that are responsible for styling your entire application becomes a pain for any developer working on the project. The cascade is also a beautiful thing, but it also becomes tough to manage in the sense that some styles you — or other devs on the project — write will introduce regressions into other parts of the application. We’ve experienced these issues before, and things like Sass (and PostCSS more recently) have been introduced to help us handle these issues

We could continue down this path and utilize the awesome power of PostCSS to write very modular CSS partials that are strung together via @import rules. This requires a little bit of work within a webpack config to be properly set up, but something you can handle for sure!

No matter what compiler you decide to use (or not use) at the end of the day, you’ll be serving one CSS file that houses all of the styles for your application via a <link> tag in the header. Depending on the complexity of that application, this file has the potential to get pretty bloated, hard to load asynchronously, and render-blocking for the rest of your application. (Sure, render-blocking isn’t always a bad thing, but for all intents and purposes, we’ll generalize a bit here and avoid render blocking scripts and styles wherever we can.)

That’s not to say that this method doesn’t have its merits. For a small application, or an application built by a team with less of a focus on the front end, a single stylesheet may be a good call. It provides clear separation between business logic and application styles, and because it’s not generated by our application, is fully within our control to ensure exactly what we write is exactly what is output. Additionally, a single CSS file is fairly easy for the browser to cache, so that returning users don’t have to re-download the entire file on their next visit.

But let’s say that we’re looking for a bit more of a robust CSS architecture that allows us to leverage the power of tooling. Something to help us manage an application that requires a bit more of a nuanced approach. Enter CSS Modules.

Option 2: CSS Modules

One fairly large problem within a single stylesheet is the risk of regression. Writing CSS that utilizes a fairly non-specific selector could end up altering another component in a completely different area of your application. This is where an approach called “scoped styles” comes in handy.

Scoped styles allow us to programmatically generate class names specific to a component. Thus scoping those styles to that specific component, ensuring that their class names will be unique. This leads to auto-generated class names like header__2lexd. The bit at the end is a hashed selector that is unique, so even if you had another component named header, you could apply a header class to it, and our scoped styles would generate a new hashed suffix like so: header__15qy_.

CSS Modules offer ways, depending on implementation, to control the generated class name, but I’ll leave that up to the CSS Modules documentation to cover that.

Once all is said and done, we are still generating a single CSS file that is delivered to the browser via a <link> tag in the header. This comes with the same potential drawbacks (render blocking, file size bloat, etc.) and some of the benefits (caching, mostly) that we covered above. But this method, because of its purpose of scoping styles, comes with another caveat: the removal of the global scope — at least initially.

Imagine you want to employ the use of a .screen-reader-text global class that can be applied to any component within your application. If using CSS Modules, you’d have to reach for the :global pseudo selector that explicitly defines the CSS within it as something that is allowed to be globally accessed by other components in the app. As long as you import the stylesheet that includes your :global declaration block into your component’s stylesheet, you’ll have the use of that global selector. Not a huge drawback, but something that takes getting used to.

Here’s an example of the :global pseudo selector in action:

// typography.css :global {   .aligncenter {     text-align: center;   }   .alignright {     text-align: right;   }   .alignleft {     text-align: left;   } }

You may run the risk of dropping a whole bunch of global selectors for typography, forms, and just general elements that most sites have into one single :global selector. Luckily, through the magic of things like PostCSS Nested or Sass, you can import partials directly into the selector to make things a bit more clean:

// main.scss :global {   @import "typography";   @import "forms"; }

This way, you can write your partials without the :global selector, and just import them directly into your main stylesheet.

Another bit that takes some getting used to is how class names are referenced within DOM nodes. I’ll let the individual docs for Vue, React, and Angular speak for themselves there. I’ll also leave you with a little example of what those class references look like utilized within a React component:

// ./css/Button.css  .btn {   background-color: blanchedalmond;   font-size: 1.4rem;   padding: 1rem 2rem;   text-transform: uppercase;   transition: background-color ease 300ms, border-color ease 300ms;    &:hover {     background-color: #000;     color: #fff;   } }  // ./Button.js  import styles from "./css/Button.css";  const Button = () => (   <button className={styles.btn}>     Click me!   </button> );  export default Button;

The CSS Modules method, again, has some great use cases. For applications looking to take advantage of scoped styles while maintaining the performance benefits of a static, but compiled stylesheet, then CSS Modules may be the right fit for you!

It’s worth noting here as well that CSS Modules can be combined with your favorite flavor of CSS preprocessing. Sass, Less, PostCSS, etc. are all able to be integrated into the build process utilizing CSS Modules.

But let’s say your application could benefit from being included within your JavaScript. Perhaps gaining access to the various states of your components, and reacting based off of the changing state, would be beneficial as well. Let’s say you want to easily incorporate critical CSS into your application as well! Enter CSS-in-JS.

Option 3: CSS-in-JS

CSS-in-JS is a fairly broad topic. There are several packages that work to make writing CSS-in-JS as painless as possible. Frameworks like JSS, Emotion, and Styled Components are just a few of the many packages that comprise this topic.

As a broad strokes explanation for most of these frameworks, CSS-in-JS is largely operates the same way. You write CSS associated with your individual component and your build process compiles the application. When this happens, most CSS-in-JS frameworks will output the associated CSS of only the components that are rendered on the page at any given time. CSS-in-JS frameworks do this by outputting that CSS within a <style> tag in the <head> of your application. This gives you a critical CSS loading strategy out of the box! Additionally, much like CSS Modules, the styles are scoped, and the class names are hashed.

As you navigate around your application, the components that are unmounted will have their styles removed from the <head> and your incoming components that are mounted will have their styles appended in their place. This provides opportunity for performance benefits on your application. It removes an HTTP request, it is not render blocking, and it ensures that your users are only downloading what they need to view the page at any given time.

Another interesting opportunity CSS-in-JS provides is the ability to reference various component states and functions in order to render different CSS. This could be as simple as replicating a class toggle based on some state change, or be as complex as something like theming.

Because CSS-in-JS is a fairly #hotdrama topic, I realized that there are a lot of different ways that folks are trying to go about this. Now, I share the feelings of many other people who hold CSS in high regard, especially when it comes to leveraging JavaScript to write CSS. My initial reactions to this approach were fairly negative. I did not like the idea of cross-contaminating the two. But I wanted to keep an open mind. Let’s look at some of the features that we as front-end-focused developers would need in order to even consider this approach.

  • If we’re writing CSS-in-JS we have to write real CSS. Several packages offer ways to write template-literal CSS, but require you to camel-case your properties — i.e. padding-left becomes paddingLeft. That’s not something I’m personally willing to sacrifice.
  • Some CSS-in-JS solutions require you to write your styles inline on the element you’re attempting to style. The syntax for that, especially within complex components, starts to get very hectic, and again is not something I’m willing to sacrifice.
  • The use of CSS-in-JS has to provide me with powerful tools that are otherwise super difficult to accomplish with CSS Modules or a dang ol’ stylesheet.
  • We have to be able to leverage forward-thinking CSS like nesting and variables. We also have to be able to incorporate things like Autoprefixer, and other add-ons to enhance the developer experience.

It’s a lot to ask of a framework, but for those of us who have spent most of our lives studying and implementing solutions around a language that we love, we have to make sure that we’re able to continue writing that same language as best we can.

Here’s a quick peek at what a React component using Styled Components could look like:

// ./Button.js import styled from 'styled-components';  const StyledButton= styled.button`   background-color: blanchedalmond;   font-size: 1.4rem;   padding: 1rem 2rem;   text-transform: uppercase;   transition: background-color ease 300ms, border-color ease 300ms;    &:hover {     background-color: #000;     color: #fff;   } `;  const Button = () => (   <StyledButton>     Click Me!   </StyledButton> );  export default Button;

We also need to address the potential downsides of a CSS-in-JS solution — and definitely not as an attempt to spark more drama. With a method like this, it’s incredibly easy for us to fall into a trap that leads us to a bloated JavaScript file with potentially hundreds of lines of CSS — and that all comes before the developer will even see any of the component’s methods or its HTML structure. We can, however, look at this as an opportunity to very closely examine how and why we are building components the way they are. In thinking a bit more deeply about this, we can potentially use it to our advantage and write leaner code, with more reusable components.

Additionally, this method absolutely blurs the line between business logic and application styles. However, with a well-documented and well-thought architecture, other developers on the project can be eased into this idea without feeling overwhelmed.

TL;DR

There are several ways to handle the beast that is CSS architecture on any project and do so while using any framework. The fact that we, as developers, have so many choices is both super exciting, and incredibly overwhelming. However, the overarching theme that I think continues to get lost in super short social media conversations that we end up having, is that each solution has its own merits, and its own inefficiencies. It’s all about how we carefully and thoughtfully implement a system that makes our future selves, and/or other developers who may touch the code, thank us for taking the time to establish that structure.

The post The Many Ways to Include CSS in JavaScript Applications appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

The Many Ways of Getting Data Into Charts

Data is available everywhere nowadays, whether it’s in a plain text file, a REST API, an online Google sheet… you name it! It’s that variety of context that makes building graphs more than simply having a database in your local project — where there is data, there is a way.

That’s pretty much what we’re going to look at in this post: making JavaScript data visualizations using data from a variety of sources.

If you want to follow along and make any of the visualizations we’re covering here, we’ll be using Chart.js so grab that and include it in your own environment:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>

Source 1: HTML data table

Lots and lots of websites have data tables, and why not? They are a great way to show data and that’s what they were made to do. But, if you could have a visualization powered by the data in it — and for not much more effort — wouldn’t that be even better?

With a little JavaScript, the data in a HTML table can be isolated from the HTML and prepped for a chart. Look at the following data table:

Year Items Sold Turnover ($ ) Profit ($ )
2016 10 200 89
2017 25 550 225
2018 55 1200 600
2019 120 2450 1100

It contains sales data for a business. Now, if we could graph this out, it would be both visually compelling and help users glean insights. So let’s do it!

First of all, let’s define a function for our chart. This comes straight out of the Chart.js library, so it’s worth cross-referencing this with the documentation is something seems unclear. I’ve added some comments to call out key parts.

function BuildChart(labels, values, chartTitle) {   var ctx = document.getElementById("myChart").getContext('2d');   var myChart = new Chart(ctx, {     type: 'bar',     data: {       labels: labels, // Our labels       datasets: [{         label: chartTitle, // Name the series         data: values, // Our values         backgroundColor: [ // Specify custom colors           'rgba(255, 99, 132, 0.2)',           'rgba(54, 162, 235, 0.2)',           'rgba(255, 206, 86, 0.2)',           'rgba(75, 192, 192, 0.2)',           'rgba(153, 102, 255, 0.2)',           'rgba(255, 159, 64, 0.2)'         ],         borderColor: [ // Add custom color borders           'rgba(255,99,132,1)',           'rgba(54, 162, 235, 1)',           'rgba(255, 206, 86, 1)',           'rgba(75, 192, 192, 1)',           'rgba(153, 102, 255, 1)',           'rgba(255, 159, 64, 1)'         ],         borderWidth: 1 // Specify bar border width       }]     },     options: {       responsive: true, // Instruct chart js to respond nicely.       maintainAspectRatio: false, // Add to prevent default behavior of full-width/height      }   });   return myChart; }

Now that we have a function to create a chart for the table data, let’s write out the HTML for the table and add a canvas element that Chart.js can use to inject its charting magic. This is exactly the same data from the table example above.

<table class="table" id="dataTable">   <thead>     <th>Year</th>     <th>Items Sold</th>     <th>Turnover ($ )</th>     <th>Profit ($ )</th>   </thead>   <tbody>     <tr>       <td>2016</td>       <td>10</td>       <td>200</td>       <td>89</td>     </tr>     <tr>       <td>2017</td>       <td>25</td>       <td>550</td>       <td>225</td>     </tr>     <tr>       <td>2018</td>       <td>55</td>       <td>1200</td>       <td>600</td>     </tr>     <tr>       <td>2019</td>       <td>120</td>       <td>2450</td>       <td>1100</td>     </tr>   </tbody> </table>  <div class="chart">   <canvas id="myChart"></canvas> </div>

Then, we need to parse the table into JSON with vanilla JavaScript. This is what Chart.js will use to populate the charts and graphs.

var table = document.getElementById('dataTable'); var json = []]; // First row needs to be headers  var headers =[]; for (var i = 0; i < table.rows[0].cells.length; i++) {   headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, ''); }  // Go through cells  for (var i = 1; i < table.rows.length; i++) {   var tableRow = table.rows[i];   var rowData = {};   for (var j = 0; j < tableRow.cells.length; j++) {     rowData[headers[j]] = tableRow.cells[j].innerHTML;   }    json.push(rowData); }  console.log(json);

We threw in that last line so we can check the output in the DevTools console. Here’s what is logged into the console:

Perfect! Our table headers become variables and are mapped to the content in the table cells.

All that’s left to do is map the year labels and items sold values to array (which Chart.js requires for its data object) and then to pass the data into the chart function.

This script maps the JSON values to an array of years. We can add it directly after the previous function.

// Map JSON values back to label array var labels = json.map(function (e) {   return e.year; }); console.log(labels); // ["2016", "2017", "2018", "2019"]  // Map JSON values back to values array var values = json.map(function (e) {   return e.itemssold; }); console.log(values); // ["10", "25", "55", "120"]

Call the BuildChart function from our first snippet (including a name for the chart) and we get a beautiful visualization of the data from the HTML table.

var chart = BuildChart(labels, values, "Items Sold Over Time");

And that is it! The charts data has now been isolated and passed into the JavaScript visualization and rendered.

See the Pen
BarChart Loaded From HTML Table
by Danny Englishby (@DanEnglishby)
on CodePen.

Source 2: A real-time API

There are many, many public APIs available in the world, many of which are rich with neat and useful data. Let’s use one of them to demonstrate how real-time data can be used to populate a chart. I’m going to use the Forbes 400 Rich List API to graph out the top 10 richest people in the world. I know, cool, eh?! I always find wealth rankings interesting, and there is so much more data this API provides. But for now, we will request data to display a chart with names and real time net worth using pure JavaScript!

First off, we want to define a chart function again, this time with a few more options.

function BuildChart(labels, values, chartTitle) {   var data = {     labels: labels,     datasets: [{       label: chartTitle, // Name the series       data: values,       backgroundColor: ['rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',       ],     }],   };   var ctx = document.getElementById("myChart").getContext('2d');   var myChart = new Chart(ctx, {     type: 'horizontalBar',     data: data,     options: {       responsive: true, // Instruct chart JS to respond nicely.       maintainAspectRatio: false, // Add to prevent default behavior of full-width/height        scales: {         xAxes: [{           scaleLabel: {             display: true,             labelString: '$  Billion'           }         }],         yAxes: [{           scaleLabel: {             display: true,             labelString: 'Name'           }         }]       },     }   });   return myChart; }

Next, we’ll need that same HTML canvas element for where the chart will be rendered:

<div class="chart" style="position: relative; height:80vh; width:100vw">   <canvas id="myChart"></canvas> </div>

Now to grab some real time data. Let’s see what is returned in the console from the Forbes API call:

As you can see by the JSON returned, there is a lot of rich information that can injected into a chart. So, let’s make our rankings!

With some light JavaScript, we can request the data from the API, pick out and map the values we went to array variables, and finally pass our data in and rendering the chart.

var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () {   if (this.readyState == 4 && this.status == 200) {     var json = JSON.parse(this.response);     // Map JSON labels  back to values array     var labels = json.map(function (e) {       return e.name;     });     // Map JSON values back to values array     var values = json.map(function (e) {       return (e.realTimeWorth / 1000); // Divide to billions in units of ten     });     BuildChart(labels, values, "Real Time Net Worth"); // Pass in data and call the chart   } }; xhttp.open("GET", "https://forbes400.herokuapp.com/api/forbes400?limit=10", false); xhttp.send();

See the Pen
Chart Loaded From RichListAPI
by Danny Englishby (@DanEnglishby)
on CodePen.

Source 3: A Google Sheet

So far, we’ve looked at data in standard HTML tables and APIs to populate charts. But what if we already have an existing Google Sheet that has a bunch of data in it? Well, we can also use that to make a chart!

First, there are some rules for accessing a Google Sheet:

  • The Google Sheet must be published
  • The Google Sheet must be public (i.e. not set to private viewing)

As long as these two points are true, we can access a Google Sheet in the form of JSON, which means, of course, we can graph it out!

Here’s a Google Sheet with some made up data that I’ve published publicly. It consists of three fields of data: MachineId, Date, and ProductsProduced.

Now, if we that the sheet’s URL, we’ll want to note everything after the last slash:

https://docs.google.com/spreadsheets/d/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg

This is the sheet identity and what we need for the GET request we send to Google. To make a GET request for JSON, we insert that string in the URL in another URL:

https://spreadsheets.google.com/feeds/list/[ID GOES HERE]/od6/public/full?alt=json

That gives us the following URL:

https://spreadsheets.google.com/feeds/list/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg/od6/public/full?alt=json

And here’s the response we get in the console:

The important piece is the feed.entry object array. This holds vital sheet data, which looks like this when we drill into it:

Notice the items underlined in red. The Google Sheets API has preceded each of the column names with gsx$ (e.g. gsx$ date). These are exactly how we will dissect the data from the object, using these uniquely generated names. So, knowing this, it’s time to insert the data into some isolated arrays and pass them into our chart function.

function BuildChart(labels, values, chartTitle) {   var data = {     labels: labels,     datasets: [{       label: chartTitle, // Name the series       data: values,       backgroundColor: ['rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',         'rgb(54, 162, 235)',       ],     }],   };    var ctx = document.getElementById("myChart").getContext('2d');   var myChart = new Chart(ctx, {     type: 'bar',     data: data,     options: {       responsive: true, // Instruct chart js to respond nicely.       maintainAspectRatio: false, // Add to prevent default behavior of full-width/height        scales: {         xAxes: [{           scaleLabel: {             display: true,             labelString: 'Date'           }         }],         yAxes: [{           scaleLabel: {             display: true,             labelString: 'Produced Count'           }         }]       },     }   });    return myChart; }

And, you guessed it, next is the Canvas element:

<div class="chart" style="position: relative; height:80vh; width:100vw">   <canvas id="myChart"></canvas> </div>

…then the GET request, mapping our labels and values array and finally calling the chart passing in the data.

var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() {   if (this.readyState == 4 && this.status == 200) {     var json = JSON.parse(this.response);     console.log(json);    // Map JSON labels  back to values array   var labels = json.feed.entry.map(function (e) {     return e.gsx$ date.$ t;   });          // Map JSON values back to values array   var values = json.feed.entry.map(function (e) {     return e.gsx$ productsproduced.$ t;   });    BuildChart(labels, values, "Production Data");   } }; xhttp.open("GET", "https://spreadsheets.google.com/feeds/list/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg/od6/public/full?alt=json", false); xhttp.send();

And, boom!

See the Pen
Chart Loaded From a Google Sheet
by Danny Englishby (@DanEnglishby)
on CodePen.

What will you make with data?

You probably get the point that there is a variety of ways we can get data to populate beautiful looking charts and graphs. As long as we have some formatted numbers and a data visualization library, then we have a lot of powers at our fingertips.

Hopefully now you’re thinking of where you might have data and how to plug into a chart! We didn’t even cover all of the possibilities here. Here are a few more resources you can use now that you’ve got chart-making chops.

A few more charting libraries

A few more places to store data

The post The Many Ways of Getting Data Into Charts appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!

Oh, the Many Ways to Make Triangular Breadcrumb Ribbons

Let’s have a look at how we can create a row of links that sorta run into each other with a chevron-like shape and notch on each block like you might see in a hierarchical breadcrumb navigation.

You’ve probably seen this pattern a lot. It comes up often in things like multi-step forms and site breadcrumbs. For our purposes we’re going to call these “ribbons” so we know what we’re referring to as we go.

Like a lot of things on the web, we can make ribbons like these in many ways! I’ve created a demo page that brings a variety of them together, like using CSS triangles, SVG backgrounds, and the CSS clip-path property.

Starting with the HTML structure

For each demo, the HTML structure will largely be the same where we have a <nav> that acts as the parent element and then links inside it as the children.

<nav class="ribbon ribbon--modifier" role="navigation" aria-label="breadcrumbs">   <a class="ribbon__element" href="https://www.silvestar.codes/">Home</a>   <a class="ribbon__element" href="https://www.silvestar.codes/categories/articles/">Blog</a>   <a class="ribbon__element" href="https://www.silvestar.codes/articles/building-an-animated-sticky-header-with-custom-offset/" aria-current="page">Post</a> </nav>

Note that these elements should be accessible, according to A11y Style Guide website. It’s a good rule to build components with accessibility in mind and introducing accessibility at the very start is the best way to prevent the classic “I forgot to make it accessible” situation.

Let’s create some baseline styles

When it comes to things like this, we want to make sure the sizing of the elements is done right. For this purpose, we are going to define the font size of the .ribbon (that’s what we’re going to call these things) wrapper element and then use em units on the child element which are the links themselves.

/* Define font size of the wrapper element */  .ribbon {   font-size: 15px; }  /* Use ems to define the size of the ribbon element */  .ribbon__element {   font-size: 1.5em;   letter-spacing: 0.01em;   line-height: 1.333em;   padding: 0.667em 0.667em 0.667em 1.333em; }

This particular technique would be beneficial for defining the size of the triangle shape for each ribbon because we would use the same sizes to calculate triangle. And since we are using em units to calculate the ribbon element size, we could resize all elements by redefining the font-size on the wrapper element.

Let’s use CSS Grid for the layout because, well, we can. We could do this in a way that offers deeper browser support, but we’ll leave that up to you based on your support requirements.

We are going to define four columns:

  • Three for ribbon elements
  • One to fix spacing issues. As it is, the right arrow shape would be placed outside of the ribbon component and that could mess up the original layout.
/* The wrapper element   * We're using CSS Grid, but ensure that meets your browser support requirements.  * Assuming the use of autoprefixer for vendor prefixes and properties.  */    .ribbon {   display: grid;   grid-gap: 1px;   grid-template-columns: repeat(auto-fill, 1fr) 1em; /* Auto-fill the three ribbon elements plus one narrow column to fix the sizing issues */ }

If you prefer to avoid stretching the ribbon elements, the grid could be defined differently. For example, we could use max-content to adjust columns by content size. (Note, however, that max-content is not very well supported yet in some key browsers.)

/* Make ribbon columns adjust to the maximum content size */ .ribbon--auto {   grid-template-columns: repeat(3, max-content) 1em; }

I am sure there are many different ways we could have gone about the layout. I like this one because it defines the exact gap between ribbon elements without complicated calculations.

Accessibility is not only adding aria attributes. It also includes color contrast and readability, as well as adding hover and focus states. If you don’t like outline style, you could use other CSS properties, like box-shadow, for example.

/* Use current link color, but add underline on hover  */ .ribbon__element:hover,  .ribbon__element:active {   color: inherit;   text-decoration: underline; }  /* Clear default outline style and use inset box shadow for focus state */ .ribbon__element:focus {   box-shadow: inset 0 -3px 0 0 #343435;   outline: none; }

Creating the unique triangular shape

We have more than one option when it comes down to defining the triangle at the end of each ribbon. We could:

  1. We could create a triangle using borders with pseudo-elements
  2. We could use an SVG background image on pseudo-elements
  3. We could use inline SVG images
  4. We could create a clip-path using the polygon() function

Let’s dig into each one.

Option 1: The border approach

First, we should set the element’s width and height to zero so it doesn’t get in the way of the pseudo-elements we’re using to draw the triangle with borders. Then we should draw the triangle using borders, specifically by defining a solid left border that matches the color of the background to make it blend in with the rest of the ribbon. From there, let’s define top and bottom borders and make them transparent. The trick here is to calculate the size of the border.

Our ribbon element has a content size of the line-height value plus the top and bottom paddings:

0.333em + 0.667em + 0.667em = 2.667em

That means our top and bottom borders should be half that size. The only thing left to do is to position elements absolutely to the correct side of the component.

/* The left arrow */ .ribbon--alpha .ribbon__element:before {   /* Make the content size zero */   content: '';     height: 0;     width: 0;    /* Use borders to make the pseudo element fit the ribbon size */   border-bottom: 1.333em solid transparent;   border-left: 0.667em solid #fff;   border-top: 1.333em solid transparent;    /* Position the element absolutely on the left side of the ribbon element */   position: absolute;   top: 0;     bottom: 0;     left: 0; }  /* The right arrow */ .ribbon--alpha .ribbon__element:after {   /* Make the content size zero */   content: '';     height: 0;     width: 0;    /* Use borders to make the pseudo-element fit the ribbon size */   border-bottom: 1.333em solid transparent;   border-left: 0.667em solid;   border-top: 1.333em solid transparent;    /* Position the element absolutely on the right side of the ribbon element and push it outside */   position: absolute;   top: 0;   right: 0;   bottom: 0;   -webkit-transform: translateX(0.667em);   transform: translateX(0.667em); }

Since the right triangle should match the background color of the ribbon, let’s remember to add the correct border color for each ribbon’s pseudo-element.

/* The right arrow of the first element */ .ribbon--alpha .ribbon__element:nth-child(1):after {   border-left-color: #11d295; }  /* The right arrow of the second element */ .ribbon--alpha .ribbon__element:nth-child(2):after {   border-left-color: #ef3675; }  /* The right arrow of the third element */ .ribbon--alpha .ribbon__element:nth-child(3):after {   border-left-color: #4cd4e9; }

And there we go!

See the Pen
CSS Grid Ribbon – Alpha
by Silvestar Bistrović (@CiTA)
on CodePen.

Option 2: The background image approach

We can also create a triangle using a background image. This requires creating an image that matches the design, which is a little cumbersome, but still totally possible. We are going to use SVG here since it’s smooth at any resolution.

Unlike the border triangle approach, we want to match the height of our pseudo-element with the height of the ribbon element, or 100%. The width of the component should match the left border width of the border triangle, which is 0.666666em in our case. Then we should use a white triangle for the background image on the triangle of the left side, and then use triangle images with color for the triangles on the right side. Again, we are using absolute positioning to place our triangles to the correct side of the ribbon element.

/* The left arrow */ .ribbon--beta .ribbon__element:before {   /* Define the arrow size */   content: '';     height: 100%;     width: 0.666666em;      /* Define the background image that matches the background color */   background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=);   background-position: center left;   background-repeat: no-repeat;   background-size: 100%;      /* Position the element absolutely on the left side of the ribbon element */   position: absolute;   bottom: 0;   top: 0;   left: 0; }  /* The right arrow */ .ribbon--beta .ribbon__element:after {   /* Define the arrow size */   content: '';     height: 100%;   width: 0.667em;    /* Define the background image attributes */   background-position: center left;   background-repeat: no-repeat;   background-size: 100%;    /* Position the element absolutely on the right side of the ribbon element and push it outside */   position: absolute;   top: 0;   right: 0;   bottom: 0;   -webkit-transform: translateX(0.667em);   transform: translateX(0.667em); }  /* Define the background image that matches the background color of the first element */ .ribbon--beta .ribbon__element:nth-child(1):after {   background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjMTFkMjk1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); }  /* Define the background image that matches the background color of the second element */ .ribbon--beta .ribbon__element:nth-child(2):after {   background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjZWYzNjc1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); }  /* Define the background image that matches the background color of the third element */ .ribbon--beta .ribbon__element:nth-child(3):after {   background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjNGNkNGU5IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); }

There we go!

See the Pen
CSS Grid Ribbon – Beta
by Silvestar Bistrović (@CiTA)
on CodePen.

Option 3: The inline SVG approach

Instead of loading a different SVG triangle for each background image, we could use inline SVG directly in the HTML.

This particular approach allows us to control the fill color of each SVG arrow with CSS. The arrow size is calculated by the ribbon size. Once again, we are using the em units to define the size and arrows are absolutely positioned, like the other approaches we’ve seen so far.

/* Position arrows absolutely and set the correct size */ .ribbon--gamma .ribbon__element svg {   height: 2.667em;   position: absolute;   top: 0;   width: 0.667em; }  /* The left arrow */ .ribbon--gamma .ribbon__element svg:first-child {   fill: #fff; /* Define the background image that matches the background color */   left: 0; /* Stick left arrows to the left side of the ribbon element */ }  /* The right arrow */ .ribbon--gamma .ribbon__element svg:last-child {   left: 100%; /* Push right arrows outside of the ribbon element */ }  /* Define the fill color that matches the background color of the first element */ .ribbon--gamma .ribbon__element:nth-child(1) svg:last-child {   fill: #11d295; }  /* Define the fill color that matches the background color of the second element */ .ribbon--gamma .ribbon__element:nth-child(2) svg:last-child {   fill: #ef3675; }  /* Define the fill color that matches the background color of the third element */ .ribbon--gamma .ribbon__element:nth-child(3) svg:last-child {   fill: #4cd4e9; }

See the Pen
CSS Grid Ribbon – Gamma
by Silvestar Bistrović (@CiTA)
on CodePen.

Option 4: The clip-path approach

We can create the ribbon triangles with a polygon that masks the background. Firefox’s Shape Editor is a fantastic tool to draw shapes directly in the browser with a GUI, as is Clippy.

Since polygons must be created using percentages, we should use our best judgment to match the size of border triangles. Also, note that percentage-based polygons might look a little funny on some viewports, especially when element sizes are adapting to its surroundings, like wrapper elements. Consider redefining polygons for different viewports.

.ribbon--delta .ribbon__element {   clip-path: polygon(95% 0, 100% 50%, 95% 100%, 0% 100%, 5% 50%, 0% 0%); }

Since we defined our wrapper element using CSS Grid, we should expand the ribbon elements but leave the last one at the size of the polygon triangle, which is 5% in our case. The last ribbon element should be wider by the size of the border triangle width to match the first two examples.

/* Make all ribbon elements (except the last one) wider by the size of the polygon triangle */ .ribbon--delta .ribbon__element:not(:last-child) {   width: 105%; }  /* Make the last ribbon element wider by the size of the border triangle */ .ribbon--delta .ribbon__element:last-child {   width: calc(100% + .667em); }

See the Pen
CSS Grid Ribbon – Delta
by Silvestar Bistrović (@CiTA)
on CodePen.

Variations on these options

Now that we’ve learned how to create the breadcrumb ribbon a few different ways, we could play around with it, like adding shadows or gradients and different sizes.

Adding a shadow

We could add the shadow on our ribbon elements. Make sure to avoid the shadow on the left or right side of the ribbon element.

/* Add shadow under each ribbon element */ .ribbon--shadow .ribbon__element {   box-shadow: 1px 3px 3px -3px black; }

See the Pen
CSS Grid Ribbon – Shadow
by Silvestar Bistrović (@CiTA)
on CodePen.

Using gradients for color

We could add gradients to our ribbon element. Be sure to match the color of the right triangle when doing so. Also, make sure to comply with contrast accessibility.

For example, if we are going to use the border approach or background image approach, we should use mostly horizontal (i.e. left-to-right) gradients (with the exceptions of some carefully calculated angled gradients). If we are using the clip-path approach, we could use any gradient version we wish.

/* Add gradient to the first ribbon element */ .ribbon--gradient .ribbon__element:nth-child(1) {   background-image: linear-gradient(to right, #11ced2, #11d295); }  /* Add gradient to the second ribbon element */ .ribbon--gradient .ribbon__element:nth-child(2) {   background-image: linear-gradient(to right, #ef36b2, #ef3675); }  /* Add gradient to the third ribbon element */ .ribbon--gradient .ribbon__element:nth-child(3) {   background-image: linear-gradient(to right, #4c9fe9, #4cd4e9); }

See the Pen
CSS Grid Ribbon – Gradient
by Silvestar Bistrović (@CiTA)
on CodePen.

Working with size variations

Since the size of our ribbon elements depends on the font size of the wrapper element, defining different sizes is pretty straightforward.

/* Small ribbons */ .ribbon--small {   font-size: 10px; }  /* Big ribbons */ .ribbon--big {   font-size: 20px; }

Here we go with a smaller set of ribbons:

See the Pen
CSS Grid Ribbon – Small
by Silvestar Bistrović (@CiTA)
on CodePen.

And here’s a nice set of chunky ribbons:

See the Pen
CSS Grid Ribbon – Big
by Silvestar Bistrović (@CiTA)
on CodePen.

Combining all the things!

We can also combine different modifier classes to achieve an even more styling. For example, let’s use gradient and shadow modifiers together:

See the Pen
CSS Grid Ribbon – Shadow Gradient
by Silvestar Bistrović (@CiTA)
on CodePen.

Any other angles to consider?

Making custom elements using different CSS techniques is a great way how each one of us could improve or refresh our knowledge. Before starting, it’s worth investing some thought into the maintainability and modularity of the component being built. A consistent naming convention, like BEM, is certainly helpful that. Accessibility is also a big deal, so starting with it in mind and documenting accessibility features along the way will serve you well.

We looked at four different approaches for drawing ribbon triangles. Have you used a different approach or know of one we haven’t considered here? Let me know in the comments!

The post Oh, the Many Ways to Make Triangular Breadcrumb Ribbons! appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Using Dotfiles for Managing Development and Many Other Magical Things

Howdy folks! 🎉 I’m Simon Owen, and over the years, I’ve loved being a part of and learning from the dotfiles community. I spend a lot of time teaching developers and running workshops. In those sessions, demonstrating how I set up my development environment is often one of things that folks appreciated the most.

Dotfiles are a key part of my development environment. Haven’t heard of them? Well, even if you have, it’s a good idea to walk through what they are and the benefits of using them.

Last year, I set myself a goal to create a screencast series. If you like this article and want to find out more, please subscribe to the mailing list and get the download link. If you really like it, you can also 🦄 donate here! 🦄

A dot-what-file?

If you’re hearing about dotfiles for the first time, it’s totally fine to be confused about what they are and what they do. I recall that it took me a considerable amount of time before I realized a dotfile is simply a file that has a dot in front of the file name!

There are two common examples of dotfiles. First, the ones you might already be familiar with are those often found at the root of many open source projects — for example, .editorconfig contains code editor preferences to help maintain consistent coding styles for a project. You may also have seen .stylelintrc and .eslintrc floating around, which set CSS and JavaScript rules, respectively.

Second (and the ones we’re looking at today), are dotfiles that can live at the root level of a user directory (i.e. /Users/<username> ). One such dotfile is .aliases, which contains custom named commands that can speed up work in the Terminal. Another is .bash_prompt, which is used to change the $ in Terminal to something a little more fun. In my case, I set it so this dude pops up to make me smile when things get tough:

༼ つ ◕_◕ ༽つ

Hopefully, you’re already starting to get a good sense of how useful dotfiles can be. They’re sort of like hidden gems (literally, since they’re hidden from views by default) that unlock superpowers for your machine to help with development. We’re talking about automation, optimizations, and efficient workflows, among other things.

First, I want to give props to the dotfiles community

Before we dig into dotfiles, it’s worth calling out how great the community behind them is. When I first forked Paul Irish’s dotfile repo, there was a lot going on in there I didn’t understand. Mathias Bynens and Paul Irish helped me immensely by answering questions about the code and it was their willingness to help that served as one of the reasons I became drawn to both the concept and the community.

Sometimes, I’ll post something to the community that I’d like to automate, but can’t figure it out for the life of me. And, without fail, I’ll get a helpful reply. Case in point: Eric Czarny wrote an app for me to automate my Spectacle settings and Mathias also contributed a code snippet. How cool is that?!

Then there are things like macOS updates. The dotfiles community is often on top of this and provide useful advice on GitHub comments regarding anything that no longer works or other useful information. You can then amend your dotfiles accordingly, such as adding the following code that increases the sound quality for Bluetooth headphones/headsets:

defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Min (editable)" -int 40

Digging into dotfiles

The code example above might look a bit familiar to you. It’s along the same lines as this often-used one to show hidden files:

defaults write com.apple.finder AppleShowAllFiles -bool true

…or this one to add spaces to the dock:

defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}'; killall Dock

These commands can be pasted directly into the Terminal. As you might expect, something like -bool true will change a boolean value from false to true and reset the command for later use.

If you’e like me and have a lot of these commands, then this is where the .macos (previously .osx) dotfile becomes especially useful. Instead of copying and pasting each command individually, we can automate and run all of them in one go.

Let’s walk through some examples

There are so many awesome things we can do in dotfiles. Here are some practical use cases that I rely on for my day-to-day work.

Setting aliases for default commands (.aliases)

Navigating between directories in the Terminal can be cumbersome and it’s easy to get lost in cd madness.

We can replace the standard “change directory” (cd) command with a custom command in the .aliases dotfile. For example, use this alias to ditch the cd prefix altogether when using the command cd .. to move up a directory in favor of .. by itself.

alias ..="cd .."

Sure, it’s only dropping two letters, but how much easier is that to remember?

An animated screenshot of a Terminal window typing two periods instead of the full cd command to move up a level in the directory.

We can do the same thing to make shortcuts to certain directories:

alias dl="cd ~/Downloads"

Or, create aliases for shorthand command tasks:

alias hs="hexo serve"
An animated screenshot of a Terminal window typing a command called hs instead of typing out hexo serve in full.

Oh, here’s another one! List only directories:

alias lsd="ls -lF $ {colorflag} | grep --color=never '^d'"

Make a custom bash prompt for a personal touch to the Terminal (.bash_prompt)

I referenced this a little earlier, but here’s how I turned my bash prompt ($ ) into a little dude that’s way more fun to look at it. This is done directly in the .bash_prompt dotfile.

PS1="༼ つ ◕_◕ ༽つ"

Create Git shortcuts to speed up commits (.gitconfig)

We can make it a little more efficient to commit all changes at once in the .gitconfig dotfile. Using ca is a lot more concise than !git add -A && git commit -av .

ca = !git add -A && git commit -av

Another handy shortcut: find commits by commit message.

fm = "!f() { git log --pretty=format:'%C(yellow)%h  %Cblue%ad  %Creset%s%Cgreen  [%cn] %Cred%d' --decorate --date=short --grep=$ 1; }; f"

Automate common Homebrew tasks (brew.sh)

Use Homebrew for package management? Although not strictly a dotfile (it doesn’t have a dot before the file name), Homebrew gives us the brew.sh shell script file. This file automates the installation and management of Apps and Tools:

brew install git brew install tree brew cask install google-chrome brew cask install iterm2 brew cask install sublime-text

Protect your Git credentials (.extra)

Hide information you don’t want to share publicly in one file in a private repo and bring it in for you alone. For example, a good idea for this file is anything that’s specific to you, such as your Git credentials. This will prevent people from cloning, running your dotfiles, then committing as you!

# Git credentials # Not in the repository, to prevent people from accidentally committing under my name GIT_AUTHOR_NAME="Simon Owen" GIT_COMMITTER_NAME="$ GIT_AUTHOR_NAME" git config --global user.name "$ GIT_AUTHOR_NAME" GIT_AUTHOR_EMAIL="<ADD-YOUR-EMAIL-HERE>" GIT_COMMITTER_EMAIL="$ GIT_AUTHOR_EMAIL" git config --global user.email "$ GIT_AUTHOR_EMAIL"

Write custom functions for tasks (.functions)

Dotfiles are more than shortcuts and aliases. We can also make custom functions in .functions that do more advanced lifting. For example, create a new directory and change directory to it:

function mkd() {   mkdir -p "$ @" && cd "$ _"; }
An animated screenshot of a Terminal window typing mkd new to trigger the creation of a new folder and navigating to it.

Or, we can open a given location in Finder with a one-letter command (o):

function o() {   if [ $ #-eq 0 ]; then     open .;   else     open "$ @";   fi; }

Specify your $ PATH and keep private (.path)

$ PATH allows the running of executable files. Instead of navigating to each path manually in Terminal, here we can set the file paths so they can run the executable files directly. It might be the case that this file contains sensitive information. As such, this file is often kept in a private repo.

Here’s an example adding ~/utils to the $ PATH:

export PATH="$ HOME/utils:$ PATH"

Force Vim to use a particular theme (.vimrc)

Editor config files are great for ensuring consistent formatting across projects, but we can also tell a Vim editor to use a specific theme in a .vimrc file:

" Use the Solarized Dark theme set background=dark colorscheme solarized let g:solarized_termtrans=1

Bonus: Helpful Terminal recipes for macOS

OK, so here’s a little bit of a bonus for Mac users that isn’t related to dotfiles, but are things we can do in the Terminal to give macOS superpowers to do pretty awesome things that make day-to-day use a little easier and more pleasant.

First off, we can show hidden files by default in the Finder so dotfiles are visible all the time by typing this into the Terminal:

defaults write com.apple.finder AppleShowAllFiles -bool true

Find the way that scrollbars toggle on and off in Finder jarring? Let’s make them visible at all times:

defaults write NSGlobalDomain AppleShowScrollBars -string "Always"

By default, macOS checks for software updates once per week. But maybe we want to check once a day or at some other interval:

defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 1

You know how holding down on a keyboard key repeats that character? Well, it repeats at a determined speed that we can supercharge to blazingly fast:

defaults write NSGlobalDomain KeyRepeat -int 0

Some people love the way macOS includes a box shadow when taking a screenshot of a window. Others don’t. Here’s how to turn it off:

defaults write com.apple.screencapture disable-shadow -bool true

And, in this example, we can automate the size of icons in the Dock:

defaults write com.apple.dock tilesize -int 36

This is only the tip of the iceberg! In my screencast series I go over more than one hundred of them.

Conclusion

Web development is increasingly more complicated as time goes on. We all have ways of making our development workflow a little easier and comfortable based on personal preferences.

You may be a seasoned developer and aware of such things as Node, npm, and Git but still find yourself stuck in a Terminal window with a bunch of errors. Or, you might be starting out and find these, and other tools, complex and tough to grasp.

Either way, hopefully knowing more about dotfiles and what they’re capable of doing gives you a new weapon in your arsenal to make your development environment tailored to you, speed up your workflow and give your machine added superpowers!

As a reminder, my screencast series will give you more tips and tricks, plus a good idea of how to get your development environment set up. This is the first in the series. Going forwards, I’m going to look at expanding on it, so please let me know if there’s anything else you’d like me to cover!

The post Using Dotfiles for Managing Development and Many Other Magical Things appeared first on CSS-Tricks.

CSS-Tricks

, , , , , ,
[Top]

The Many Ways to Change an SVG Fill on Hover (and When to Use Them)

SVG is a great format for icons. Vector formats look crisp and razor sharp, no matter the size or device — and we get tons of design control when using them inline.

SVG also gives us another powerful feature: the ability to manipulate their properties with CSS. As a result, we can make quick and simple interactions where it used to take crafty CSS tricks or swapping out entire image files.

Those interactions include changing color on hover states. It sounds like such a straightforward thing here in 2019, but there are actually a few totally valid ways to go about it — which only demonstrates the awesome powers of SVG more.

First off, let’s begin with a little abbreviated SVG markup:

<svg class="icon">   <path .../> </svg>

Target the .icon class in CSS and set the SVG fill property on the hover state to swap colors.

.icon:hover {   fill: #DA4567; }

This is by far the easiest way to apply a colored hover state to an SVG. Three lines of code!

SVGs can also be referenced using an <img> tag or as a background image. This allows the images to be cached and we can avoid bloating your HTML with chunks of SVG code. But the downside is a big one: we no longer have the ability to manipulate those properties using CSS. Whenever I come across non-inline icons, my first port of call is to inline them, but sometimes that’s not an option.

I was recently working on a project where the social icons were a component in a pattern library that everyone was happy with. In this case, the icons were being referenced from an <img> element. I was tasked with applying colored :focus and :hover styles, without adjusting the markup.

So, how do you go about adding a colored hover effect to an icon if it’s not an inline SVG?

CSS Filters

CSS filters allow us to apply a whole bunch of cool, Photoshop-esque effects right in the browser. Filters are applied to the element after the browser renders layout and initial paint, which means they fall back gracefully. They apply to the whole element, including children. Think of a filter as a lens laid over the top of the element it’s applied to.

These are the CSS filters available to us:

  • brightness(<number-percentage>);
  • contrast(<number-percentage>);
  • grayscale(<number-percentage>);
  • invert(<number-percentage>);
  • opacity(<number-percentage>);
  • saturate(<number-percentage>);
  • sepia(<number-percentage>);
  • hue-rotate(<angle>);
  • blur(<length>);
  • drop-shadow(<length><color>);

All filters take a value which can be changed to adjust the effect. In most cases, this value can be expressed in either a decimal or percent units (e.g. brightness(0.5) or brightness(50%)).

Straight out of the box, there’s no CSS filter that allows us to add our own specific color.
We have hue-rotate(), but that only adjusts an existing color; it doesn’t add a color, which is no good since we’re starting with a monochromatic icon.

The game-changing bit about CSS filters is that we don’t have to use them in isolation. Multiple filters can be applied to an element by space-separating the filter functions like this:

.icon:hover {   filter: grayscale(100%) sepia(100%); }

If one of the filter functions doesn’t exist, or has an incorrect value, the whole list is ignored and no filter will be applied to the element.

When applying multiple filter functions to an element, their order is important and will affect the final output. Each filter function will be applied to the result of the previous operation.

So, in order to colorize our icons, we have to find the right combination.

To make use of hue-rotate(), we need to start off with a colored icon. The sepia() filter is the only filter function that allows us to add a color, giving the filtered element a yellow-brown-y tinge, like an old photo.

The output color is dependent on the starting tonal value:

In order to add enough color with sepia(), we first need to use invert() to convert our icon to a medium grey:

.icon:hover {   filter: invert(0.5) }

We can then add the yellow/brown tone with sepia():

.icon:hover {   filter: invert(0.5) sepia(1); }

…then change the hue with hue-rotate():

.icon:hover {   filter: invert(0.5) sepia(1) hue-rotate(200deg);                                   }

Once we have the rough color we want, we can tweak it with saturation() and brightness():

.icon:hover {   filter:      invert(0.5)     sepia(1)     hue-rotate(200deg)     saturate(4)     brightness(1); }

I’ve made a little tool for this to make your life a little easier, as this is a pretty confusing process to guesstimate.

See the Pen CSS filter example by Cassie Evans (@cassie-codes)
on CodePen.

Even with the tool, it’s still a little fiddly, not supported by Internet Explorer, and most importantly, you’re unable to specify a precise color.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
18* 15* 35 No 18 6*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1* 46 No 4.4* 71 64

So, what do we do if we need a specific hex code?

SVG Filters

If we need more precise control (and better browser support) than CSS filters can offer, then it’s time to turn to SVG.

Filters originally came from SVG. In fact, under the hood, CSS filters are just shortcuts to SVG filters with a particular set of values baked in.

Unlike CSS, the filter isn’t predefined for us, so we have to create it. How do we do this?

This is the syntax to define a filter:

<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">   <defs>     <filter id="id-of-your-filter">       ...                        ...     </filter>     ...   </defs> </svg>

Filters are defined by a <filter> element, which goes inside the <defs> section of an SVG.

SVG filters can be applied to SVG content within the same SVG document. Or, the filter can be referenced and applied to HTML content elsewhere.

To apply an SVG filter to HTML content, we reference it the same way as a CSS filter: by using the url() filter function. The URL points to the ID of the SVG filter.

.icon:hover {   filter: url('#id-of-your-filter'); }

The SVG filter can be placed inline in the document or the filter function can reference an external SVG. I prefer the latter route as it allows me to keep my SVG filters tidied away in an assets folder.

.icon:hover {   filter: url('assets/your-SVG.svg#id-of-your-filter'); }

Back to the <filter> element itself.

<filter id="id-of-your-filter">   ...                ... </filter>

Right now, this filter is empty and won’t do anything as we haven’t defined a filter primitive. Filter primitives are what create the filter effects. There are a number of filter primitives available to us, including:

  • [<feBlend>]
  • [<feColorMatrix>]
  • [<feComponentTransfer>]
  • [<feComposite>]
  • [<feConvolveMatrix>]
  • [<feDiffuseLighting>]
  • [<feDisplacementMap>]
  • [<feDropShadow>]
  • [<feFlood>]
  • [<feGaussianBlur>]
  • [<feImage>]
  • [<feMerge>]
  • [<feMorphology>]
  • [<feOffset>]
  • [<feSpecularLighting>]
  • [<feTile>]
  • [<feTurbulence>]

Just like with CSS filters, we can use them on their own or include multiple filter primitives in the <filter> tag for more interesting effects. If more than one filter primitive is used, then each operation will build on top of the previous one.

For our purposes we’re just going to use feColorMatrix, but if you want to know more about SVG filters, you can check out the specs on MDN or this (in progress, at the time of this writing) article series that Sara Soueidan has kicked off.

feColourMatrix allows us to change color values on a per-channel basis, much like channel mixing in Photoshop.

This is what the syntax looks like:

<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">   <defs>     <filter id="id-of-your-filter">       <feColorMatrix         color-interpolation-filters="sRGB"         type="matrix"         values="1 0 0 0 0                 0 1 0 0 0                 0 0 1 0 0                 0 0 0 1 0 "/>     </filter>     ...   </defs> </svg>

Let’s have a closer look at the color matrix values.

The first four columns represent the red, green and blue channels of color and the alpha (opacity) value. The rows contain the red, green, blue and alpha values in those channels.

The M column is a multiplier — we don’t need to change any of these values for our purposes here. The values for each color channel are represented as floating point numbers in the range 0 to 1.

We could write these values as a CSS RGBA color declaration like this:

rgba(255, 255, 255, 1)

The values for each color channel (red, green and blue) are stored as integers in the range 0 to 255. In computers, this is the range that one 8-bit byte can offer.

By dividing these color channel values by 255, the values can be represented as a floating point number which we can use in the feColorMatrix.

And, by doing this, we can create a color filter for any color with an RGB value!

Like teal, for example:

rgba(0, 128, 128, 1). 128%255=0.50

See the Pen
SVG filter – teal hover
by Cassie Evans (@cassie-codes)
on CodePen.

This SVG filter will only impart color to icons with a white fill, so If we have an icon with a black fill, we can use invert() to convert it to white before applying the SVG filter.

.icon:hover {   filter: invert(100%) url('assets/your-SVG.svg#id-of-your-filter'); }

If we just have a hex code, the math is a little trickier, although there are plenty of hex-to-RGBA converters out there. To help out, I’ve made a HEX to feColorMatrix converter.

See the Pen
HEX to feColorMatrix converterr
by Cassie Evans (@cassie-codes)
on CodePen.

Have a play around, and happy filtering!

The post The Many Ways to Change an SVG Fill on Hover (and When to Use Them) appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]