Archive

Archive for November, 2021

What do you get for using a search input type?

November 17th, 2021 No comments

Like this:

  1. You get an extra-round-y appearance in Safari, which at one time matched the macOS look for search inputs, but not really anymore. I don’t hate the look, except…
  2. Safari totally ignores the font-size you set on it, so careful about that. Unless you smash off the round-y look with -webkit-appearance: none—then you can, so probably 92% of all websites do this.
  3. You get a little × icon inside the input (when it has a value) that clears it out. This is probably the best reason to use it, and mercifiully you get to keep it even after resetting the appearance.
  4. You get the satisfaction of knowing that you’re using the semantically correct input type for the job, assuming you are building a thing that actually searches something.
  5. You get past search terms with autocomplete. Browsers store those past search terms and offer a menu for autocompleting them. I’m trying to make this a list of things that are unique to search inputs, and I can prove this happens on non-search inputs. But hey, it does make the most sense on search inputs.
  6. You get the pleasure of adding a role to the parent form (i.e. ) because that helps assistive technology announce it as a search form.
  7. You get to remember to add a proper to the input. Just using a magnifying glass icon or just a placeholder alone won’t cut it, even though that’s what a lot of designs call for visually.
  8. You get a super weird incremental attribute that sends a debounced search event to the DOM element itself. I guess that is useful for live search UX. But it’s non-standard and not in Firefox so probably don’t count on it (via Christian Shaefer).
  9. You get to live another day as a front-end developer.

The post What do you get for using a search input type? appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Cherry-Picking Commits in Git

November 17th, 2021 No comments

This article is part of our “Advanced Git” series. Be sure to follow us on Twitter or sign up for our newsletter to hear about the next articles!

In part 5 of this series, we looked at rebasing and merging. Although there are a couple of differences between git merge and git rebase, both commands have the same goal: they integrate changes from one branch into another.

Today, we’ll look at git cherry-pick and how it allows us to integrate selected, individual commits from any branch into our current HEAD branch. This is a big difference compared to git merge or git rebase, which both integrate all new commits from the specified branch.

So why would you want to do this and pick only one commit from a branch to apply it to another one? There are different reasons, of course, but an especially helpful one is to undo changes. Let’s say you accidentally made a commit on the wrong branch. Using cherry-pick this is not a big problem: you can switch to the correct branch and then cherry pick the commit!

Advanced Git series:


Before we look at a practical example, a word of warning: don’t get too excited about cherry picking. Your primary goal should be to work on a branch level, and both git merge and git rebase were built exactly for this job. Cherry picking is meant for special occasions, not as a replacement for merging and rebasing.

Moving a commit to another branch

Here’s a real-life scenario to explain when cherry picking is the right approach. Let’s say you committed something to the master branch that was intended for the feature/newsletter instead. What now? Do you have to call your team members or your boss to explain this “mistake”?

The following screenshot of Tower, a graphical Git client for macOS and Windows, shows the problem and the commit 26bf1b48 which was accidentally made on the master branch:

Showing the Tower app UI with a commit history of a master branch. Red arrows point to the most recent commit and the newsletter branch,. indicating that is where the commit was intended to go.

Alternatively, you can examine the situation on the command line if you type git log in the terminal:

$ git log
commit 26bf1b4808ba9783e4fabb19ec81e7a4c8160194 (HEAD -> master)
Author: Tobias Günther
Date:   Fri Oct 5 09:58:03 2018 +0200

    Newsletter signup page

So, the commit with the ID 26bf1b48 ended up in master, but you should’ve committed it to the branch feature/newsletter. Let’s cherry pick that particular commit and move it to the correct branch. First, you switch branches, and then you cherry pick the commit:

$ git checkout feature/newsletter
Switched to branch 'feature/newsletter'
$ git status
On branch feature/newsletter
nothing to commit, working tree clean
$ git cherry-pick 26bf1b48
[feature/newsletter 7fb55d0] Newsletter signup page
 Author: Tobias Günther <tg@fournova.com>
 Date: Fri Oct 5 09:58:03 2018 +0200
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 signup.html

If you run git log again, you can see the new commit on the feature/newsletter branch:

$ git log
commit 7fb55d06a8e70fdce46921a8a3d3a9de7f7fb8d7 (HEAD -> feature/newsletter)
Author: Tobias Günther <tg@fournova.com>
Date:   Fri Oct 5 09:58:03 2018 +0200

    Newsletter signup page

What happened in the background? Git created a copy of the commit with the same changes and the same commit message on the feature/newsletter branch. It is, however, a completely new commit with its own, new ID. And what about the original commit?

Cleaning up the other branch

If you check the master branch, you can still see that “wrong” commit. This means that cherry picking doesn’t “move” a picked commit from the original branch; it merely creates a copy and leaves the original untouched.

Now, in order to clean up and undo the commit, you can use git reset.

$ git checkout master
Switched to branch 'master'
$ git reset --hard HEAD~1
HEAD is now at 776f8ca Change about title and delete error page

That’s it — like nothing ever happened.

In case you’re using a GUI app like Tower, this is what the whole process looks like:

Animated screenshot showing a commit being dragged from master branch and dropped on the feature/newsletter branch where it was intended to go.

A tool for special cases, not the everyday integration

Whenever you can use a traditional merge or rebase, you should do so. Cherry picking should be reserved for cases when a git merge or git rebase is not possible, when you want to move only individual commits from one branch to another. Always keep in mind that git cherry-pick creates “duplicate” commits and that you should clean up afterwards.

If you want to dive deeper into advanced Git tools, feel free to check out my (free!) “Advanced Git Kit”: it’s a collection of short videos about topics like branching strategies, Interactive Rebase, Reflog, Submodules and much more.

Happy cherry picking — and see you soon for the next part in our series on “Advanced Git”!

Advanced Git series:


The post Cherry-Picking Commits in Git appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

The Gap (Design Engineering)

November 17th, 2021 No comments

Egor Kloos describes a situation where a (purely visual) designer asks for some changes to a component. There is a misunderstanding where the (code monkey) developer implements the change exactly as requested—but really what was required was both a bug fix and a new variation to the component. Because of the skill siloing: problems.

