Tag: just

That’s Just How I Scroll

How do you know a page (or any element on that page) scrolls? Well, if it has a scrollbar, that’s a pretty good indication. You might still have to scrapple with your client about “the fold” or whatever, but I don’t think anyone is confused at what a scrollbar is or what it indicates.

But let’s say there is no scrollbar. That’s super common. macOS hides scrollbars by default and only shows them during scroll. Most mobile browsers don’t have scrollbars, even if you attempt to force them with something like overflow: scroll;.

Why does this matter? If you don’t know an area is scrollable, you might miss out on important content or functionality.

I regularly think about the Perfectly Cropped story from Tyler Hall. There is a screen on iOS that has important functionality you need to scroll down to, but there is no indicator whatsoever that you can scroll there.

The result of that was Tyler’s mom literally not being able to find functionality she was used to. Not great.

There is an elaborate way to detect visible scrollbars and force them to be visible, but something about that rubs me the wrong way. It doesn’t honor a user’s preference (assuming it is the user’s preference), requires DOM manipulation tests, and uses vendor-prefixed CSS (which will probably live a long time, but has been standardized now, so maybe not forever).

I enjoy these approaches and by Chris Smith and his thinking:

My favorite are the shadow-based techniques. To me an inset shadow is a really clear indicator, as it makes it appear that content is flowing underneath and the shadow follows an edge that as a hint that you can scroll in that direction. Plus, you’ve got CSS control there so I’d think it could match whatever UI situation you’re in fairly easily.

It should be known though that it can be done entirely in CSS though, no JavaScript, and is one of the great CSS tricks.


The post That’s Just How I Scroll appeared first on CSS-Tricks.

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

CSS-Tricks

, ,

Just another +1 for subgrid

I’d say 85% of my grid usage is in one of these two categories…

  1. I just need some pretty basic (probably equal width) columns that ends up being something like like grid-template-columns: repeat(3, minmax(0, 1fr)); to be safe.
  2. Actually doing some real layout where five minutes in I realize I’d really like subgrid.

Subgrid? It’s a nice intuitive way to have a child element on the grid inherit relevant grid lines from the parent grid.

Here’s a great recent video from Rachel Andrew covering it. Last year, we linked up her talk on the same! It’s such a clutch feature and I wish we could rely on it cross-browser. Right now, Firefox is the only one that has it. (Chrome issue, Safari issue)

In my recent video, right about at 20 minutes, I realize subgrid would make even a fairly simple layout much nicer, like removing the need for variables or resorting to magic numbers.

The post Just another +1 for subgrid appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Flexbox-like “just put elements in a row” with CSS grid

It occurred to me while we were talking about flexbox and gap that one reason we sometimes reach for flexbox is to chuck some boxes in a row and space them out a little.

My brain still reaches for flexbox in that situation, and with gap, it probably will continue to do so. It’s worth noting though that grid can do the same thing in its own special way.

Like this:

.grid {   display: grid;   gap: 1rem;   grid-auto-flow: column; }

They all look equal width there, but that’s only because there is no content in them. With content, you’ll see the boxes start pushing on each other based on the natural width of that content. If you need to exert some control, you can always set width / min-width / max-width on the elements that fall into those columns — or, set them with grid-template-columns but without setting the actual number of columns, then letting the min-content dictate the width.

.grid {   display: grid;   gap: 1rem;   grid-auto-flow: column;   grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr)); }

Flexible grids are the coolest.

Another thought… if you only want the whole grid itself to be as wide as the content (i.e. less than 100% or auto, if need be) then be aware that display: inline-grid; is a thing.

The post Flexbox-like “just put elements in a row” with CSS grid appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Block Links Are a Pain (and Maybe Just a Bad Idea)

As we noted in our complete guide, you can put an <a href=""> link around whatever chunks of HTML you like. Let’s call that a “block link.” Like you are wanting to link up an entire “Card” of content because it makes a big clickable target.

<a href="/article/"> <!-- display: block; -->   <div class="card">     <h2>Card</h2>     <img src="..." alt="...">     <p>Content</p>   </div> </a>

On that, Adrian Roselli:

Perhaps the worst thing you can do for a block link is to wrap everything in the <a href>.

[…] for a screen reader user the entire string is read when tabbing through controls. In the following example, the first link contains the heading, image (without declaring it as an image), and block of text, taking about 25 seconds to read before announcing it as a link. When tabbing, you do not always know the control type until the accessible name is complete.

(The example is a pretty normal looking card with a header, image, and paragraph.)

So don’t do that.

The alternative is to let the link be “normal” like just the header.

<div class="card">   <h2><a href="/article/">Article</a></h2>   <img src="..." alt="...">   <p>Content</p> </div>

