Hello, Blog!

Introducing my blog, and an experiment in responsive design without breakpoints

Introducing the Blog

I've always enjoyed technical writing and have always kicked around the idea of starting a blog, so it's time to get started! This is primarily to

I hope to focus on the following topics to write articles about:

  • Thoughts and concepts in Software Engineering
  • Tutorials
  • Talking about experiments or new things that I've learned

Experiment: A Responsive Website without Breakpoints

I figured I would start the blog with an example of the last item - in this case - is it possible to build a responsive website without breakpoints? Why would someone attempt this, or why would that matter?

The idea came to me after coming across an article titled "The 100% correct way to do CSS breakpoints"  , which describes the problem with setting up breakpoints in the "traditional" (read: Bootstrap) way:

  • X-Small: 0-576px
  • Small: 576-768px
  • Medium: 768-992px
  • Large: 992-1200px
  • X-Large: 1200-1400px
  • XX-Large: >1400px

The article (convincingly) argues that this is the wrong way to think about breakpoints, rather than breaking on exact device widths ("Wait, is the 768px inclusive or exclusive?"), you should instead think about ranges instead of points, and groups of devices rather than single cut-off points. However, coming across this article many years later, I can't help but to think there's more to the story now.

It isn't just about the device width, but there are also more ways that screens are used. Android has a One Handed Mode   that changes how the screens are used. Windows has had Snap To Edge   for a long time. Devices have multiple orientations that people often switch between, and mobile devices have made a full cycle back around to being foldable. One can imagine a world (or does it already exist?) where screens are present on common household items such as refrigerators, security system panels, thermostats, and desks?

These aren't just statically different devices, but also dynamically different - someone may be on your website interacting with their finger, and then fold open their phone and interact with a stylus without a page reload.

Media Queries

Media queries were originally developed to give developers the ability to display the website differently based on the media that it was being viewed on. The earliest application of this was to provide different styles for screen and print versions of the website, as elements could look different on a computer screen vs. a piece of paper. Later on, with the advent of mobile devices and the standardization of Media Queries Level 3   these became almost synonymous with "breakpoints", as the most commonly used media query by far is width.

Nowadays, in {current year}, although we have more challenges, we also have more tools available to us for responsive design, and these are especially effective for static content (such as this website), assuming you don't need to support Internet Explorer  . Here are a sampling of these tools.

Relative Units

Most front-end developers are comfortable with the idea of relative units, such as em and rem which can particularly help with making styles more resistant to change by sizing with relative units rather than specific pixel sizes. This also helps when a user has configured their web browser to use a different default font size than 16px by automatically scaling your text according to their preferences.

There are other units available also, such as vw (viewport width), vh (viewport height), ch (character width), and using percentages.

Example from this site:

.main {
  margin: 0 auto 2rem auto;
  max-width: 110ch;
}

This is a simple example that keeps the main content centered and at a maximum of 110 characters wide (the "zero" character 0 is the baseline for the width of a character). If you stretch or shrink this page, you'll see the central column widen to 110 characters and then stay there. This is also quite easy to adjust, just changing the 110 to something else and the page remains intact.

clamp()

The CSS clamp() function   can be used for fluidly resizing values. The example below uses it to resize the <h1> based on the current viewport width:

.main h1 {
  font-size: clamp(2rem, 4vw, 3.5rem);
}

The function arguments are (MIN, VAL, MAX), and rem units are used for the MIN and MAX to provide limits on the size (relative to the user's font size preference), and the VAL is the "preferred value" that is based on the current viewport width.

calc() and var()

The calc() function can be used to... calculate values, and var() allows referencing a CSS Custom Property  .

.main {
  /* Fluidly scale padding down to 1rem at small screen widths */
  --scaling-factor: 20;
  --relative-padding: calc(100vw - 320px);
  padding-left: calc(var(--relative-padding) / var(--scaling-factor) + 1rem);
  padding-right: calc(var(--relative-padding) / var(--scaling-factor) + 1rem);
}

This is a little math that causes the horizontal padding to fluidly shrink as the viewport shrinks, all way down to a minimum of 1rem (if the viewport width was 0).

CSS Grid

There are many (better) resources available for learning CSS Grid, but just an example from this site for making a grid that fluidly rearranges items in the grid and resizes them based on screen width.

.card-grid {
  display: grid;
  row-gap: 3vw;
  column-gap: 3vw;

  --min-card-width: 20rem;
  grid-template-columns: repeat(auto-fit, minmax(var(--min-card-width), 1fr));
}

This allows for a 2x3 grid to fluidly resize to 3x2 and then 6x1 on a shrinking screen, and adjusts the items themselves (with a minimum threshold) to reduce the amount that the layout is rearranged.

Media Queries for Detecting Other Media

Throughout this experiment, I haven't banned myself from using media queries, just "breakpoints". I'm using the prefers-color-schema   media query to default the dark/light mode based on your browser or operating system preferences. Applications that use animations really should use prefers-reduced-motion   for the comfort and safety of their users, and prefers-contrast   to ensure that everyone can see the content effectively. We can detect if the device has a coarse pointer (ex. finger) or a fine pointer (ex. mouse) to make buttons easier to press/click.

Other interesting modern media queries can be seen in the Media Queries Level 4   specification. Of course, we should check for browser support, and only use these for progressive enhancement, not rely on them.

During research for this article, I came across "What if I told you that you can build a web page without device-based breakpoints?"   which discusses much of the same topics.

Disclaimer and Closing Thoughts

I am definitely not a UI or CSS expert (I primarily work with server-side technologies), these are just some neat tricks that I learned during this experiment. This was also not intended as a tutorial or a comprehensive source of information. I fully expect there will be responsiveness issues with this website itself, please Report an Issue   with details of the issue if you find any. I'll try my best to fix it without introducing any breakpoints, bonus points for finding this issue on a weird or obscure device!

I used this as an opportunity to learn about the real purpose of media queries and what we can do with them (and just as importantly, what we can do without them). The best part about all this is there is significantly less CSS that I have to write and maintain with the fluid design than with the "traditional" breakpoint approach. Gone are the days of adjusting fonts at every breakpoint, embrace robust and dynamic styling!