Designers move from idea to a wireframe, a prototype, a logo, or even just a drawing. Developers move from a problem or feature to a coded solution that is solved and released. Both are creative, both are in aid of the end-user. The Design Engineer role is also creative and authors code but systematically translates a design towards implementation in a structured way. 

Design Engineering is certainly becoming at thing! You can listen to Natalya Shelburne talk about it on an episode of ShopTalk, and there is a whole book on it. I suspect it is similar-but-different (somehow?) to the term “DesignOps.” I heard Cameron asking about that the other day and got some good responses.

I find all this fascinating. In the beginning, we had the webmaster and that role did all the things. The webmaster was pulled into two, front-end and back-end developer. Design was maybe a bit lumped into front-end, but has now clearly pulled away as a very distinct role. Back-end has pulled apart, birthing DevOps as a new role. Front-end has been pulled apart the most—see “Front of the Front / Back of the Front” for more on that.

We see more and more specialists in fields like performance and accessibility. Now we’re seeing “glue” roles between the roles that we previously pulled apart. This will continue to happen as the haystack of responsibility continues to grow (and it will).

Heck, Dave and I joked the other day there might be entire jobs just focused on dealing with images. I feel fortunate that I’ve largely always worked on small teams with very talented people that very often see across and reach across silos.

To Shared LinkPermalink on CSS-Tricks


The post The Gap (Design Engineering) appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

How To Speed Up Your Bootstrap Development Process

November 17th, 2021 No comments

Currently, Bootstrap is among the most popular frameworks in the developer community. One of the most straightforward solutions for front-end development methods available, Bootstrap allows users to access convenient CSS and HTML components for forms, typography, sliders, navigation, and everything else you might need.

Bootstrap is naturally a pretty fast development solution, as it allows you to access everything you need to create your app in a straightforward environment. You can access premade classes, kits, and themes right out of the box and speed up your development without compromising on performance.

Still, this doesn’t mean there aren’t plenty of ways to enhance the speed of your Bootstrap strategy from time to time. So today, we’re going to look at some of the things you can do to speed up the development of your Bootstrap app.

Make The Most of the Tools Available

Let’s start with the basics: One of the things that makes Bootstrap so effective as a development tool is the ability to access specific tools and services to make building more efficient. The more you leverage these features, the better you’ll be at designing amazing apps quickly. 

For instance, a Task Runner is a fantastic addition to a Bootstrap development strategy. With these tools, you can automate tasks like compiling code or moving code from Typescript to JavaScript. In addition, many developers use these tools when they configure a job that runs every time a specific file is modified, so they don’t have to manually recompile all the time.

The most popular Task Runners available right now are Grunt JS and Gulp JS. Gulp is based on Node.jS, while Grunt works in line with its templating environment. 

Other helpful tools you can check out to accelerate your development process include Sass or Syntactically Awesome Style Sheets – a pre-processor scripting language compiled into CSS so that you can create better stylesheets with minimal effort. In addition, the Sass technology reduces the need for repetition by extending CSS through various methods like inline imports, variable, and nested maps. This means you can implement changes a lot quicker and take more risks in your designs.

Tools like BrowserSync JS will synchronize your browser testing process by performing as a middle man between your browser and server. Using this tool, you shouldn’t have to hit the refresh button on the browser over and over when editing your code to see updates.

Get Comfortable with Scaffolding and Kits

Bootstrap’s front-end framework relies heavily on the grid system within the technology, packed with features to help developers structure a responsive layout. Because of this grid system, it’s easier to scaffold responsive designs before you do any coding. This way, you get ahead of the coding process and better insight into where content should go. 

Bootstrap’s grid system is pretty flexible so that you can define a set of rows divided according to each of the sections in your site or app. The best part is that each column can adjust to suit the template perfectly. 

You can speed up your development process even more by simply accessing existing themes and UI kits from the Bootstrap ecosystem. 

Bootstrap kits are UI kits consisting of a collection of flexible, attractive, and easy-to-use Bootstrap-based components and assets. You can easily plug your solution into your website and customize it based on your required design output. UI components might include things like input forms, widgets, navigation menus, and testimonials. A few options include:

  • Pixel: A free Bootstrap 5 UI kit with over 80 coded UI components, example pages, and more to help you design and build a website that makes sense for your projects. 
  • Fabrx: A comprehensive Bootstrap 5 kit with access to more than 500 responsive components, 250+ wireframes, and a host of ready-made templates. This comes seamlessly coded with CSS and HTML.
  • Material Design: One of the most popular open-source UI kits based on Bootstrap 5, this solution makes it easy to create material design-based components with CSS, JS, and HTML. There are more than 700 UI components already available within the kit. 

Experiment with Bootstrap Themes

Like Bootstrap UI kits, Bootstrap themes are a ready-to-use bundle of JavaScript, HTML, and CSS code complete with UI components, style components, and page layouts. Usually, these themes are designed for a specific kind of app or website. However, everything is generally created for you, for the most part, so that you can modify elements with your requirements later. 

While Bootstrap UI kits give you multiple pieces of coding and technology you can use in your development and how you like, Bootstrap themes are intended to be plug-and-play solutions. You modify a few components and resources, and you’re ready to publish. 

Bootstrap has its own selection of themes available, though most are available for a premium cost, so it’s worth checking out what you get in advance. One good option is the Admin and Dashboard template designed for creating applications for tracking things like analytics and website information. 

The theme here comes with access to all of your crucial bootstrap components, as well as Brite charts, Apex charts, multiple widgets, and icons. A few alternatives to try include:

Use a Bootstrap Builder

Most developers prefer to code their application or website entirely from scratch with Bootstrap – mainly since it’s easy to do. However, there’s also a faster alternative route you can consider too. For instance, using a Bootstrap builder or studio will turn the design process from a hard-code configuration into a more visual and straightforward process. 

Page builders come in many shapes and sizes, designed for both the web and desktop. Popular options like the Bootstrap studio come with drag-and-drop functionality for grid-based content, component creation, and access to quick-add components