The extending the “clickable area” of the link to cover the entire area.

.card {   position: relative; } .card h2 a::after {   content: "";   position: absolute;   top: 0;   left: 0;   width: 100%;   height: 100%; }

That works for the clickable area and solves the penalty to screen reader users.

But there is another problem that hurts both of these solutions, and it’s text selection. You can’t just put your cursor somewhere in the card and select text normally. The click activates the link, waiting for you to mouseup while still on the link to trigger it. You don’t get the ability to select inner parts of the text as you would probably expect. It doesn’t prevent the ability to select the text at all, but it makes it awkward and annoying.

I’m not sure that is easily solveable. Perhaps there is some exotic JavaScript solution that can detect if you’ve started to select text and then not trigger a click, but if you click without dragging then it does go to the link. Something about that is a bit red-flaggy to me though.

All in all, I’d say block links are just a bad idea. But I’d love to be proven wrong and see a really good implementation that solves all these issues.

The post Block Links Are a Pain (and Maybe Just a Bad Idea) appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

Just Dropping Some Type Links

I’ve had a bunch of tabs open that just so happen to all be related to typography, so I figured I’d give myself the mental release of closing them by blogging them. How’s that for a blog post format for ya: whatever random tabs you’ve had open for far too long.

  • Times New Roman is popular on the web in the sense that it’s a default font installed on most computers and safe to use without having to load any web fonts. But it’s also the default font that (all?) web browsers use if you don’t declare a font-family at all so, in that sense, it sometimes feels like a site is broken on accident when Times is used. Typewolf has a nice list of alternatives if you like the vibe but need something different.
  • Speaking of Times, err, The New York Times profiles TypeThursday with a pretty funny correction where they got the typeface name wrong.
  • In the last month of 2019, Tyopgraphica published their favorite typefaces of 2018. Fern grabs me.
  • Una Kravets has a “designing in the browser” video about typography on the Chrome Developers channel on YouTube. About 11 minutes in, she gets into variable fonts which are just incredible. I know they are capable of all sorts of amazing things (even animation), but I remain the most excited about performance: loading one font and having tons of design control.
  • Florens Verschelde’s “A short history of body copy sizes on the Web” gets into how typical font size usage has crept up and up over the years.
  • Alina Sava makes the argument that font licensing is ill. Primarily: pricing web fonts based on page views. As someone who works on some high-traffic / fairly-low-profit websites, it’s hard to disagree.
  • Matej Latin covers five fonts designed for coding that have ligatures. Ya know, instead of != you get , but only visually rather than actually changing the characters that are used as I did there. Ligatures are a neat trick to use (another trick: ligatures as icons), but Matthew Butterick says “hell no”: The ligature introduces an ambiguity that wasn’t there before. I find it notable that Operator Mono chose not to go there. I feel like I overheard a discussion about it once but can’t dig it up now. I know there is a way to add them, and it’s a little surprising to me that’s legal.
  • Trent popped some new fonts on his blog and shared his font shopping list.
  • You might have noticed some new fonts around here on CSS-Tricks as well, as of a few weeks ago. I just wanted to freshen up the place as I was getting sick of looking at system fonts (they started looking bad to me on Catalina, which is something Andy Baio pointed out is a Chrome Bug, but still). The CSS-Tricks logo has long been Gotham Rounded, so I went back to Hoefler&Co. for the font choices here to kinda stay in the family. The headers use Ringside, monospace content uses Operator Mono, and the body uses Sentinel.

The post Just Dropping Some Type Links appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Responsive Grid Magazine Layout in Just 20 Lines of CSS

I was recently working on a modern take of the blogroll. The idea was to offer readers a selection of latest posts from those blogs in a magazine-style layout, instead of just popping a list of our favorite blogs in the sidebar.

The easy part was grabbing a list of posts with excerpts from our favorite RSS feeds. For that, we used a WordPress plugin, Feedzy lite, which can aggregate multiple feeds into a single time-ordered list — perfect for showcasing their latest offerings. The hard part was making it all look awesome.

The plugin’s default list UI is rather bland, so I wanted to style it to look like a newspaper or magazine website with a mixture of smaller and larger “featured content” panels.

This seems like an ideal case for CSS Grid! Create a grid layout for different layouts, say, one five-column layout and one three-column layout, then use media queries to switch between them at different break points. Right? But do we actually need those media queries — and all the hassle of identifying break points — when we can use grid’s auto-fit options to automatically create a fluid responsive grid for us? 

The approach sounded tempting, but when I started introducing column-spanning elements, I ran into trouble with the grid overflowing on narrow screens. Media queries appeared to be the only solution. That is, until I found a workaround!

