1,000 SVG Icons!

Well, 996 to be exact.

I think it’s fair to say that Font Awesome is the most successful icon project ever, and in addition to their paid offerings, they have an open-source free version. We’ve always offered up SVG icons you can easily copy/paste in our free Assets panel, but up until now, there were only ~20 of them. So, ya know, a 50× increase ain’t bad. Especially since the way we were able to integrate this is way easier than what we were doing before because they publish the icons in a JavaScript format that is easy for us to use in React components.

More icons. Better icons. Easier to maintain.

Here’s how it works:

Despite the name “Font Awesome”, we’re not delivering these icons as a font, we’re offering up inline <svg> you can copy and paste.

If you prefer using icon fonts, you might wanna check out the project We Love Icon Fonts which is like a CDN for hosting icon web fonts.

High five to Mr. Shaw on this one who had the idea and got this implemented for us.

The post 1,000 SVG Icons! appeared first on CodePen Blog.

Vue 3.0 has entered Release Candidate stage!

Vue is in the process of a complete overhaul that rebuilds the popular JavaScript framework from the ground up. This has been going on the last couple of years and, at long last, the API and implementation of Vue 3 core are now stabilize. This is exciting for a number of reasons:

  • Vue 3 promises to be much more performant than Vue 2.
  • Despite being a complete rewrite, the surface API hasn’t changed drastically, so there’s no need to forget what you already know about Vue.
  • The Vue documentation was completely migrated revised. (If you see me celebrating that, it’s because I helped work on it.)
  • There are several new features — like the Composition API (inspired by React Hooks) — that are additive and helpful for composition between multiple components.

Here’s how you can get your hands on the Vue 3 release candidate:

There is more information about DevTools, experimental features and more in the release notes.

Docs updates, now in beta

Why am I so excited about the Vue doc updates? Because the updates include but are not limited to:

We are still actively working on things, of course, so if you see to-dos or unresolved work, please let us know! Feel free to open an issue or PR over at GitHub but, please, note that large requests will likely be closed out while we’re still refining our current work.

All in all we think you’ll enjoy it! It’s all the features you know and love, with some extra lovely bits, plus excellent performance.


The post Vue 3.0 has entered Release Candidate stage! appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CMD+Z for Git is Here

Version control with Git has become a “commodity” by now: virtually every software project today uses Git, and virtually every developer knows Git to some extent. This explains why I sometimes hear the following question when I talk about what I do for a living: “A desktop client for Git? Why would I need that? I can do that on the command line!

If I’m lucky, I have a computer next to me when that question hits me. And instead of producing a wordy answer, I do a couple of things in Tower, our desktop client for Git.

Anyone who’s ever performed an “Interactive Rebase” is amazed by how easy that is in Tower: you simply drag and drop to combine commits or reorder them. And anyone who hasn’t yet used “Interactive Rebase” – because it was too complicated and clunky to use on the command line – now understands that it’s a very valuable tool.

Or I might make a mistake: accidentally deleting a branch or messing up a merge in a terrible way. And I’ll simply hit CMD+Z, like I would in a text editor, to undo the mess I just made.

People then start to realize that the real question is not: “Can I get by using Git on the command line?” The more important questions are:

  • Can I use all of Git’s power? (Even the advanced features that might be hard to use, but that can be very valuable…)
  • Can I work with Git in a productive way? (Not having to look up parameters, not spending too much time on my workflows…)
  • Can I work with Git in an easy way? (Without having to think about it too much…)

We – a small team of just 9 people – have spent the last 10 years answering those questions by building Tower.

How to Undo Mistakes

One of Git’s greatest features is that it allows you to undo almost anything. However, it requires quite some experience to know how exactly to undo your particular kind of mess: a failed merge has to be cleaned up differently than a deleted branch!

After working on this for a long time, Tower now allows you to undo virtually anything – simply by pressing CMD+Z! (Note: the “Undo” feature is a quite recent addition and first available in the Mac version of Tower. It will soon come to Windows, too).

No matter if you messed up a merge, inadvertently deleted a branch, discarded a valuable local change, published a branch on a remote too soon, or simply committed something that you shouldn’t have – your lifesaver is as simple as “CMD+Z”, and it’s always available.