Another bonus of using a builder is you can usually expect to have the latest version of Bootstrap available, so you don’t have to update constantly. For example, some of the newest page builders offering access to Bootstrap 5 include:

  • Start-up: A simple bootstrap-based builder, Start-up allows designers and developers to create websites, applications, and landing pages with drag-and-drop functionality. The solution is compatible with all Retina devices and has easy exporting. 
  • Boostrap Build: This is a simple and effective bootstrap application for prototyping and designing all kinds of Bootstrap themes and templates. There are tons of theming capabilities built-in, as well as live preview, color picker, variable search, and size adjuster. 
  • Mobirise: A free and straightforward bootstrap builder, this solution focuses on building various Bootstrap websites. 

Keep Learning

Bootstrap, like many development and design tools today, is constantly evolving. As new versions and components continue to emerge, it’s essential to be confident with the options you have for your website, application, or whatever else you might be making. 

It is exhausting to continuously check out the latest tutorials and posts on the official Bootstrap website; it is much easier to get things done when you know how everything works. The good news is that many of the courses and guidelines available on the web today are free to use. For example, you can get a crash course for beginners on Bootstrap 5 or find a collection of some of the most popular crash courses here.

It’s also worth keeping an eye on the latest news released by the Bootstrap team, so you can get an idea of any new features or functionality you might need to learn as you’re working on your builds. If you’re using the tools we mentioned above, like Sass, make sure you check out the latest updates for those, too – many of the tools available for Bootstrap will get updates too. 

If you’re feeling really in the dark about your new Bootstrap features, you can check out sites like Udemy, which offer step-by-step guides for beginners.  Though the entire course does have a fee attached to it, you’ll learn how to build various projects within Bootstrap, which could make you more efficient at development later. 

As you’re learning how to master Bootstrap development, try not to pile too much on your plate at once. If you decide to work with the precompiled download package for Bootstrap, it’s worth accessing only the specific aspects of the library you need at any given time. 

Start by using simple tools like bootstrap-reboot.min.css for a simple CSS reset for your project, or access the easy-to-use grid system at bootstrap-grid.min.css. You don’t necessarily need to access and learn all the frameworks at once.

Remember the Basics

Finally, all aspects of Bootstrap development get a lot easier when you start thinking about becoming a better coder. Apart from the above points, optimizing a website in any landscape still means incorporating the right front-end performance techniques you would access for any website. 

Although focusing on getting the UX right with your bootstrap build might add more time to your development process initially, it also means you’re less likely to have to come back to your website and make changes in the future. This should mean that you can spend less time developing your project overall and more time optimizing the experience.

For instance, you should still:

  • Use lean JavaScript and CSS: Remember, every character in your code will contribute to the final weight of your webpage. Clean and concise JS and CSS can be difficult to master, but it’s something you need to strive for in most of your projects. Good CSS practices will usually involve getting rid of unused selectors where possible and duplicate code, overly nested rules, and disorganized content. Style guides can often be helpful here. You can also access features like JS Lint and CSS lint to clean up your code too. 
  • Minify your JS and CSS code: An essential step in optimizing your website is limiting the number of HTTP requests a website makes to render the content. Each trip to the server and back takes more time, harming user experience. Minifying the document will help you to keep file sizes small and reduce HTTP requests. 
  • Reduce image sizes: The weightiest part of your website is usually the image files. However, video and audio files will also play their role. Make sure you’re always using the right image or file type for each job and squeeze extra bytes from your images wherever you can with compression too. 

While it’s great to get a development project done quickly, don’t mistake rushing through and forgetting essential elements that influence the impact of your project. You still want your project to work perfectly – even if you’re developing it quickly. 

Speeding Up Development with Bootstrap

Bootstrap is a fantastic, fast-paced solution for developing all kinds of incredible websites, applications, and projects. However, learning how to use all the features and components of your Bootstrap environment correctly can ensure you’re more likely to speed up the development process. The tips above will allow you to discover all the benefits of the Bootstrap front-end framework. 

Remember, try to find the right balance between speeding up your development process, and maintaining a high level of quality. Time saved on initial development won’t do much good if you have to come back and make additional fixes later. So focus on getting things right the first time, but use tools and templates to help you whenever you can. The more you work on Bootstrap, the better your projects will become. 

Source

The post How To Speed Up Your Bootstrap Development Process first appeared on Webdesigner Depot.

Categories: Designing, Others Tags:

A Clever Sticky Footer Technique

November 17th, 2021 No comments

Upon hearing “sticky footer” these days, I would think most people imagine a position: sticky situation where a footer element appears fixed on the screen while in the scrolling context of some parent element.

That’s not quite what I’m talking about here. “Sticky footers” were a UI concept before position: sticky existed and they mean something slightly different. The idea is that they stick to the bottom of the screen, even when the content of the page isn’t enough to push them there. But if there is enough content, they are happily pushed down.

We covered five ways to do this in years past, which included techniques that are somewhat modern, including calc(), flexbox, and CSS Grid.

Enter a sixth challenger! Reader Sílvio Rosa wrote in with this:

CodePen Embed Fallback

(Probably easiest to check out on a medium-sized desktop screen, which is kinda where sticky footers matter the most anyway.)

It’s pretty much just this:

html, body { height: 100%;}

body > footer {
  position: sticky;
  top: 100vh;
}

What I like about it is that it doesn’t require any special extra wrapper for non-footer content.

It’s also a little brain-bending. When I see top: 100vh; I think well that won’t work because it will push the footer outside the viewable area. But that’s the clever bit. It will do that no matter how big the footer is (no magic numbers), and then the sticky positioning will “suck it back up” to stick along the bottom edge. But it will never overlap content, so it’s happy to be pushed down below content, which is a core tenant of the sticky footer pattern.


The post A Clever Sticky Footer Technique appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Line length revisited: following the research

November 16th, 2021 No comments

Mary Dyson produces nitty gritty research on the long-accepted notion that shorter line lengths are more legible than longer ones. The study finds that shorter lines do not necessarily lead to faster reading. If you’re looking for a definitive answer to use in your next design review debate, though, no dice. The big finding is that long lines don’t slow things down as much as previously thought, not that they’re better or worse.

But there’s so much more meat in here that I found much more interesting, mostly because I’m largely ignorant on the topic and gained a dollop of context on writing, legibility, and behavior.

Things like…

There’s a term for transitioning between lines of text