After looking at several tutorials on CSS Grid, I found that they largely fall into two camps:

  1. Tutorials that show you how to create an interesting layout with spanned elements, but for a fixed number of columns.
  2. Tutorials that explain how to make a responsive grid that resizes automatically, but with all of the grid items the same width (i.e. without any spanned columns).

I want to make the grid do both: create a fully responsive fluid layout that includes responsively resizing multi-column elements as well.

The beauty is that once you understand the limitations of responsive grids, and why and when column spans break grid responsiveness, it is possible to define a responsive magazine/news style layout in just a dozen lines of code plus one simple media query (or even with no media queries if you are willing to limit your span options).

Here’s a visual showing the RSS plugin right out of the box and what it’ll look like after we style it up. 

(Demo)

This magazine-style grid layout is fully responsive with the colored featured panels adjusting dynamically as the number of columns change. The page displays around 50 posts, but the layout code is agnostic as to the number of items displayed. Ramp up the plugin to show 100 items and the layout stays interesting all the way down.

All of this is achieved using only CSS and with only a single media query to deal with a single column display on the narrowest of screens (i.e. smaller than 460px).

Incredibly, this layout only took 21 lines of CSS (excluding global content styling). However, to achieve such flexibility in such a few lines of code, I had to dig deep into the more obscure parts of some of  CSS Grid and learn how to work around some of its inherent limitations.

The essential elements of the code that produce this layout is incredibly short and a testament to the awesomeness of CSS Grid:

.archive {   display: grid;   grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));   grid-gap: 32px;   grid-auto-flow: dense; }  /* Extra-wide grid-posts */ .article:nth-child(31n + 1) {   grid-column: 1 / -1; } .article:nth-child(16n + 2) {   grid-column: -3 / -1; } .article:nth-child(16n + 10) {   grid-column: 1 / -2; }  /* Single column display for phones */ @media (max-width: 459px) {   .archive {     display: flex;     flex-direction: column;   } }

The techniques in this article could be used equally well to style any dynamically generated content such as the output from a latest posts widget, archive pages or search results.

Creating a responsive grid

I have set up seventeen items displaying a variety of mock content — headlines, images and excerpts — which are all contained in a wrapper

<div class="archive">   <article class="article">     <!-- content -->   </article>      <!-- 16 more articles -->    </div>

The code that turns these items into a responsive grid is remarkably compact:

.archive {   /* Define the element as a grid container */   display: grid;   /* Auto-fit as many items on a row as possible without going under 180px */   grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));   /* A little spacing between articles */   grid-gap: 1em; }

Notice how the heights of the rows automatically adjust to accommodate the tallest content in the row. If you change the width of the Pen, you will see the items grow and shrink fluidly and the number of columns change from one to five, respectively.

The CSS Grid magic at play here is the auto-fit keyword that works hand-in-hand with the minmax() function that’s applied to grid-template-columns.

How it works

We could have achieved the five-column layout alone using this:

.archive {   display: grid;   grid-template-columns: repeat(5, 1fr); }

However, this would create five columns that grow and shrink with different screen widths, but always stay at five columns, resulting in them becoming ridiculously narrow on small screens. The first thought might be to create a bunch of media queries and redefine the grid with different numbers of columns. That would work fine, but with the auto-fit keyword, it is all done automatically.

For auto-fit to work the way we want, we need to use the minmax() function. This tells the browser how small the columns can be squeezed down to followed by the maximum width they can expand to. Any smaller, and it will automatically reduce the number of columns. Any larger, and the number of columns increases.

.archive {   grid-template-columns: repeat (auto-fit, minmax(180px, 1fr)); }

In this example, the browser will fit in as many columns as it can 180px wide. If there is space left over the columns will all grow equally by sharing the remaining space between them —  that’s what the 1fr value is saying: make the columns equal fractions of the available width. 

Drag the window out and as the available space increases the columns all grow equally to use up any additional space. The columns will keep growing until the available space allows for an additional 180px column, at which point a whole new column appears. Decrease the screen width, and the process reverses, perfectly adjusting the grid all the way down to a single column layout. Magic!

And you get all this responsiveness out of just one line of code. How cool is that? 

Creating spans with “autoflow: dense”

So far, we have a responsive grid but all items the same width. For a news or magazine layout we need some content to be featured by spanning two or more columns or even, perhaps, to span all the columns.

To create multi-column spans we can add the column-span feature to the grid items we want to take up more space. For example, if we want the third item in our list to be two columns wide we can add:

.article:nth-child(3) {   grid-column: span 2; }

However, once we start adding spans a number of problems can arise. First, gaps may appear in the grid because a wide item may may not fit on the row, so grid auto-fit pushes it onto the next line, leaving a gap where it would have been:

The easy fix is adding grid-auto-flow: dense to the grid element which tells the browser to fill in any gaps with other items, effectively making the narrower content flow around the wider items like this:

Note that the items are now out of order, with the fourth item coming before the third item, which is double the width. There is no way round this as far as I can tell, and it is one of the limitations you have to accept with CSS Grid.

Check out Geoff Graham’s “The Auto-Flowing Powers of Grid’s Dense Keyword” for an introduction to grid-auto-flow: dense with examples of how it behaves.

Ways to specify spans

There are several ways to indicate how many columns an item should span. The easiest is to apply grid-columns: span [n] to one of the items, where n  is the number of columns the element will span. The third item in our layout has grid-column: span 2, which explains why it is double the width of other items that only span a single column.

Other methods require you to explicitly define grid lines. The numbering system for grid lines is as follows:

Grid lines can be specified from left-to-right using positive values (e.g. 1, 2, 3) or negative values (e.g. -1, -2, -3) to go from right-to-left. These can be used to place items on the grid using the grid-column property like this:

.grid-item {   grid-column: (start track) / (end track); }

So, this gives us additional ways to specify a spanned item. This is especially flexible as either the start or end value can be replaced with the span keyword. For example, the three-column blue box in the example above could be created by adding any of the following to the eighth grid item:

  • grid-column: 3 / 6
  • grid-column: -4 / -1
  • grid-column: 3 / span 3
  • grid-column: -4 / span 3
  • grid-column: span 3 / -1
  • Etc.

On a non-responsive (i.e. fixed columns) grid, these all produce the same effect (like the blue box above), however, if the grid is responsive and the number of columns changes, their differences start to become apparent. Certain column spans break the  layout with an auto-flowing grid, making the two techniques appear incompatible. Fortunately, there are some solutions which allow us to combine the two successfully. 

First, however, we need to understand the problem.

Overflow side-scrolling problems

Here are some featured areas created using the notation above:

(Demo)

It all looks good at full-width (five columns) but when resized to what should be two columns, the layout breaks like this:

 As you can see, our grid has lost its responsiveness and, although the container has shrunk, the grid is trying to maintain all five columns. To do so, it has given up trying to keep equal-width columns, and the grid is breaking out of the right-hand side of its container, causing horizontal scrolling.

Why is this? The problem comes about because the browser is trying to honor the explicit grid lines we named. At this width, the auto-fit grid should implicitly be displaying two columns, but our grid line numbering system contradicts this by explicitly referring to the fifth grid line. This contradiction leads to the mess. To display our implicit two-column grid correctly, the only line numbers allowed are 1, 2 and 3 and -3, -2, -1, like this:

But if any of our grid items contains grid-column references that lie outside this, such as grid line number 4, 5 or 6 (or -4, -5 or -6), the browser is getting mixed messages. On the one hand, we have asked it to automatic create flexible columns (which should implicitly give us two columns at this screen width) but we have also explicitly referred to grid lines that don’t appear in a two-column grid. When there is a conflict between implicit (automatic) columns and an implicit number of columns, grid always defers to the explicit grid; hence the unwanted columns and horizontal overflow (which has also been aptly named CSS data loss). Just like using grid line numbers, spans can also create explicit columns. So, grid-column: span 3 (the eighth grid item in the demo) forces the grid to explicitly adopt at least three columns, whereas we want it, implicitly display two.

At this point it might seem like the only way forward is to use media queries to change the grid-column values at the width where our layout breaks — but not so fast! That’s what I assumed at first. But after thinking it though a bit more and playing around with various options, I found there are a limited set of workarounds that work all the way down to two columns, leaving just one media query to cover a single column layout for the narrowest screens.

The solutions

The trick, I realized, is to only specify spans using grid lines that appear in the narrowest grid you intend to display. That is a two-column grid in this case. (We will use a media query to cover the single column scenario for very narrow screens.) That means we can safely use grid lines 1, 2 and 3 (or -3, -2 and -1) without breaking the grid.

I initially thought that meant limiting myself to a maximum span of two columns, using combinations of the following:

  • grid column: span 2
  • grid-column: 1 /3
  • grid-column: -3 / -1

Which remains perfectly responsive right down to two columns:

Although this works, it is rather limiting from a design perspective, and not particularly exciting. I wanted to be able to create spans that would be three, four or even five columns wide on large screens. But how? My first thought was that I would have to resort to media queries (OMG old habits die hard!) but I was trying to get away from that approach and think differently about responsive design.