The Power of Interactive Rebase

Interactive Rebase is a wonderful example of Git’s more powerful features. It allows you to…

  • edit old commits (both their messages as well as their changesets!)
  • combine multiple commits into one
  • reorder commits
  • …and even delete commits you don’t need anymore!

All of these can help a lot to keep a code base clean and structured. But being a very powerful tool, Interactive Rebase is also an example of a Git feature that is quite complicated to use!

Many beginners are scared away by this complexity – meaning that, of course, they will miss out on the benefits of the feature! Many experienced developers know and use Interactive Rebase; but since the feature is hard to use, it costs them a lot of time and/or they make mistakes from time to time.

Knowing this, we had two goals for integrating Interactive Rebase into Tower: on the one hand, we wanted to reduce as much of its complexity as possible. And on the other hand, we wanted to make the feature easily accessible.

The result is that Interactive Rebase is now integrated right into the “Commit History” and accessible via simple drag & drop and menu options:

Countless developers that wouldn’t have used Interactive Rebase at all on the Command Line are now using it on a daily basis in Tower.

Quick Actions

Almost independent of its size, working in a code base means spending a lot of time searching: for example for a certain branch (out of lots of branches) or a certain file (out of lots of files).

Tower allows you to do most of your daily tasks without sifting through data – and even without taking your hands off the keyboard. The “Quick Action” dialog takes almost any input and allows you to simply act on it:

  • Give it a branch name and it will offer to do a checkout.
  • Give it a file name and it will offer to show it in the File History.
  • Give it a commit hash and it will offer to show that commit’s details.

Being able to perform many tasks right from the keyboard, without having to search and sift through loads of data, can make life as a developer a lot easier.

Solving Conflicts with Confidence

Everyone hates that moment when a merge (or rebase) stops and leaves you with a bunch of conflicts 😱 Multiple questions then quickly enter the poor programmer’s mind:

  • What are my changes? What are someone else’s?
  • What actually happened?
  • Why me?

While, admittedly, Tower cannot answer all of those questions, it offers a special “Conflict Wizard” that helps make the situation much more understandable:

You can easily see where changes came from and can solve the conflict simply by choosing which version to go with (or jump into a dedicated merge tool). It makes things a lot easier when merge conflicts are visualized in this way, instead of being an abstract mess.

Becoming More Productive

When building and improving Tower, we’re always striving to make things easier for our users – and to make them more productive. Let’s take some examples of where this shows in Tower:

  • No More Passwords, Tokens, SSH Keys: You can easily connect your GitHub / GitLab / Bitbucket / Azure DevOps accounts with Tower. Once connected, you never have to wrestle with passwords, authentication, tokens, usernames, and SSH Keys anymore. Cloning and interacting with a remote repository, then, is a matter of just a click.
  • Single-Line Staging & Discarding: There’s a golden rule in version control: when you make a commit, you should only include changes from a single topic (and not mix multiple topics in a commit, thereby making it extremely hard to understand what actually happened). With the ability to stage / unstage / discard individual chunks and lines from your changes, Tower enables you to create granular, precise commits.
  • A New Diff Viewer: In a very recent update, we gave our internal Diff Viewer a complete overhaul. It now highlights inline changes, allows you to show/hide whitespace changes, can display the complete file, and is completely customizable with themes!
  • Automations for the Boring Stuff: Tower takes care of much of the grunt work around Git. To take just two examples: neither do you have to regularly fetch new updates from the remote, nor do you have to remember to stage uncommitted changes before pulling/switching branches/merging… Tower does that automatically for you.

When I think about the favorite applications I use myself, they all have some things in common: they make life easier for me, they make me more productive, and they enable me to do advanced stuff that I’d have a hard time doing without them. I’m glad and grateful that many of our users consider Tower to be one of their favorite apps!

If you want to give Tower a try, just download it from our website and test it 30 days for free. And if you are a student or teacher, you can use Tower for free!


The post CMD+Z for Git is Here appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Vonage Launches Vonage Voyagers to Foster Developer Feedback and Community Growth