It’s return sweeps. You know, like your eye hits the Return key at the end of the line and sweeps to the start of the next line. Then, there are undershoots. The idea is that eyes may not sweep to the exact start of the next line, instead stopping a bit short.

Those little rapid eye movements between words and phrases? Those are called saccades. I had to look that up.

The impact of undershoots is what’s being challenged

The previous research we’ve relied on for years comes from 1940(!), a time when we obviously were more concerned with paper pages than bright digital displays. Longer lines, it said, increased the likelihood that eyes undershoot during a return sweep, and undershooting results in a regression that results in a 130ms to 250ms delay where the brain needs to get its bearings. The report refers to that as undersweep-fixation.

We can still process words during undersweep-fixation

This report cites a 2019 study that tried to correct undershoots by bolding the first word at the start of each new line, sort of like an anchor that naturally draws the eye closer to the left margin.

The 2019 study did find that the bolded words did decrease undershot return sweeps But despite that, reading speed did not improve. That’s the impetus for challenging the long-held assumption that shorter is better.

Mary explains further:

In seeking to reconcile why longer line lengths may not slow down reading on screen but do so when reading print, I outlined some differences, e.g. visual angle, time spent scrolling. But although physical differences between reading from screen and reading print still exist, we now have direct evidence to explain why longer lines were read at least as fast as shorter lines. Readers can process words during the brief fixation when undershooting the start of the new line. This saves time in subsequent processing. Now we might also acknowledge that there is greater consistency between the range of optimal line lengths for print and screen.

Where does this leave us today?

Well, nowhere closer to a clear answer we can use in our day-to-day work. But it’s good to dust off our collection of design and copywriting best practices and know that line length is less of a constraint than perhaps it has been.

Again, none of this tells us whether long or short lines are better. Mary ends her report by saying she cannot definitely recommend using longer lines of text because there are clear because there are still some factors at play, including:

  • Shorter lines are more effective for people with dyslexia.
  • More questions about return sweeps and undershooting need to be answered.
  • Several other studies indicate that users prefer shorter lines and judge longer lines as more difficult to read.

To Shared LinkPermalink on CSS-Tricks


The post Line length revisited: following the research appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Generate a Pull Request of Static Content With a Simple HTML Form

November 16th, 2021 No comments
The Resources page of the CSS-Tricks Serverless site. The site is primarily purple in varying shades with accents of orange. The page shows a couple of serverless resources in the main area and a list of categories in the right sidebar.

Jamstack has been in the website world for years. Static Site Generators (SSGs) — which often have content that lives right within a GitHub repo itself — are a big part of that story. That opens up the idea of having contributors that can open pull requests to add, change, or edit content. Very useful!

Examples of this are like:

Why built with a static site approach?

When we need to build content-based sites like this, it’s common to think about what database to use. Keeping content in a database is a time-honored good idea. But it’s not the only approach! SSGs can be a great alternative because…

  • They are cheap and easy to deploy. SSGs are usually free, making them great for an MVP or a proof of concept.
  • They have great security. There is nothing to hack through the browser, as all the site contains is often just static files.
  • You’re ready to scale. The host you’re already on can handle it.

There is another advantage for us when it comes to a content site. The content of the site itself can be written in static files right in the repo. That means that adding and updating content can happen right from pull requests on GitHub, for example. Even for the non-technically inclined, it opens the door to things like Netlify CMS and the concept of open authoring, allowing for community contributions.

But let’s go the super lo-fi route and embrace the idea of pull requests for content, using nothing more than basic HTML.

The challenge

How people contribute adding or updating a resource isn’t always perfectly straightforward. People need to understand how to fork your repository, how to and where to add their content, content formatting standards, required fields, and all sorts of stuff. They might even need to “spin up” the site themselves locally to ensure the content looks right.

People who seriously want to help our site sometimes will back off because the process of contributing is a technological hurdle and learning curve — which is sad.

You know what anybody can do? Use a

Just like a normal website, the easy way for people to submit a content is to fill out a form and submit it with the content they want.

What if we can make a way for users to contribute content to our sites by way of nothing more than an HTML designed to take exactly the content we need? But instead of the form posting to a database, it goes the route of a pull request against our static site generator? There is a trick!

The trick: Create a GitHub pull request with query parameters

Here’s a little known trick: We can pre-fill a pull request against our repository by adding query parameter to a special GitHub URL. This comes right from the GitHub docs themselves.

Let’s reverse engineer this.

If we know we can pre-fill a link, then we need to generate the link. We’re trying to make this easy remember. To generate this dynamic data-filled link, we’ll use a touch of JavaScript.

So now, how do we generate this link after the user submits the form?

Demo time!

Let’s take the Serverless site from CSS-Tricks as an example. Currently, the only way to add a new resource is by forking the repo on GitHub and adding a new Markdown file. But let’s see how we can do it with a form instead of jumping through those hoops.

The Serverless site itself has many categories (e.g. for forms) we can contribute to. For the sake of simplicity, let’s focus on the “Resources” category. People can add articles about things related to Serverless or Jamstack from there.

All of the resource files are in this folder in the repo.

Showing the main page of the CSS-Tricks Serverless repo in GitHub, displaying all the files.

Just picking a random file from there to explore the structure…

---
title: "How to deploy a custom domain with the Amplify Console"
url: "https://read.acloud.guru/how-to-deploy-a-custom-domain-with-the-amplify-console-a884b6a3c0fc"
author: "Nader Dabit"
tags: ["hosting", "amplify"]
---

In this tutorial, we’ll learn how to add a custom domain to an Amplify Console deployment in just a couple of minutes.

Looking over that content, our form must have these columns:

  • Title
  • URL
  • Author
  • Tags
  • Snippet or description of the link.

So let’s build an HTML form for all those fields:

<div class="columns container my-2">
  <div class="column is-half is-offset-one-quarter">
  <h1 class="title">Contribute to Serverless Resources</h1>

  <div class="field">
    <label class="label" for="title">Title</label>
    <div class="control">
      <input id="title" name="title" class="input" type="text">
    </div>
  </div>
  
  <div class="field">
    <label class="label" for="url">URL</label>
    <div class="control">
      <input id="url" name="url" class="input" type="url">
    </div>
  </div>
    
  <div class="field">
    <label class="label" for="author">Author</label>
    <div class="control">
      <input id="author" class="input" type="text" name="author">
    </div>
  </div>
  
  <div class="field">
    <label class="label" for="tags">Tags (comma separated)</label>
    <div class="control">
      <input id="tags" class="input" type="text" name="tags">
    </div>
  </div>
    
  <div class="field">
    <label class="label" for="description">Description</label>
    <div class="control">
      <textarea id="description" class="textarea" name="description"></textarea>
    </div>
  </div>
  
   <!-- Prepare the JavaScript function for later -->
  <div class="control">
    <button onclick="validateSubmission();" class="button is-link is-fullwidth">Submit</button>
  </div>
    
  </div>
</div>

I’m using Bulma for styling, so the class names in use here are from that.

Now we write a JavaScript function that transforms a user’s input into a friendly URL that we can combine as GitHub query parameters on our pull request. Here is the step by step:

  • Get the user’s input about the content they want to add
  • Generate a string from all that content
  • Encode the string to format it in a way that humans can read
  • Attach the encoded string to a complete URL pointing to GitHub’s page for new pull requests

Here is the Pen:

CodePen Embed Fallback

After pressing the Submit button, the user is taken right to GitHub with an open pull request for this new file in the right location.

GitHub pull request screen showing a new file with content.

Quick caveat: Users still need a GitHub account to contribute. But this is still much easier than having to know how to fork a repo and create a pull request from that fork.

Other benefits of this approach

Well, for one, this is a form that lives on our site. We can style it however we want. That sort of control is always nice to have.

Secondly, since we’ve already written the JavaScript, we can use the same basic idea to talk with other services or APIs in order to process the input first. For example, if we need information from a website (like the title, meta description, or favicon) we can fetch this information just by providing the URL.

Taking things further

Let’s have a play with that second point above. We could simply pre-fill our form by fetching information from the URL provided for the user rather than having them have to enter it by hand.

With that in mind, let’s now only ask the user for two inputs (rather than four) — just the URL and tags.

CodePen Embed Fallback

How does this work? We can fetch meta information from a website with JavaScript just by having the URL. There are many APIs that fetch information from a website, but you might the one that I built for this project. Try hitting any URL like this:

https://metadata-api.vercel.app/api?url=https://css-tricks.com

The demo above uses that as an API to pre-fill data based on the URL the user provides. Easier for the user!

Wrapping up

You could think of this as a very minimal CMS for any kind of Static Site Generator. All you need to do is customize the form and update the pre-filled query parameters to match the data formats you need.

How will you use this sort of thing? The four sites we saw at the very beginning are good examples. But there are so many other times where might need to do something with a user submission, and this might be a low-lift way to do it.


The post Generate a Pull Request of Static Content With a Simple HTML Form appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Jamstack TV

November 16th, 2021 No comments

That’s the name of Netlify’s YouTube Channel. Love that. I linked up Rich’s talk the other day, which was a part of this past JamstackConf, but now all the talks are up on there. Rich got to talk about Svelte, but there are talks on Astro, RedwoodJS, Eleventy, Vue… all the cool kids really.

I’m subscribed, of course. I’ve been on a real YouTube bender, spending most of my non-active screen time there. I’d say half of what I watch is tech content (like JamstackTV) and the rest is watching people play video games or puzzles and watching people talk about where they live or have traveled (preferably with an AMSR-friendly voice). I find if you subscribe to enough stuff you actually like, the algorithm really kicks in and finds you more stuff you’re very likely to enjoy. We’ve got a fairly active channel ourselves!


The post Jamstack TV appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Color Alpha Anywhere

November 16th, 2021 No comments

In my “Different Degrees of Custom Property Usage” article, I noted a situation about colors and CSS custom properties where I went “too far” with breaking up HSL color values. Breaking every single color into its H, S, and L parts is may be a step too far.

But you probably do want to split it up like this:

html {
  --color-1-hsl: 200deg 15% 73%;
  --color-1: hsl(var(--color-1-hsl));
}

So, two custom properties per color in your color system. Why? Because now you’ve got a really easy way to use it and you’ve got a way to apply alpha to the color if you want.

.card {
  background: var(--color-1);
}
.card-with-alpha {
  background: hsl(var(--color-1) / 0.5);
}

There’s not really any other way to take an existing color in CSS and apply alpha transparency to it. Well, I say that, but actually

/* Future CSS! (works in Safari TP right now) */
.card-with-alpha {
  background: hsl(from var(--color-1) h s l / 0.5);
}

That’s neat, but I’m not entirely sure when we’ll be able to rely on that in production.

You know what else we can’t use for anything super important in production? Houdini paint worklets. No Firefox or Safari yet on those.

A bummer, because Dave almost had this thing cracked! The insight here is that Houdini paint worklets basically return an image that you paint with APIs. You can paint a rectangle in Canvas with any color format, then set the globalAlpha, return that as an image, and so that basically unlocks alpha on any color format! It works (in Chrome):

CodePen Embed Fallback

Dave chucked the code on GitHub and blogged it. Of course, it made a good video as well:

Like and subscribe.

But if you need a system like this on production, just do the custom properties technique I listed first.

A previous version of this post was tweetbombed, but I’m blogging it here because real bloggers blog.


The post Color Alpha Anywhere appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Defining and Applying UI Themes Using the Mimcss CSS-in-JS Library

November 15th, 2021 No comments

Theming UI refers to the ability to perform a change in visual styles in a consistent manner that defines the “look and feel” of a site. Swapping color palettes, à la dark mode or some other means, is a good example. From the user’s perspective, theming involves changing visual styles, whether it’s with UI for selecting a theme style, or the site automatically respecting the user’s color theme preference at the OS-level. From the developer’s perspective, tools used for theming should be easy-to-use and define themes at develop-time, before applying them at runtime.

This article describes how to approach theming with Mimcss, a CSS-in-JS library, using class inheritance—a method that should be intuitive for most developer as theming is usually about overriding CSS property values, and inheritance is perfect for those overrides.

Full discloser: I am the author of Mimcss. If you consider this a shameless promotion, you are not far from the truth. Nevertheless, I really do believe that the theming technique we’re covering in this article is unique, intuitive and worth exploring.

General theming considerations