Taking another look at what we can do with just 1 to 3 and -3 to -1, I gradually realized that I could mix positive and negative line numbers for the grid column’s start and end values ,such as 1/-3 and 2/-2. At first glance, this does not seem very interesting. That changes when you realize where these lines are located as you resize the grid: these spanned elements change width with the screen size. This opened up a whole new set of possibilities for responsive column spans: items that will span different numbers of columns as the screen gets wider, without needing media queries.

The first example I discovered is grid-column: 1/-1.This makes the item act like a full-width banner, spanning from the first to the last column at all column numbers. it even works down to one column wide!

By using grid-column: 1/-2, a left-aligned nearly-full-width span could be created that would always leave a one column item to the right of it. When shrunk to two columns it would shrink responsively to a single column. Surprisingly, it even works when shrunk to a single column layout. (The reason seems to be that grid will not collapse an item to zero width, so it remains one column wide, as does grid-column: 1/1.) I assumed grid-column: 2/-1 would work similarly, but aligned with the right-hand edge, and for the most part it does, except at one column display when it causes overflow.

Next I tried 1/-3  which worked fine on wider screen, showing at least three columns, and smaller screens, showing one column. I thought it would do something weird on a two-column grid as the first grid line is the same as the grid line with -3. To my surprise, it still displays fine as a single-column item. 

After a lot of playing around, I came up with eleven possible grid column values using grid line numbers from the two-column grid. Surprisingly, three of these work right down to single-column layouts. Seven more work down to two columns and would only need a single media query to deal with single column display.

Here is the full list:

Responsive grid-column values, showing how they display at different screen sizes in an auto-fit grid. (Demo)

As you can see, although this is a limited subset of every possible responsive span, there are actually a lot of possibilities.

  • 2/-2 is interesting as it creates a centered span which works all the way down to one column! 
  • 3/-1 is  least useful as it causes overflow even with two-columns.
  • 3/-3 was a surprise.

By using a variety of grid-column values from this list, it is possible to create an interesting and fully responsive layout. Using a single media query for the narrowest single-column display, we have ten different grid-column span patterns to play with.  

The single-column media query is generally straightforward as well. The one on this final demo reverts to using flexbox at smaller screens:

@media (max-width: 680px) {   .archive {     display: flex;     flex-direction: column;   }    .article {     margin-bottom: 2em;   } }

Here is the final grid which, as you can see, is fully responsive from one to five columns:

(Demo)

Using :nth-child() to repeat variable length displays

The last trick I used to get my code down to two dozen lines was the :nth-child(n) selector which I used to style multiple items in my grid. I wanted my span styling to apply to multiple items in my feed, so that the featured post boxes appeared regularly throughout the page. To start with I used a comma-separated selector list, like this:

.article:nth-child(2), .article:nth-child(18), .article:nth-child(34), .article:nth-child(50)  {   background-color: rgba(128,0,64,0.8);   grid-column: -3 / -1; }

But I soon found this cumbersome, especially as I had to repeat this list for each child element I wanted to style within each article — such as the title, links and so on. During prototyping, if I wanted to play around with the position of my spanned elements, I had to manually change the numbers in each of these lists, which was tedious and error prone.

That’s when I realized that I could use a powerful feature :nth-child pseudo-selector instead of a simple integer as I had used in the list above. :nth-child(n) can also take an equation, such as :nth-child(2n+ 2), which will target every second child element.

Here is how I used the :nth-child([formula]) to create the blue full-width panels in my grid which appear at the very top of the page, and is repeated just over half way down:

.article:nth-child(31n + 1) {   grid-column: 1 / -1;   background: rgba(11, 111, 222, 0.5); }

The bit in the brackets (31n + 1 ) ensures that the 1st, 32nd, 63rd, etc. child is selected. The browser runs a loop starting with n=0 (in which case 31 * 0 + 1 = 1), then n=1 (31 * 1 + 1 = 32), then n=2 (31 * 2 + 1 = 63). In the last case, the browser realizes that  there is no 63rd child item so it ignores that, stops looping, and applies the CSS to the 1st and 32nd children.

I do something similar for the purple boxes which alternate down the page from right-to-left:

.article:nth-child(16n + 2) {   grid-column: -3 / -1;   background: rgba(128, 0, 64, 0.8); }  .article:nth-child(16n + 10) {   grid-column: 1 / -2;   background: rgba(128, 0, 64, 0.8); }

The first selector is for the right-hand purple boxes. The 16n + 2 makes sure that the styling applies to every 16th grid item, starting with the second item.

The second selector targets the right-hand boxes. It uses the same spacing (16n) but with a different offset (10). As a result, these boxes appear regularly on the right-hand side for grid items 10, 26, 42, etc.