Vonage, a global cloud communication services provider, has announced a new developer program called Vonage Voyagers. This new program is intended to help build a developer community that provides the company with product feedback and user-generated content. To support this, Vonage is committed to providing this new community with increased support, in-depth training, and early access to APIs.

How to Organize WordPress Files in Media Library Folders

Do you want to organize WordPress files in the media library folders?

By default, WordPress automatically creates folders in the media library based on year and months. However, some users may want to create their own custom folders for different media files.

In this article, we’ll show you how to easily organize WordPress files in custom media library folders.

Organizing your media library folders in WordPress

Why Organize Your Files in Media Library Folders?

Normally, WordPress stores all your images and other media files in the /wp-content/uploads/ folder. To keep it structured, all files are stored in folders organized by year and month.

https://example.com/wp-content/uploads/2020/07/

This works perfectly for most websites. However, some users may want to get better control on how WordPress stores media files.

For instance, a photography website may want to organize WordPress images by topic, location, or event folders. Similarly, a portfolio website may want to organize their media uploads by type, client, industry, and more.

This allows them to easily browse their media files. At the same time, it improves image SEO, as you can now add keywords in your image file URLs which makes URLs more meaningful.

Having said that, let’s take a look at how to easily create folders to organize your WordPress media files.

How to Organize Your WordPress Files in Media Library Folders

First, you need to install and activate the Media Library Folders plugin. For more details, see our step by step guide on how to install a WordPress plugin.

Note: The free version of the plugin only lets you create up to 10 folders. You will need to upgrade to the pro version if you want to make more.

Upon activation, the plugin will add a new menu item labeled ‘Media Library Folders’ in your WordPress admin sidebar. Clicking on it will open plugin’s folder view showing all the folders inside your WordPress upload directory.

The Media Library Folders page within your WordPress dashboard

From here, you can create new folders and add files to them. You can also move, copy, rename, or delete your files.

We’re going to create some new folders and add images to them.

To create a new folder, simply click the ‘Add Folder’ button and then type in the name you want to use for that folder.

Tip: You cannot use spaces in folder names. Instead, use hyphen or underscore to separate words if needed.

Adding a new folder using the Media Library Folders plugin

It’s also possible to make subfolders within folders, if needed. To create subfolders, simply click on the parent folder to select it, and then click on the ‘Add Folder’ button.

Adding a subfolder using Media Library Folders

We created two subfolders for our ‘Landscape-Photos’ folder. They are ‘Forests’ and ‘Mountains’. To view a subfolder, you need to click on the small arrow to the left of the main folder:

Click the small arrow to expand a folder to see the subfolders

To add files to your folders, simply click on the folder then click the ‘Add File’ button. After that, go ahead and upload as many files as you want.

Uploading files using the Media Library Folders plugin

Once you’re done uploading files, you’ll see them on the screen as thumbnails with the filename below:

The uploaded images showing in the Forests folder

It’s easy to add your uploaded files to your posts or pages. You can add them just like any other files that you’ve uploaded to the media library:

Viewing the uploaded images in the Windows Media Library

Moving and Copying Your Files in Media Library Folders

What if you need to move a file to a different WordPress media library folder? It’s easy to move it or copy it using Media Library Folders.

Moving an Image to a New Folder in the Media Library

To move an image or any other file, simply check that the move/copy toggle is set to ‘Move’ and then drag the image to the correct folder.

Tip: Your mouse pointer should be on the new folder, as shown below. The small thumbnail of the image is just showing you what you’re moving, not where you’re moving it to.

In this example, a mountain image was incorrectly placed in the Forests folder. We are moving it to the Mountains folder.

Moving an image into the Mountains folder

Copying an Image to a Different Folder in the Media Library

To copy an image, set the move/copy toggle to ‘Copy’, then go ahead and drag the image as before. Here, we are copying an image of a bird and flower, so that it’s in both the ‘Bird-Photos’ and the ‘Flower-Photos’ folders.

Copying a photo so that you have it in two folders

This time, your original image will stay in place. Your image will be duplicated so that it can be present in both folders.

Renaming Files and Folders in Media Library Folders