Styling in web UI is implemented by having HTML elements reference CSS entities (classes, IDs, etc.). Since both HTML and CSS are dynamic in nature, changing visual representation can be achieved by one of the following methods:

  1. Changing the CSS selector of an HTML element, such as a different class name or ID.
  2. Changing actual CSS styling for that HTML element while preserving the selector.

Depending on the context, one method can be more efficient than another. Themes are usually defined by a limited number of style entities. Yes, themes are more than just a collection of colors and fonts—they can define paddings, margins, layouts, animations and so on . However, it seems that the number of CSS entities defined by a theme might be less than a number of HTML elements referencing these entities, especially if we are talking about heavy widgets such as tables, trees or code editors. With this assumption, when we want to change a theme, we’d rather replace style definitions than go over the HTML elements and (most likely) change the values of their class attributes.

Theming in plain CSS

In regular CSS, one way theming is supported is by using alternate stylesheets. This allows developers to link up multiple CSS files in the HTML :

<link href="default.css" rel="stylesheet" type="text/css" title="Default Style">
<link href="fancy.css" rel="alternate stylesheet" type="text/css" title="Fancy">
<link href="basic.css" rel="alternate stylesheet" type="text/css" title="Basic">

Only one of the above stylesheets can be active at any given time and browsers are expected to provide the UI through which the user chooses a theme name taken from the values of the element’s title attribute. The CSS rule names (i.e. class names) within the alternative stylesheets are expected to be identical, like:

/* default.css */
.element {
  color: #fff;
}

/* basic.css */
.element {
  color: #333;
}

This way, when the browser activates a different stylesheet, no HTML changes are required. The browser just recalculates styles (and layout) and repaints the page based on the “winning” values, as determined by The Cascade.

Alternate stylesheets, unfortunately, are not well-supported by mainstream browsers and, in some of them, work only with special extensions. As we will see later, Mimcss builds upon the idea of alternate stylesheets, but leverages it in a pure TypeScript framework.

Theming in CSS-in-JS

There are too many CSS-in-JS libraries out there, and there is no way we can completely cover how theming works in CSS-in-JS in a single post to do it justice. As far as CSS-in-JS libraries that are tightly integrated with React (e.g. Styled Components), theming is implemented on the ThemeProvider component and the Context API, or on the withTheme higher-order component. In both cases, changing a theme leads to re-rendering. As far as CSS-in-JS libraries that are framework-agnostic, theming is achieved via proprietary mechanisms, if theming is even supported at all.

The majority of the CSS-in-JS libraries—both React-specific and framework-agnostic—are focused on “scoping” style rules to components and thus are mostly concerned with creating unique names for CSS entities (e.g. CSS classes). In such environments, changing a theme necessarily means changing the HTML. This goes against the alternative stylesheets approach described above, in which theming is achieved by just changing the styles.

Here is where Mimcss library is different. It tries to combine the best of both theming worlds. On one hand, Mimcss follows the alternate stylesheets approach by defining multiple variants of stylesheets with identically named CSS entities. On the other hand, it offers the object-oriented approach and powerful TypeScript typing system with all the advantages of CSS-in-JS dynamic programming and type safety.

Theming in Mimcss

Mimcss is in that latter group of CSS-in-JS libraries in that it’s framework-agnostic. But it’s also created with the primary objective of allowing everything that native CSS allows in a type-safe manner, while leveraging the full power of the TypeScript’s typing system. In particular, Mimcss uses TypeScript classes to mimic the native CSS stylesheet files. Just as CSS files contain rules, the Mimcss Style Definition classes contain rules.

Classes open up the opportunity to use class inheritance to implement theming. The general idea is that a base class declares CSS rules used by the themes while derived classes provide different style property values for these rules. This is very similar to the native alternative stylesheets approach: activate a different theme class and, without any changes to the HTML code, the styles change.

But first, let’s very briefly touch on how styles are defined in Mimcss.

Mimcss basics

Stylesheets in Mimcss are modeled as Style Definition classes, which define CSS rules as their properties. For example:

import * as css from "mimcss"

class MyStyles extends css.StyleDefinition
{
  significant = this.$class({
    color: "orange",
    fontStyle: "italic"
  })

  critical = this.$id({
    color: "red",
    fontWeight: 700
  })
}

The Mimcss syntax tries to be as close to regular CSS as possible. It is slightly more verbose, of course; after all, it is pure TypeScript that doesn’t require any plug-ins or pre-processing. But it still follows regular CSS patterns: for every rule, there is the rule name (e.g. significant), what type of rule it is (e.g. $class), and the style properties the rule contains.

In addition to CSS classes and IDs, style definition properties can define other CSS rules, e.g. tags, keyframes, custom CSS properties, style rules with arbitrary selectors, media, @font-face, counters, and so on. Mimcss also supports nested rules including those with pseudo classes and pseudo-elements.

After a style definition class is defined, the styles should be activated:

let styles = css.activate(MyStyles);

Activating styles creates an instance of the style definition class and writes the CSS rules to the DOM. In order to use the styles, we reference the instance’s properties in our HTML rendering code:

render()
{
  return <div>
    <p className={styles.significant.name}>
      This is a significant paragraph.
    </p>
    <p id={styles.critical.name}>
      This is a critical paragraph.
    </p>
  </div>
}

We use styles.significant.name as a CSS class name. Note that the styles.significant property is not a string, but an object that has the name property and the CSS class name. The property itself also provides access to the CSS Object Model rule, which allows direct rule manipulation; this, however, is outside of the scope of this article (although Louis Lazaris has a great article on it).

If the styles are no longer needed, they can be deactivated which removes them from the DOM:

css.deactivate(styles);

The CSS class and ID names are uniquely generated by Mimcss. The generation mechanism is different in development and production versions of the library. For example, for the significant CSS class, the name is generated as MyStyles_significant in the development version, and as something like n2 in the production version. The names are generated when the style definition class is activated for the first time and they remain the same no matter how many times the class is activated and deactivated. How the names are generated depends on in what class they were first declared and this becomes very important when we start inheriting style definitions.

Style definition inheritance

Let’s look at a simple example and see what Mimcss does in the presence of inheritance:

class Base extends css.StyleDefinition
{
  pad4 = this.$class({ padding: 4 })
}
class Derived extends Base
{
  pad8 = this.$class({ padding: 8 })
}
let derived = css.activate(Derived);

Nothing surprising happens when we activate the Derived class: the derived variable provides access to both the pad4 and the pad8 CSS classes. Mimcss generates a unique CSS class name for each of these properties. The names of the classes are Base_pad4 and Derived_pad8 in the development version of the library.

Interesting things start happening when the Derived class overrides a property from the base class:

class Base extends css.StyleDefinition
{
  pad = this.$class({ padding: 4 })
}
class Derived extends Base
{
  pad = this.$class({ padding: 8 })
}
let derived = css.activate(Derived);

There is a single name generated for the derived.pad.name variable. The name is Base_pad; however, the style is { padding: 8px }. That is, the name is generated using the name of the base class, while the style is taken from the derived class.

Let’s try another style definition class that derives from the same Base class:

class AnotherDerived extends Base
{
  pad = this.$class({ padding: 16 })
}
let anotherDerived = css.activate(AnotherDerived);

As expected, the anotherDerived.pad.name has the value of Base_pad and the style is { padding: 16px }. Thus, no matter how many different derived classes we may have, they all use the same name for the inherited properties, but different styles are assigned to them. This is the key Mimcss feature that allows us to use style definition inheritance for theming.

Creating themes in Mimcss

The main idea of theming in Mimcss is to have a theme declaration class that declares several CSS rules, and to have multiple implementation classes that are derived from the declaration while overriding these rules by providing actual styles values. When we need CSS class names, as well as other named CSS entities in our code, we can use the properties from the theme declaration class. Then we can activate either this or that implementation class and, voilà, we can completely change the styling of our application with very little code.

Let’s consider a very simple example that nicely demonstrates the overall approach to theming in Mimcss.: a theme simply defines the shape and style of an element’s border.

First, we need to create the theme declaration class. Theme declarations are classes that derive from the ThemeDefinition class, which itself derives from the StyleDefinition class (there is an explanation why we need the ThemeDefinition class and why themes should not derive directly from the StyleDefinition class, but this is a topic for another day).

class BorderTheme extends css.ThemeDefinition
{
  borderShape = this.$class()
}

The BorderTheme class defines a single CSS class, borderShape. Note that we haven’t specified any styles for it. We are using this class only to define the borderShape property type, and let Mimcss create a unique name for it. In a sense, it is a lot like a method declaration in an interface—it declares its signature, which should be implemented by the derived classes.

Now let’s define two actual themes—using SquareBorderTheme and RoundBorderTheme classes—that derive from the BorderTheme class and override the borderShape property by specifying different style parameters.

class SquareBorderTheme extends BorderTheme
{
  borderShape = this.$class({
    border: ["thin", "solid", "green"],
    borderInlineStartWidth: "thick"
  })
}

class RoundBorderTheme extends BorderTheme
{
  borderShape = this.$class({
    border: ["medium", "solid", "blue"],
    borderRadius: 8 // Mimcss will convert 8 to 8px
  })
}

TypeScript ensures that the derived classes can only override a property using the same type that was declared in the base class which, in our case, is an internal Mimcss type used for defining CSS classes. That means that developers cannot use the borderShape property to mistakenly declare a different CSS rule because it leads to a compilation error.

We can now activate one of the themes as the default theme:

let theme: BorderTheme = css.activate(SquareBorderTheme);

When Mimcss first activates a style definition class, it generates unique names for all of CSS entities defined in the class. As we have seen before, the name generated for the borderShape property is generated once and will be reused when other classes deriving from the BorderTheme class are activated.

The activate function returns an instance of the activated class, which we store in the theme variable of type BorderTheme. Having this variable tells the TypeScript compiler that it has access to all the properties from the BorderTheme. This allows us to write the following rendering code for a fictional component:

render()
{
  return <div>
    <input type="text" className={theme.borderShape.name} />
  </div>
}

All that is left to write is the code that allows the user to choose one of the two themes and activate it.

onToggleTheme()
{
  if (theme instanceof SquareBorderTheme)
    theme = css.activate(RoundBorderTheme);
  else
    theme = css.activate(SquareBorderTheme);
}

Note that we didn’t have to deactivate the old theme. One of the features of the ThemeDefinition class (as opposed to the StyleDefintion class) is that for every theme declaration class, it allows only a single theme to be active at the same time. That is, in our case, either RoundBorderTheme or SquareBorderTheme can be active, but never both. Of course, for multiple theme hierarchies, multiple themes can be simultaneously active. That is, if we have another hierarchy with the ColorTheme declaration class and the derived DarkTheme and LightTheme classes, a single ColorTheme-derived class can be co-active with a single BorderTheme-derived class. However, DarkTheme and LightTheme cannot be active at the same time.

Referencing Mimcss themes

In the example we just looked at, we used a theme object directly but themes frequently define elements like colors, sizes, and fonts that can be referenced by other style definitions. This is especially useful for separating the code that defines themes from the code that defines styles for a component that only wants to use the elements defined by the currently active theme.

CSS custom properties are perfect for declaring elements from which styles can be built. So, let’s define two custom properties in our themes: one for the foreground color, and one for the background color. We can also create a simple component and define a separate style definition class for it. Here is how we define the theme declaration class:

class ColorTheme extends css.ThemeDefinition
{
  bgColor = this.$var( "color")
  frColor = this.$var( "color")
}

The $var method defines a CSS custom property. The first parameter specifies the name of the CSS style property, which determines acceptable property values. Note that we don’t specify the actual values here; in the declaration class, we only want Mimcss to create unique names for the custom CSS properties (e.g. --n13) while the values are specified in the theme implementation classes, which we do next.

class LightTheme extends ColorTheme
{
  bgColor = this.$var( "color", "white")
  frColor = this.$var( "color", "black")
}

class DarkTheme extendsBorderTheme
{
  bgColor = this.$var( "color", "black")
  frColor = this.$var( "color", "white")
}

Thanks to the Mimcss (and of course TypeScript’s) typing system, developers cannot mistakenly reuse, say, the bgColor property with a different type; nor they can specify values that are not acceptable for a color type. Doing so would immediately produce a compilation error, which may save developers quite a few cycles (one of the declared goals of Mimcss).