When it comes to the visual styling for these grid items and their contents, I used another trick to reduce repetition. For styles that both boxes share (such as the background-color, for example) a single selector can be used to target both:

.article:nth-child(8n + 2) {   background: rgba(128, 0, 64, 0.8);   /* Other shared syling */ }

This will target items 2, 10, 18, 26, 34, 42, 50, and so forth.  In other words,  it selects both the left- and right-hand featured boxes.

It works because 8n is exactly half of 16n, and because the offsets used in the two separate selectors have a difference of 8 (i.e. the difference between +10 and +2 is 8) 

Final thoughts

Right now, CSS Grid can be used to create flexible responsive grids with minimal code, but this does come with some significant limitations on positioning elements without the retrograde step of using media queries.

It would be great to be able to specify spans that would not force overflow on smaller screens. At the moment, we effectively tell the browser, “Make a responsive grid, please,” which it does beautifully. But when we continue by saying, “Oh, and make this grid item span four columns,” it throws a hissy-fit on narrow screens, prioritizing the four-column span request rather than the responsive grid. It would be great to be able to tell grid to prioritize responsiveness over our span request. Something like this:

.article {   grid-column: span 3, autofit; }

Another issue with responsive grids is the last row. As the screen width changes the last row will frequently not be filled. I spent a long time looking for a way to make the last grid item span (and hence fill) the remaining columns, but it seems you can’t do it in Grid right now. It would be nice if we could specify the item’s start position with a keyword like auto meaning, “Please leave the left-hand edge wherever it falls.” Like this:

.article {   grid-column: auto, -1; }

…which would make the left-hand edge span to the end of the row.

The post Responsive Grid Magazine Layout in Just 20 Lines of CSS appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

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.

CSS-Tricks

, , , , , ,
[Top]

“All these things are quite easy to do, they just need somebody to sit down and just go through the website”

I saw a video posted on Twitter from Channel 5 News in the UK (I have no idea what the credibility of them is, it’s an ocean away from me) with anchor Claudia Liza asking Glen Turner and Kristina Barrick questions about website accessibility.

Apparently, they often post videos with captions, but this particular video doesn’t (ironically). So, I’ve transcribed it here as I found them pretty well-spoken.

[Claudia Liza]: … you do have a visual impairment. How does that make it difficult for you to shop online?

[Glen Turner]: Well, I use various special features on my devices to shop online to make it easier. So, I enlarge the text, I’ll invert the colors to make the background dark so that I don’t have glare. I will zoom in on pictures, I will use speech to read things to me because it’s too difficult sometimes. But sometimes websites and apps aren’t designed in a way that is compatible with that. So sometimes the text will be poorly contrasted so you’ll have things like brown on black, or red on black, or yellow on white, something like that. Or the menu system won’t be very easy to navigate, or images won’t have descriptions for the visually impaired because images can have descriptions embedded that a speech reader will read back to them. So all these various factors make it difficult or impossible to shop on certain websites.

[Claudia Liza]: What do you need retailers to do? How do they need to change their technology on their websites and apps to make it easier?

It’s quite easy to do a lot of these things, really. Check the colors on your website. Make sure you’ve got light against dark and there is a very clear distinctive contrast. Make sure there are descriptions for the visually impaired. Make sure there are captions on videos for the hearing impaired. Make sure your menus are easy to navigate and make it easy to get around. All these things are quite easy to do, they just need somebody to sit down and just go through the website and check that it’s all right and consult disabled people as well. Ideally, you’ve got disabled people in your organization you employ, but consult the wider disabled community as well. There is loads of us online there is loads of us spread all over the country. There is 14 million of us you can talk to, so come and talk to us and say, “You know, is our website accessible for you? What can we do to improve it?” Then act on it when we give you our advice.

[Claudia Liza]: It makes sense doesn’t it, Glen? It sounds so simple. But Christina, it is a bit tricky for retailers. Why is that? What do other people with disabilities tell you?

So, we hear about content on websites being confusing in the way it’s written. There’s lots of information online about how to make an accessible website. There’s a global minimum legal standard called WCAG and there’s lot of resources online. Scope has their own which has loads of information on how to make your website accessible.

I think the problem really is generally lack of awareness. It doesn’t get spoken about a lot. I think that disabled consumers – there’s not a lot of places to complain. Sometimes they’ll go on a website and there isn’t even a way to contact that business to tell them that their website isn’t accessible. So what Scope is trying to do is raise the voices of disabled people. We have crowdsourced a lot of people’s feedback on where they experience inaccessible websites. We’re raising that profile and trying to get businesses to change.

[Claudia Liza]: So is it legal when retails aren’t making their websites accessible?

Yeah, so, under the Equality Act 2010, it’s not legal to create an inaccessible website, but what we’ve found is that government isn’t generally enforcing that as a law.

[Claudia Liza]: Glenn, do you feel confident that one day you’ll be able to buy whatever you want online?

I would certainly like to think that would be the case. As I say, you raise enough awareness and get the message out there and alert business to the fact that there is a huge consumer market among the disabled community, and we’ve got a 274 billion pound expenditure a year that we can give to them. Then if they are aware of that, then yeah, hopefully they will open their doors to us and let us spend our money with them.

The post “All these things are quite easy to do, they just need somebody to sit down and just go through the website” appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , , , , , ,
[Top]

PHP Templating in Just PHP

With stuff like template literals in JavaScript and templating languages, like JSX, I’ve gotten used to wanting to write my HTML templates in one nice chunk and sprinkling in variables wherever I need them.

I had a situation where I needed to do that in “raw” PHP the other day, so I’m just documenting it here.

Say I have some data like…

$  title = "The Title"; $  desc  = "Some information about this thing blah blah."; $  img   = "/images/header.jpg";

But that data changes, or there might be multiple sets of it, and I want to be able to pass that data into a function and have it spit out some HTML. That way, it’s easy to change the template and have it affect everywhere that uses it.

I don’t want to sprinkle it into some HTML as a one-off. I’d rather have a function.

function echo_card($  title = "Default Title", $  desc = "Default Description", $  img = "/images/fallback.jpg") {    echo ""; }

Rather than string-interpolate a bunch of HTML together, PHP has the HEREDOC syntax that is a smidge like JavaScript’s template literals.

function echo_card($  title = "Default Title", $  desc = "Default Description", $  img = "/images/fallback.jpg") {    $  html = <<<"EOT"       <div class="card">          <img src="$  img" alt="">          <h2>$  title</h2>          <p>$  desc</p>       </div> EOT;     echo $  html; }

Now I can call this function to echo an HTML template with my data.

echo_card($  title, $  desc, $  img);

I found it a fairly comfortable way to work, without requiring any other libraries or anything.

The post PHP Templating in Just PHP appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Just Sharing My Gulpfile

Seemingly out of the blue, the Gulp processing I had set up for this site started to have a race condition. I’d run my watch command, change some CSS, and the processing would sometimes leave behind some extra files that were meant to be cleaned up during the processing. Like the cleanup tasks happened before the files landed in the file system (or something… I never really got to the bottom of it).

Nevermind about the specifics of that bug. I figured I’d go about solving it by upgrading things to use Gulp 4.x instead of 3.x, and running things in the built-in gulp.series command, which I thought would help (it did).

Getting Gulp 4.x going was a heck of a journey for me, involving me giving up for a year, then reigniting the struggle and ultimately getting it fixed. My trouble was that Gulp 4 requires a CLI version of 2.x while Gulp 3, for whatever reason, used a 3.x version. Essentially I needed to downgrade versions, but after trying a billion things to do that, nothing seemed to work, like there was a ghost version of CLI 3.x on my machine.

I’m sure savvier command-line folks could have sussed this out faster than me, but it turns out running command -v gulp will reveal the file path of where Gulp is installed which revealed /usr/local/share/npm/bin/gulp for me, and deleting it manually from there before re-installing the lastest version worked in getting me back down to 2.x.

Now that I could use Gulp 4.x, I re-wrote my gulpfile.js into smaller functions, each fairly isolated in responsibility. Much of this is pretty unique to my setup on this site, so it’s not meant to be some boilerplate for generic usage. I’m just publishing because it certainly would have been helpful for me to reference as I was creating it.

Things my particular Gulpfile does

  • Runs a web server (Browsersync) for style injection and auto-refreshing
  • Runs a file watcher (native Gulp feature) for running the right tasks on the right files and doing the above things
  • CSS processing
    • Sass > Autoprefixer > Minify
    • Break stylesheet cache from the templates (e.g. <link href="style.css?BREAK_CACHE">
    • Put style.css in the right place for a WordPress theme and clean up files only needed during processing
  • JavaScript processing
    • Babel > Concatenate > Minify
    • Break browser cache for the <script>s
    • Clean up unused files created in processing
  • SVG processing
    • Make an SVG sprite (a block of <symbol>s
    • Name it as a sprite.php file (so it can be PHP-included in a template) and put it somewhere specific
  • PHP processing
    • Update the Ajax call in the JavaScript to cache-bust when the ads change

Code dump!

const gulp = require("gulp"),   browserSync = require("browser-sync").create(),   sass = require("gulp-sass"),   postcss = require("gulp-postcss"),   autoprefixer = require("autoprefixer"),   cssnano = require("cssnano"),   del = require("del"),   babel = require("gulp-babel"),   minify = require("gulp-minify"),   concat = require("gulp-concat"),   rename = require("gulp-rename"),   replace = require("gulp-replace"),   svgSymbols = require("gulp-svg-symbols"),   svgmin = require("gulp-svgmin");  const paths = {   styles: {     src: ["./scss/*.scss", "./art-direction/*.scss"],     dest: "./css/"   },   scripts: {     src: ["./js/*.js", "./js/libs/*.js", "!./js/min/*.js"],     dest: "./js/min"   },   svg: {     src: "./icons/*.svg"   },   php: {     src: ["./*.php", "./ads/*.php", "./art-direction/*.php", "./parts/**/*.php"]   },   ads: {     src: "./ads/*.php"   } };  /* STYLES */ function doStyles(done) {   return gulp.series(style, moveMainStyle, deleteOldMainStyle, done => {     cacheBust("./header.php", "./");     done();   })(done); }  function style() {   return gulp     .src(paths.styles.src)     .pipe(sass())     .on("error", sass.logError)     .pipe(postcss([autoprefixer(), cssnano()]))     .pipe(gulp.dest(paths.styles.dest))     .pipe(browserSync.stream()); }  function moveMainStyle() {   return gulp.src("./css/style.css").pipe(gulp.dest("./")); }  function deleteOldMainStyle() {   return del("./css/style.css"); } /* END STYLES */  /* SCRIPTS */ function doScripts(done) {   return gulp.series(     preprocessJs,     concatJs,     minifyJs,     deleteArtifactJs,     reload,     done => {       cacheBust("./parts/footer-scripts.php", "./parts/");       done();     }   )(done); }  function preprocessJs() {   return gulp     .src(paths.scripts.src)     .pipe(       babel({         presets: ["@babel/env"],         plugins: ["@babel/plugin-proposal-class-properties"]       })     )     .pipe(gulp.dest("./js/babel/")); }  function concatJs() {   return gulp     .src([       "js/libs/jquery.lazy.js",       "js/libs/jquery.fitvids.js",       "js/libs/jquery.resizable.js",       "js/libs/prism.js",       "js/babel/highlighting-fixes.js",       "js/babel/global.js"     ])     .pipe(concat("global-concat.js"))     .pipe(gulp.dest("./js/concat/")); }  function minifyJs() {   return gulp     .src(["./js/babel/*.js", "./js/concat/*.js"])     .pipe(       minify({         ext: {           src: ".js",           min: ".min.js"         }       })     )     .pipe(gulp.dest(paths.scripts.dest)); }  function deleteArtifactJs() {   return del([     "./js/babel",     "./js/concat",     "./js/min/*.js",     "!./js/min/*.min.js"   ]); } /* END SCRIPTS */  /* SVG */ function doSvg() {   return gulp     .src(paths.svg.src)     .pipe(svgmin())     .pipe(       svgSymbols({         templates: ["default-svg"],         svgAttrs: {           width: 0,           height: 0,           display: "none"         }       })     )     .pipe(rename("icons/sprite/icons.php"))     .pipe(gulp.dest("./")); } /* END SVG */  /* GENERIC THINGS */ function cacheBust(src, dest) {   var cbString = new Date().getTime();   return gulp     .src(src)     .pipe(       replace(/cache_bust=\d+/g, function() {         return "cache_bust=" + cbString;       })     )     .pipe(gulp.dest(dest)); }  function reload(done) {   browserSync.reload();   done(); }  function watch() {   browserSync.init({     proxy: "csstricks.local"   });   gulp.watch(paths.styles.src, doStyles);   gulp.watch(paths.scripts.src, doScripts);   gulp.watch(paths.svg.src, doSvg);   gulp.watch(paths.php.src, reload);   gulp.watch(paths.ads.src, done => {     cacheBust("./js/global.js", "./js/");     done();   }); }  gulp.task("default", watch);

Problems / Questions

  • The worst part is that it doesn’t break cache very intelligently. When CSS changes, it breaks the cache on all stylesheets, not just the relevant ones.
  • I’d probably just inline SVG icons with PHP include()s in the future rather than deal with spriting.
  • The SVG processor breaks if the original SVGs have width and height attributes, which seems wrong.
  • Would gulp-changed be a speed boost? As in, only looking at files that have changed instead of all files? Or is it not necessary anymore?
  • Should I be restarting gulp on gulpfile.js changes?
  • Sure would be nice if all the libs I used were ES6-compatible so I could import stuff rather than having to manually concatenate.

Always so much more that can be done. Ideally, I’d just open-source this whole site, I just haven’t gotten there yet.

The post Just Sharing My Gulpfile appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]