You can easily change the filename with the Media Library Folders plugin. First, find the file you want to change and click the checkbox below it. Next, click the ‘Rename’ button at the top of the screen.

After that, type in the filename you want to use. Image filenames can have a small impact on your WordPress SEO, so it’s recommended to use keywords within them. Here, we’ve changed the file name for a post on inspiring forest images:

Changing the file name of an image using the Media Library Folders plugin

You cannot rename or move a folder in Media Library Folders. However, it’s possible to create a new folder, move all the images into it, then delete the old folder.

To delete a folder, right click on it, and then click ‘Delete this folder?’ button. Here, we’ve moved the forest images into a new folder called Woodlands, and we’re deleting the Forests folder:

Deleting a folder using the Media Library Folders plugin

You’ll then see a message prompting you to confirm. Click ‘OK’ to continue and the folder will be deleted. You’ll no longer see it in the list:

The Forest folder has now been deleted

Tip: You may see the message ‘This folder is not empty and could not be deleted’ even though the folder looks empty. Simply click the ‘Sync’ button. WordPress may have created additional versions of your images that need deleting. After syncing, you’ll be able to review and delete those images.

Click the Sync button to check for other files in the folder

We hope this article helped you learn how to organize WordPress files in media library folders. You might also want to check out our articles on fixing common image issues in WordPress and other must have WordPress plugins for business websites.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Organize WordPress Files in Media Library Folders appeared first on WPBeginner.

How To Use Styled-Components In React

How To Use Styled-Components In React

How To Use Styled-Components In React

Adebiyi Adedotun

Styled components are a CSS-in-JS tool that bridges the gap between components and styling, offering numerous features to get you up and running in styling components in a functional and reusable way. In this article, you’ll learn the basics of styled components and how to properly apply them to your React applications. You should have worked on React previously before going through this tutorial. If you’re looking for various options in styling React components, you can check out our previous post on the subject.

At the core of CSS is the capability to target any HTML element — globally — no matter its position in the DOM tree. This can be a hindrance when used with components, because components demand, to a reasonable extent, colocation (i.e. keeping assets such as states and styling) closer to where they’re used (known as localization).

In React’s own words, styled components are “visual primitives for components”, and their goal is to give us a flexible way to style components. The result is a tight coupling between components and their styles.

Note: Styled components are available both for React and React Native, and while you should definitely check out the React Native guide, our focus here will be on styled components for React.

Why Styled Components?

Apart from helping you to scope styles, styled components include the following features:

  • Automatic vendor prefixing
    You can use standard CSS properties, and styled components will add vendor prefixes should they be needed.
  • Unique class names
    Styled components are independent of each other, and you do not have to worry about their names because the library handles that for you.
  • Elimination of dead styles
    Styled components remove unused styles, even if they’re declared in your code.
  • and many more.

Installation

Installing styled components is easy. You can do it through a CDN or with a package manager such as Yarn…

yarn add styled-components

… or npm:

npm i styled-components

Our demo uses create-react-app.

Starting Out

Perhaps the first thing you’ll notice about styled components is their syntax, which can be daunting if you don’t understand the magic behind styled components. To put it briefly, styled components use JavaScript’s template literals to bridge the gap between components and styles. So, when you create a styled component, what you’re actually creating is a React component with styles. It looks like this:

import styled from "styled-components";

// Styled component named StyledButton
const StyledButton = styled.button`
  background-color: black;
  font-size: 32px;
  color: white;
`;

function Component() {
  // Use it like any other component.
  return <StyledButton> Login </StyledButton>;
}

Here, StyledButton is the styled component, and it will be rendered as an HTML button with the contained styles. styled is an internal utility method that transforms the styling from JavaScript into actual CSS.

In raw HTML and CSS, we would have this:

button {
  background-color: black;
  font-size: 32px;
  color: white;
}

<button> Login </button>

If styled components are React components, can we use props? Yes, we can.

Adapting Based on Props

Styled components are functional, so we can easily style elements dynamically. Let’s assume we have two types of buttons on our page, one with a black background, and the other blue. We do not have to create two styled components for them; we can adapt their styling based on their props.

import styled from "styled-components";