Let’s define styles for our component by referencing the theme’s custom CSS properties:

class MyStyles extends css.StyleDefinition
{
  theme = this.$use(ColorTheme)

  container = this.$class({
    color: this.theme.fgColor,
    backgroundColor: this.theme.bgColor,
  })
}

The MyStyles style definition class references the ColorTheme class by calling the Mimcss $use method. This returns an instance of the ColorTheme class through which all its properties can be accessed and used to assign values to CSS properties.

We don’t need to write the var() function invocation because it’s already done by Mimcss when the $var property is referenced. In effect, the CSS class for the container property creates the following CSS rule (with uniquely generated names, of course):

.container {
  color: var(--fgColor);
  backgroundColor: var(--bgColor);
}

Now we can define our component (in pseudo-React style):

class MyComponent extends Component
{
  private styles = css.activate(MyStyles);

  componentWillUnmount()
  {
    css.deactivate(this.styles);
  }

  render()
  {
    return <div className={this.styles.container.name}>
      This area will change colors depending on a selected theme.
    </div>
  }
}

Note one important thing in the above code: our component is completely decoupled from the classes that implement actual themes. The only class our component needs to know about is the theme declaration class ColorTheme. This opens a door to easily “externalize” creation of themes—they can be created by third-party vendors and delivered as regular JavaScript packages. As long as they derive from the ColorTheme class, they can be activated and our component reflects their values.

Imagine creating a theme declaration class for, say, Material Design styles along with multiple theme classes that derive from this class. The only caveat is that since we are using an existing system, the actual names of the CSS properties cannot be generated by Mimcss—they must be the exact names that the Material Design system uses (e.g. --mdc-theme--primary). Thankfully, for all named CSS entities, Mimcss provides a way to override its internal name generation mechanism and use an explicitly provided name. Here is how it can be done with Material Design CSS properties:

class MaterialDesignThemeBase extends css.ThemeDefinition
{
  primary = this.$var( "color", undefined, "mdc-theme--primary")
  onPrimary = this.$var( "color", undefined, "mdc-theme--on-primary")
  // ...
}

The third parameter in the $var call is the name, which is given to the CSS custom property. The second parameter is set to undefined meaning we aren’t providing any value for the property since this is a theme declaration, and not a concrete theme implementation.

The implementation classes do not need to worry about specifying the correct names because all name assignments are based on the theme declaration class:

class MyMaterialDesignTheme extends MaterialDesignThemeBase
{
  primary = this.$var( "color", "lightslategray")
  onPrimary = this.$var( "color", "navy")
  // ...
}

Multiple themes on one page

As mentioned earlier, only a single theme implementation can be active from among the themes derived from the same theme declaration class. The reason is that different theme implementations define different values for the CSS rules with the same names. Thus, if multiple theme implementations were allowed to be active at the same time, we would have multiple definitions of identically-named CSS rules. This is, of course, a recipe for disaster.

Normally, having a single theme active at a time is not a problem at all—it is likely what we want in most cases. Themes usually define the overall look and feel of the entire page and there is no need to have different page sections to use different themes. What if, however, we are in that rare situation where we do need to apply different themes to different parts of our page? For example, what if before a user chooses a light or dark theme, we want to allow them to compare the two modes side-by-side?

The solution is based on the fact that custom CSS properties can be redefined under CSS rules. Since theme definition classes usually contain a lot of custom CSS properties, Mimcss provides an easy way to use their values from different themes under different CSS rules.

Let’s consider an example where we need to display two elements using two different themes on the same page. The idea is to create a style definition class for our component so that we could write the following rendering code:

public render()
{
  return <div>
    <div className={this.styles.top.name}>
      This should be black text on white background
    </div>
    <div className={this.styles.bottom.name}>
      This should be white text on black background
    </div>
  </div>
}

We need to define the CSS top and bottom classes so that we redefine the custom properties under each of them taking values from different themes. We essentially want to have the following CSS:

.block {
  backgroundColor: var(--bgColor);
  color: var(--fgColor);
}

.block.top {
  --bgColor: while;
  --fgColor: black;
}

.block.bottom {
  --bgColor: black;
  --fgColor: white;
}

We use the block class for optimization purposes and to showcase how Mimcss handles inheriting CSS styles, but it is optional.

Here is how this is done in Mimcss:

class MyStyles extends css.StyleDefinition
{
  theme = this.$use(ColorTheme)

  block = this.$class({
    backgroundColor: this.theme.bgColor,
    color: this.theme.fgColor
  })

  top = this.$class({
    "++": this.block,
    "--": [LightTheme],
  })

  bottom = this.$class({
    "++": this.block,
    "--": [DarkTheme],
  })
}

Just as we did previously, we reference our ColorTheme declaration class. Then we define a helper block CSS class, which sets the foreground and background colors using the custom CSS properties from the theme. Then we define the top and bottom classes and use the "++" property to indicate that they inherit from the block class. Mimcss supports several methods of style inheritance; the "++" property simply appends the name of the referenced class to our class name. That is, the value returned by the styles.top.name is "top block" where we’re combining the two CSS classes (the actual names are randomly generated, so it would be something like "n153 n459").

Then we use the "--" property to set values of the custom CSS variables. Mimcss supports several methods of redefining custom CSS properties in a ruleset; in our case, we just reference a corresponding theme definition class. This causes Mimcss to redefine all custom CSS properties found in the theme class with their corresponding values.

What do you think?

Theming in Mimcss is intentionally based on style definition inheritance. We looked at exactly how this works, where we get the best of both theming worlds: the ability to use alternate stylesheets alongside the ability to swap out CSS property values using an object-oriented approach.

At runtime, Mimcss applies a theme without changing the HTML whatsoever. At build-time, Mimcss leverages the well-tried and easy-to-use class inheritance technique. Please check out the Mimcss documentation for a much deeper dive on the things we covered here. You can also visit the Mimcss Playground where you can explore a number of examples and easily try your own code.

And, of course, tell me what you think of this approach! This has been my go-to solution for theming and I’d like to continue making it stronger based on feedback from developers like yourself.


The post Defining and Applying UI Themes Using the Mimcss CSS-in-JS Library appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags: