Archiwum kategorii: CSS

Is Having an RSS Feed Just Giving Content Away for Free?

Post pobrano z: Is Having an RSS Feed Just Giving Content Away for Free?

I mean, kinda.

I was just asked this question the other day so I’m answering here because blogging is cool.

The point of an RSS feed is for people to read your content elsewhere (hence the last part of the acronym, Syndication, as in, broadcasting elsewhere). Probably an RSS reader. But RSS is XML, so in a sense, it’s a limited API to your content as well, which people can use to do other programmatic things (e.g. show a list of recent posts on some other site).

If you hate the idea of people seeing your work outside of your website, then don’t have an RSS feed. It doesn’t prevent your site from being scraped (nothing really does), but it isn’t inviting people to your content the way RSS does.

But…

Don’t you want people to read your stuff? Having an RSS feed is saying, „I’m happy to meet you where you are. If you like reading stuff over there, then great, read it over there. I just like it when you read my stuff.”

It’s hard enough to get people to care about your work anyway. Being extra protective over it isn’t going to help that.

Who’s comic book are you more likely to buy? The webcomic you read and laugh at every day because they make it so easy and free to read? Or the comic that you can’t see because you have to pay for to get a peek and have to roll the dice on whether you’re going to like it or not?

What consultant are you more likely to hire? The one that shares a ton of knowledge about their skills and has firmly established themselves as a publicly verifiable expert? Or a consultant with a homepage that’s just a pricing sheet and phone number?

What blog are you more likely to trust a recommendation from? One that you subscribe to on purpose because you like their content and writers? Or some site you randomly landed on?

What web do you want to exist? One with fun interoperable possibilities? Or walled gardens?

The post Is Having an RSS Feed Just Giving Content Away for Free? appeared first on CSS-Tricks.

Guillermo’s 2019 in Review

Post pobrano z: Guillermo’s 2019 in Review

Of all the tech-focused year-in-review posts I read, Guillermo Rauch’s is my favorite. There is a lot in there, jumping from topics like modern architectures, high-fiving specific apps, and philosophical movements.

I’ll pick one quote about the rise of „deploy previews”:

A salient feature is the transition we are seeing away from code review into deployment preview.

Code review is undeniably important (specially speedy code review), but nothing beats teams collaborating by sharing URLs to the actual sites that are being worked on and experiencing them directly.

Having a URL for every single push to every single branch (or at least for every single Pull Request¹ is huge. This isn’t just „staging.” It’s like Super Staging, and Jamstack makes it possible. Both Netlify and ZEIT do it automatically.

Not only does it help the author (and her co-workers) check out the changes on a production replica, it helps out a pile of automation tools that can run against these URLs, making for way more stable development workflows.

  1. GitHub calls them „Pull Requests” but I use GitLab just as much which calls them „Merge Requests,” so I never know which to write. „Pull/Merge Requests” is awkward at best and confusing at worst. I don’t use Bitbucket much, but they are Pull Requests there. I guess I’ll let that tip the scales and just say Pull Request from now on.

Direct Link to Article — Permalink

The post Guillermo’s 2019 in Review appeared first on CSS-Tricks.

Custom Styling Form Inputs With Modern CSS Features

Post pobrano z: Custom Styling Form Inputs With Modern CSS Features

It’s entirely possible to build custom checkboxes, radio buttons, and toggle switches these days, while staying semantic and accessible. We don’t even need a single line of JavaScript or extra HTML elements! It’s actually gotten easier lately than it has been in the past. Let’s take a look.

Here’s where we’ll end up:

CodePen Embed Fallback

Things sure have gotten easier than they were!

The reason is that we can finally style the ::before and ::after pseudo-elements on the <input> tag itself. This means we can keep and style an <input> and won’t need any extra elements. Before, we had to rely on the likes of an extra <div> or <span>, to pull off a custom design.

Let’s look at the HTML

Nothing special here. We can style our inputs with just this HTML:

<!-- Checkbox -->
<input type="checkbox">

<!-- Radio -->
<input type="radio">

<!-- Switch -->
<input type="checkbox" class="switch">

That’s it for the HTML part, but of course it’s recommended to have name and id attributes, plus a matching <label> element:

<!-- Checkbox -->
<input type="checkbox" name="c1" id="c1">
<label for="c1">Checkbox</label>

<!-- Radio -->
<input type="radio" name="r1" id="r1">
<label for="r1">Radio</label>

<!-- Switch -->
<input type="checkbox" class="switch" name="s1" id="s1">
<label for="s1">Switch</label>

Getting into the styling 

First of all, we check for the support of appearance: none;, including it’s prefixed companions. The appearance property is key because it is designed to remove a browser’s default styling from an element. If the property isn’t supported, the styles won’t apply and default input styles will be shown. That’s perfectly fine and a good example of progressive enhancement at play.

@supports(-webkit-appearance: none) or (-moz-appearance: none) {
  input[type='checkbox'],
  input[type='radio'] {
    -webkit-appearance: none;
    -moz-appearance: none;
  }
}

As it stands today, appearance  is a working draft, but here’s what support looks like:

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

Desktop

Chrome Firefox IE Edge Safari
82* 74* No 79* TP*

Mobile / Tablet

Android Chrome Android Firefox Android iOS Safari
79* 68* 76* 13.3*

Like links, we’ve gotta consider different interactive states with form elements. We’ll consider these when styling our elements:

  • :checked
  • :hover
  • :focus
  • :disabled

For example, here’s how we can style our toggle input, create the knob, and account for the :checked state:

/* The toggle container */
.switch {
  width: 38px;
  border-radius: 11px;
}

/* The toggle knob */
.switch::after {
  left: 2px;
  top: 2px;
  border-radius: 50%;
  width: 15px;
  height: 15px;
  background: var(--ab, var(--border));
  transform: translateX(var(--x, 0));
}

/* Change color and position when checked */
.switch:checked {
  --ab: var(--active-inner);
  --x: 17px;
}

/* Drop the opacity of the toggle knob when the input is disabled */
.switch:disabled:not(:checked)::after {
  opacity: .6;
}

We are using the <input> element like a container. The knob inside of the input is created with the ::after pseudo-element. Again, no more need for extra markup!

If you crack open the styles in the demo, you’ll see that we’re defining some CSS custom properties because that’s become such a nice way to manage reusable values in a stylesheet:

@supports(-webkit-appearance: none) or (-moz-appearance: none) {
  input[type='checkbox'],
  input[type='radio'] {
    --active: #275EFE;
    --active-inner: #fff;
    --focus: 2px rgba(39, 94, 254, .25);
    --border: #BBC1E1;
    --border-hover: #275EFE;
    --background: #fff;
    --disabled: #F6F8FF;
    --disabled-inner: #E1E6F9;
  }
}

But there’s another reason we’re using custom properties — they work well for updating values based on the state of the element! We won’t go into full detail here, but here’s an example how we can use custom properties for different states.

/* Default */
input[type='checkbox'],
input[type='radio'] {
  --active: #275EFE;
  --border: #BBC1E1;
  border: 1px solid var(--bc, var(--border));
}

/* Override defaults */
input[type='checkbox']:checked,
input[type='radio']:checked {
  --b: var(--active);
  --bc: var(--active);
}
  
/* Apply another border color on hover if not checked & not disabled */
input[type='checkbox']:not(:checked):not(:disabled):hover,
input[type='radio']:not(:checked):not(:disabled):hover {
  --bc: var(--border-hover);
}

For accessibility, we ought to add a custom focus style. We are removing the default outline because it can’t be rounded like the rest of the things we’re styling. But a border-radius along with a box-shadow can make for a rounded style that works just like an outline.

input[type='checkbox'],
input[type='radio'] {
  --focus: 2px rgba(39, 94, 254, .25);
  outline: none;
  transition: box-shadow .2s;
}

input[type='checkbox']:focus,
input[type='radio']:focus {
  box-shadow: 0 0 0 var(--focus);
}

It’s also possible to align and style the <label> element which directly follows the <input> element in the HTML:

<input type="checkbox" name="c1" id="c1">
<label for="c1">Checkbox</label>
input[type='checkbox'] + label,
input[type='radio'] + label {
  display: inline-block;
  vertical-align: top;
  /* Additional styling */
}

input[type='checkbox']:disabled + label,
input[type='radio']:disabled + label {
    cursor: not-allowed;
}

Here’s that demo again:

CodePen Embed Fallback

Hopefully, you’re seeing how nice it is to create custom form styles these days. It requires less markup, thanks to pseudo-elements that are directly on form inputs. It requires less fancy style switching, thanks to custom properties. And it has pretty darn good browser support, thanks to @supports.

All in all, this is a much more pleasant developer experience than we’ve had to deal with in the past!

The post Custom Styling Form Inputs With Modern CSS Features appeared first on CSS-Tricks.

Old CSS, new CSS

Post pobrano z: Old CSS, new CSS

I love this post that walks through the development of CSS and HTML — it shows just how far web design has come and how much easier it is for us all now.

Eevee looks at designing websites with tables, the Space Jam website, and how for centuries there was no way to easily inspect changes made to a webpage:

Notice the extremely precise positioning of these navigation links. This feat was accomplished the same way everyone did everything in 1996: with tables.

In fact, tables have one functional advantage over CSS for layout, which was very important in those days, and not only because CSS didn’t exist yet. You see, you can ctrl-click to select a table cell and even drag around to select all of them, which shows you how the cells are arranged and functions as a super retro layout debugger. This was great because the first meaningful web debug tool, Firebug, wasn’t released until 2006 — a whole decade later!

This makes me realize two things. First, I cannot imagine a greater horror than this. And secondly, we’re so lucky to have all the excellent DevTools options that modern day browsers have. One example: I recently remembered that if you see a little grid icon next to some CSS or HTML in Firefox, then you can click it and see the Grid outlines appear:

I think we probably take all of this for granted in our day-to-day lives now but this has me thinking: what are some ways we’ll look back at our work today and be like WHAT! You had to do that thing with XYZ??!?

Direct Link to Article — Permalink

The post Old CSS, new CSS appeared first on CSS-Tricks.

Innovation Can’t Keep the Web Fast

Post pobrano z: Innovation Can’t Keep the Web Fast

Every so often, the fruits of innovation bear fruit in the form of improvements to the foundational layers of the web. In 2015, HTTP/2 became a published standard in an effort to update an aging protocol. This was was both necessary and overdue, as HTTP/1 rendered web performance as an arcane sort of discipline in the form of strange workarounds of its limitations. Though HTTP/2 proliferation isn’t absolute — and there are kinks yet to be worked out — I don’t think it’s a stretch to say the web is better off because of it.

Unfortunately, the rollout of HTTP/2 has presided over a 102% median increase of bytes transferred over mobile the last four years. If we look at the 90th percentile of that same dataset — because it’s really the long tail of performance we need to optimize for — we see an increase of 239%. From 2016 (PDF warning) to 2019, the average mobile download speed in the U.S. has increased by 73%. In Brazil and India, average mobile download speeds increased by 75% and 28%, respectively, in that same period of time.

While page weight alone doesn’t necessarily tell the whole story of the user experience, it is, at the very least, a loosely related phenomenon which threatens the collective user experience. The story that HTTPArchive tells through data acquired from the Chrome User Experience Export (CrUX) can be interpreted a number of different ways, but this one fact is steadfast and unrelenting: most metrics gleaned from CrUX over the last couple of years show little, if any improvement despite various improvements in browsers, the HTTP protocol, and the network itself.

Given these trends, all that can be said of the impact of these improvements at this point is that it has helped to stem the tide of our excesses, but precious little to reduce them. Despite every significant improvement to the underpinnings of the web and the networks we access it through, we continue to build for it in ways that suggest we’re content with the never-ending Jevons paradox in which we toil.

If we’re to make progress in making a faster web for everyone, we must recognize some of the impediments to that goal:

  1. The relentless desire to monetize every square inch of the web, as well as the army of third party vendors which fuel the research mandated by such fevered efforts.
  2. Workplace cultures that favor unrestrained feature-driven development. This practice adds to — but rarely takes away from — what we cram down the wire to users.
  3. Developer conveniences that make the job of the developer easier, but can place an increasing cost on the client.

Counter-intuitively, owners of mature codebases which embody some or all of these traits continue to take the same unsustainable path to profitability they always have. They do this at their own peril, rather than acknowledge the repeatedly established fact that performance-first development practices will do as much — or more — for their bottom line and the user experience.

It’s with this understanding that I’ve come to accept that our current approach to remedy poor performance largely consists of engineering techniques that stem from the ill effects of our business, product management, and engineering practices. We’re good at applying tourniquets, but not so good at sewing up deep wounds.

It’s becoming increasingly clear that web performance isn’t solely an engineering problem, but a problem of people. This is an unappealing assessment in part because technical solutions are comparably inarguable. Content compression works. Minification works. Tree shaking works. Code splitting works. They’re undeniably effective solutions to what may seem like entirely technical problems.

The intersection of web performance and people, on the other hand, is messy and inconvenient. Unlike a technical solution as clearly beneficial as HTTP/2, how do we qualify what successful performance cultures look like? How do we qualify successful approaches to get there? I don’t know exactly what that looks like, but I believe a good template is the following marriage of cultural and engineering tenets:

  1. An organization can’t be successful in prioritizing performance if it can’t secure the support of its leaders. Without that crucial element, it becomes extremely difficult for organizations to create a culture in which performance is the primary feature of their product.
  2. Even with leadership support, performance can’t be effectively prioritized if the telemetry isn’t in place to measure it. Without measurement, it becomes impossible to explain how product development affects performance. If you don’t have the numbers, no one will care about performance until it becomes an apparent crisis.
  3. When you have the support of leadership to make performance a priority and the telemetry in place to measure it, you still can’t get there unless your entire organization understands web performance. This is the time at which you develop and roll out training, documentation, best practices, and standards the organization can embrace. In some ways, this is the space which organizations have already spent a lot of time in, but the challenging work is in establishing feedback loops to assess how well they understand and have applied that knowledge.
  4. When all of the other pieces are finally in place, you can start to create accountability in the organization around performance. Accountability doesn’t come in the form of reprisals when your telemetry tells you performance has suffered over time, but rather in the form of guard rails put in place in the deployment process to alert you when thresholds have been crossed.

Now comes the kicker: even if all of these things come together in your workplace, good outcomes aren’t guaranteed. Barring some regulation that forces us to address the poorly performing websites in our charge — akin to how the ADA keeps us on our toes with regard to accessibility — it’s going to take continuing evangelism and pressure to ensure performance remains a priority. Like so much of the work we do on the web, the work of maintaining a good user experience in evolving codebases is never done. I hope 2020 is the year that we meaningfully recognize that performance is about people, and adapt accordingly.

As technological innovations such as HTTP/3 and 5G emerge, we must take care not to rest on our laurels and simply assume they will heal our ills once and for all. If we do, we’ll certainly be having this discussion again when the successors to those technologies loom. Innovation alone can’t keep the web fast because making the web fast — and keeping it that way — is the hard work we can only accomplish by working together.

The post Innovation Can’t Keep the Web Fast appeared first on CSS-Tricks.

Smaller HTML Payloads with Service Workers

Post pobrano z: Smaller HTML Payloads with Service Workers

Short story: Philip Walton has a clever idea for using service workers to cache the top and bottom of HTML files, reducing a lot of network weight.

Longer thoughts: When you’re building a really simple website, you can get away with literally writing raw HTML. It doesn’t take long to need a bit more abstraction than that. Even if you’re building a three-page site, that’s three HTML files, and your programmer’s mind will be looking for ways to not repeat yourself. You’ll probably find a way to „include” all the stuff at the top and bottom of the HTML, and just change the content in the middle.

I have tended to reach for PHP for that sort of thing in the past (<?php include('header.php); ?>), although these days I’m feeling much more Jamstack-y and I’d probably do it with Eleventy and Nunjucks.

Or, you could go down the SPA (Single Page App) route just for this basic abstraction if you want. Next and Nuxt are perhaps a little heavy-handed for a few includes, but hey, at least they are easy to work with and the result is a nice static site. The thing about these JavaScript-powered SPA frameworks (Gatsby is in here, too), is that they „hydrate” from static sites into SPAs as the JavaScript loads. Part of the reason for that is speed. No longer does the browser need to reload and request a whole big HTML page again to render; it just asks for whatever smaller amount of data it needs and replaces it on the fly.

So in a sense, you might build a SPA because you have a common header and footer and just want to replace the guts, for efficiencies sake.

Here’s Phil:

In a traditional client-server setup, the server always needs to send a full HTML page to the client for every request (otherwise the response would be invalid). But when you think about it, that’s pretty wasteful. Most sites on the internet have a lot of repetition in their HTML payloads because their pages share a lot of common elements (e.g. the <head>, navigation bars, banners, sidebars, footers etc.). But in an ideal world, you wouldn’t have to send so much of the same HTML, over and over again, with every single page request.

With service workers, there’s a solution to this problem. A service worker can request just the bare minimum of data it needs from the server (e.g. an HTML content partial, a Markdown file, JSON data, etc.), and then it can programmatically transform that data into a full HTML document.

So rather than PHP, Eleventy, a JavaScript framework, or any other solution, Phil’s idea is that a service worker (a native browser technology) can save a cache of a site’s header and footer. Then server requests only need to be made for the „guts” while the full HTML document can be created on the fly.

It’s a super fancy idea, and no joke to implement, but the fact that it could be done with less tooling might be appealing to some. On Phil’s site:

 on this site over the past 30 days, page loads from a service worker had a 47.6% smaller network payloads, and a median First Contentful Paint (FCP) that was 52.3% faster than page loads without a service worker (416ms vs. 851ms).

Aside from configuring a service worker, I’d think the most finicky part is having to configure your server/API to deliver a content-only version of your stuff or build two flat file versions of everything.

Direct Link to Article — Permalink

The post Smaller HTML Payloads with Service Workers appeared first on CSS-Tricks.

Sticky Table of Contents with Scrolling Active States

Post pobrano z: Sticky Table of Contents with Scrolling Active States

Say you have a two-column layout: a main column with content. Say it has a lot of content, with sections that requires scrolling. And let’s toss in a sidebar column that is largely empty, such that you can safely put a position: sticky; table of contents over there for all that content in the main column. A fairly common pattern for documentation.

Bramus Van Damme has a nice tutorial on all this, starting from semantic markup, implementing most of the functionality with HTML and CSS, and then doing the last bit of active nav enhancement with JavaScript.

For example, if you don’t click yourself down to a section (where you might be able to get away with :target styling for active navigation), JavaScript is necessary to tell where you are scrolled to an highlight the active navigation. That active bit is handled nicely with IntersectionObserver, which is, like, the perfect API for this.

Here’s that result:

CodePen Embed Fallback

It reminds me of a very similar demo from Hakim El Hattab he called Progress Nav. The design pattern is exactly the same, but Hakim’s version has this ultra fancy SVG path that draws itself along the way, indenting for sub nav. I’ll embed a video here:

That one doesn’t use IntersectionObserver, so if you want to hack on this, combine ’em!

The post Sticky Table of Contents with Scrolling Active States appeared first on CSS-Tricks.

Playwright

Post pobrano z: Playwright

So Microsoft launches a Node-based browser automation project called Playwright. It allows you to spin up a headless version of a browser and control it. Go here! Click something! Take a screenshot! That kind of stuff. Particularly useful for testing.

It’s just like Google’s Puppeteer, only instead of being Chrome-only, it also „works” in Firefox and Safari.

The drama started immediately.

The launch tweet from Andrey Lushnikov (who’s Twitter bio is „former TL @ Chrome Puppeteer, former eng @ Chrome DevTools”), is responded to by Sam Sneddon who questions the cross-browser compatibility. Apparently that compatibility comes via very large patches to those other browsers which some feel are a little house-of-cards-esque and will never actually land in those other browsers, especially since there are competing efforts like puppeteer-firefox.

It’s fairly obvious that the original team from Google behind Puppeteer kinda, uhhhh, made their way over to Microsoft and re-did the work over there. A little bird tells me Google is proper pissed about it.

I don’t have any other inside knowledge here, but it doesn’t seem to make Microsoft look very good here. For a company that has had so much success with an open-source strategy, hiring away a team to build a directly competing alternate open-source project without much cooperation from the other open-source projects it integrates with isn’t a great look. At the same time, having a working project that allows cross-browser headless control is pretty rad.

Feel free to enlighten me if I have it all wrong.

Related: As I understand it, Cypress doesn’t use either project, but has their own thing, and is close to Firefox support as well.

Direct Link to Article — Permalink

The post Playwright appeared first on CSS-Tricks.

Bundling JavaScript for Performance: Best Practices

Post pobrano z: Bundling JavaScript for Performance: Best Practices

Performance advice from David Calhoun on how many scripts to load on a page for best performance:

[…] some of your vendor dependencies probably change slower than others. react and react-dom probably change the slowest, and their versions are always paired together, so they both form a logical chunk that can be kept separate from other faster-changing vendor code:

<!-- index.html -->
<script src="vendor.react.[hash].min.js"></script>
<script src="vendor.others.[hash].min.js"></script>
<script src="index.[hash].min.js"></script>

Funny how times haven’t changed that much! Me, in 2012, talking about how many CSS files need to be loaded on any given page: One, Two, or Three. I split it into global, section-specific, and-page-specific so it was less about third-party code, although that could certainly apply, too.

Direct Link to Article — Permalink

The post Bundling JavaScript for Performance: Best Practices appeared first on CSS-Tricks.