const StyledButton = styled.button`
  min-width: 200px;
  border: none;
  font-size: 18px;
  padding: 7px 10px;
  /* The resulting background color will be based on the bg props. */
  background-color: ${props => props.bg === "black" ? "black" : "blue";
`;

function Profile() {
  return (
    <div>
      <StyledButton bg="black">Button A</StyledButton>
      <StyledButton bg="blue">Button B</StyledButton>
    </div>
  )
}

Because StyledButton is a React component that accepts props, we can assign a different background color based on the existence or value of the bg prop.

You’ll notice, though, that we haven’t given our button a type. Let’s do that:

function Profile() {
  return (
    <>
      <StyledButton bg="black" type="button">
        Button A
      </StyledButton>
      <StyledButton bg="blue" type="submit" onClick={() => alert("clicked")}>
        Button B
      </StyledButton>
    </>
  );
}

Styled components can differentiate between the types of props they receive. They know that type is an HTML attribute, so they actually render <button type="button">Button A</button>, while using the bg prop in their own processing. Notice how we attached an event handler, too?

Speaking of attributes, an extended syntax lets us manage props using the attrs constructor. Check this out:

const StyledContainer = styled.section.attrs((props) => ({
  width: props.width || "100%",
  hasPadding: props.hasPadding || false,
}))`
  --container-padding: 20px;
  width: ${(props) => props.width}; // Falls back to 100%
  padding: ${(props) =>
    (props.hasPadding && "var(--container-padding)") || "none"};
`;

Notice how we don’t need a ternary when setting the width? That’s because we’ve already set a default for it with width: props.width || "100%",. Also, we used CSS custom properties because we can!

Note: If styled components are React components, and we can pass props, then can we also use states? The library’s GitHub account has an issue addressing this very matter.

Extending Styles

Let’s say you’re working on a landing page, and you’ve set your container to a certain max-width to keep things centered. You have a StyledContainer for that:

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

Then, you discover that you need a smaller container, with padding of 10 pixels on both sides, instead of 20 pixels. Your first thought might be to create another styled component, and you’d be right, but it wouldn’t take any time before you realize that you are duplicating styles.

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

const StyledSmallContainer = styled.section`
  max-width: 1024px;
  padding: 0 10px;
  margin: 0 auto;
`;

Before you go ahead and create StyledSmallContainer, like in the snippet above, let’s learn the way to reuse and inherit styles. It’s more or less like how the spread operator works:

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

// Inherit StyledContainer in StyledSmallConatiner
const StyledSmallContainer = styled(StyledContainer)`
  padding: 0 10px;
`;

function Home() {
  return (
    <StyledContainer>
      <h1>The secret is to be happy</h1>
    </StyledContainer>
  );
}

function Contact() {
  return (
    <StyledSmallContainer>
      <h1>The road goes on and on</h1>
    </StyledSmallContainer>
  );
}

In your StyledSmallContainer, you’ll get all of the styles from StyledContainer, but the padding will be overridden. Keep in mind that, ordinarily, you’ll get a section element rendered for StyledSmallContainer, because that’s what StyledContainer renders. But that doesn’t mean it’s carved in stone or unchangeable.

The “as” Polymorphic Prop

With the as polymorphic prop, you can swap the end element that gets rendered. One use case is when you inherit styles (as in the last example). If, for example, you’d prefer a div to a section for StyledSmallContainer, you can pass the as prop to your styled component with the value of your preferred element, like so:

function Home() {
  return (
    <StyledContainer>
      <h1>It’s business, not personal</h1>
    </StyledContainer>
  );
}

function Contact() {
  return (
    <StyledSmallContainer as="div">
      <h1>Never dribble when you can pass</h1>
    </StyledSmallContainer>
  );
}

Now, StyledSmallContainer will be rendered as a div. You could even have a custom component as your value:

function Home() {
  return (
    <StyledContainer>
      <h1>It’s business, not personal</h1>
    </StyledContainer>
  );
}

function Contact() {
  return (
    <StyledSmallContainer as={StyledContainer}>
      <h1>Never dribble when you can pass</h1>
    </StyledSmallContainer>
  );
}

Don’t take it for granted.

SCSS-Like Syntax

The CSS preprocessor Stylis enables styled components to support SCSS-like syntax, such as nesting:

const StyledProfileCard = styled.div`
  border: 1px solid black;

  > .username {
    font-size: 20px;
    color: black;
    transition: 0.2s;

    &:hover {
      color: red;
    }

    + .dob {
      color: grey;
    }
  }
`;

function ProfileCard() {
  return (
    <StyledProfileCard>
      <h1 className="username">John Doe</h1>
      <p className="dob">
        Date: <span>12th October, 2013</span>
      </p>
      <p className="gender">Male</p>
    </StyledProfileCard>
  );
}

Animation

Styled components have a keyframes helper that assists with constructing (reusable) animation keyframes. The advantage here is that the keyframes will be detached from the styled components and can be exported and reused wherever needed.

import styled, {keyframes} from "styled-components";

const slideIn = keyframes`
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
`;

const Toast = styled.div`
  animation: ${slideIn} 0.5s cubic-bezier(0.4, 0, 0.2, 1) both;
  border-radius: 5px;
  padding: 20px;
  position: fixed;
`;

Global Styling

While the original goal of CSS-in-JS and, by extension, styled components is scoping of styles, we can also leverage styled components’ global styling. Because we’re mostly working with scoped styles, you might think that’s an invariable factory setting, but you’d be wrong. Think about it: What really is scoping? It’s technically possible for us — in the name of global styling — to do something similar to this:

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

But we already have a helper function — createGlobalStyle — whose sole reason for existence is global styling. So, why deny it its responsibility?

One thing we can use createGlobalStyle for is to normalize the CSS:

import {createGlobalStyle} from "styled-components";

const GlobalStyle = createGlobalStyle`
    /* Your css reset here */
`;

// Use your GlobalStyle
function App() {
  return (
    <div>
      <GlobalStyle />
      <Routes />
    </div>
  );
}

Note: Styles created with createGlobalStyle do not accept any children. Learn more in the documentation.

At this point, you might be wondering why we should bother using createGlobalStlye at all. Here are a few reasons:

  • We can’t target anything outside of the root render without it (for example, html, body, etc.).
  • createGlobalStyle injects styles but does not render any actual elements. If you look at the last example closely, you’ll notice we didn’t specify any HTML element to render. This is cool because we might not actually need the element. After all, we’re concerned with global styles. We are targeting selectors at large, not specific elements.
  • createGlobalStyle is not scoped and can be rendered anywhere in our app and will be applicable as long as it’s in the DOM. Think about the concept, not the structure.
import {createGlobalStyle} from "styled-components";

const GlobalStyle = createGlobalStyle`
  /* Your css reset here */

  .app-title {
    font-size: 40px;
  }
`;

const StyledNav = styled.nav`
    /* Your styles here */
`;

function Nav({children}) {
  return (
    <StyledNav>
      <GlobalStyle />
      {children}
    </StyledNav>
  );
}

function App() {
  return (
    <div>
      <Nav>
        <h1 className="app-title">STYLED COMPONENTS</h1>
      </Nav>
      <Main />
      <Footer />
    </div>
  );
}

If you think about the structure, then app-title should not be styled as set in GlobalStyle. But it doesn’t work that way. Wherever you choose to render your GlobalStyle, it will be injected when your component is rendered.

Be careful: createGlobalStyles will only be rendered if and when it’s in the DOM.

CSS Helper

Already we’ve seen how to adapt styles based on props. What if we wanted to go a little further? The CSS helper function helps to achieve this. Let’s assume we have two text-input fields with states: empty and active, each with a different color. We can do this:

const StyledTextField = styled.input`
  color: ${(props) => (props.isEmpty ? "none" : "black")};
`;

All’s well. Subsequently, if we need to add another state of filled, we’d have to modify our styles:

const StyledTextField = styled.input`
  color: ${(props) =>
    props.isEmpty ? "none" : props.active ? "purple" : "blue"};
`;

Now the ternary operation is growing in complexity. What if we add another state to our text-input fields later on? Or what if we want to give each state additional styles, other than color? Can you imagine cramping the styles into the ternary operation? The css helper comes in handy.

const StyledTextField = styled.input`
  width: 100%;
  height: 40px;

  ${(props) =>
    (props.empty &&
      css`
        color: none;
        backgroundcolor: white;
      `) ||
    (props.active &&
      css`
        color: black;
        backgroundcolor: whitesmoke;
      `)}
`;

What we’ve done is sort of expanded our ternary syntax to accommodate more styles, and with a more understandable and organized syntax. If the previous statement seems wrong, it’s because the code is trying to do too much. So, let’s step back and refine:

const StyledTextField = styled.input`
width: 100%;
height: 40px;

// 1. Empty state
${(props) =>
  props.empty &&
  css`
    color: none;
    backgroundcolor: white;
  `}

// 2. Active state
${(props) =>
  props.active &&
  css`
    color: black;
    backgroundcolor: whitesmoke;
  `}

// 3. Filled state
${(props) =>
  props.filled &&
  css`
    color: black;
    backgroundcolor: white;
    border: 1px solid green;
  `}
`;

Our refinement splits the styling into three different manageable and easy-to-understand chunks. It’s a win.

StyleSheetManager

Like the CSS helper, StyleSheetManager is a helper method for modifying how styles are processed. It takes certain props — like disableVendorPrefixes (you can check out the full list) — that help you opt out of vendor prefixes from its subtree.

import styled, {StyleSheetManager} from "styled-components";

const StyledCard = styled.div`
  width: 200px;
  backgroundcolor: white;
`;

const StyledNav = styled.div`
  width: calc(100% - var(--side-nav-width));
`;

function Profile() {
  return (
    <div>
      <StyledNav />
      <StyleSheetManager disableVendorPrefixes>
        <StyledCard> This is a card </StyledCard>
      </StyleSheetManager>
    </div>
  );
}

disableVendorPrefixes is passed as a prop to <StyleSheetManager>. So, the styled components wrapped by <StyleSheetManager> would be disabled, but not the ones in <StyledNav>.

Easier Debugging

When introducing styled components to one of my colleagues, one of their complaints was that it’s hard to locate a rendered element in the DOM — or in React Developer Tools, for that matter. This is one of the drawbacks of styled components: In trying to provide unique class names, it assigns unique hashes to elements, which happen to be cryptic, but it makes the displayName readable for easier debugging.

import React from "react";
import styled from "styled-components";
import "./App.css";

const LoginButton = styled.button`
  background-color: white;
  color: black;
  border: 1px solid red;
`;

function App() {
  return (
    <div className="App">
      <LoginButton>Login</LoginButton>
    </div>
  );
}

By default, styled components render LoginButton as <button class="LoginButton-xxxx xxxx">Login</button> in the DOM, and as LoginButton in React Developer Tools, which makes debugging easier. We can toggle the displayName boolean if we don’t want this behavior. This requires a Babel configuration.

Note: In the documentation, the package babel-plugin-styled-components is specified, as well as a .babelrc configuration file. The issue with this is that, because we’re using create-react-app, we can’t configure a lot of things unless we eject. This is where Babel macros come in.

We’ll need to install babel-plugin-macros with npm or Yarn, and then create a babel-plugin-macros.config.js at the root of our application, with the content:

module.exports = {
  styledComponents: {
    displayName: true,
    fileName: false,
  },
};

With the fileName value inverted, the displayName will be prefixed with the file name for even more unique precision.

We also now need to import from the macro:

// Before
import styled from "styled-components";

// After
import styled from "styled-components/macro";

Conclusion

Now that you can programmatically compose your CSS, do not abuse the freedom. For what it’s worth, do your very best to maintain sanity in your styled components. Don’t try to compose heavy conditionals, nor suppose that every thing should be a styled component. Also, do not over-abstract by creating nascent styled components for use cases that you are only guessing are somewhere around the corner.

Further Resources

  1. Documentation, Styled Components
  2. Building a Reusable Component System with React.js and styled-components”, Lukas Gisder-Dubé
  3. Usage with Next.js
  4. Usage with Gatsby
Smashing Editorial (ks, ra, yk, al, il)