> All in One 586: September 2024

Ads

Monday, September 30, 2024

Mostly Clear today!



With a high of F and a low of 37F. Currently, it's 55F and Fair outside.

Current wind speeds: 11 from the Northeast

Pollen: 0

Sunrise: September 30, 2024 at 06:47PM

Sunset: October 1, 2024 at 06:34AM

UV index: 0

Humidity: 32%

via https://ift.tt/YFneTMk

October 1, 2024 at 10:02AM

CSS Masonry & CSS Grid

An approach for creating masonry layouts in vanilla CSS is one of those “holy grail” aspirations. I actually tend to plop masonry and the classic “Holy Grail” layout in the same general era of web design. They’re different types of layouts, of course, but the Holy Grail was a done deal when we got CSS Grid.

That leaves masonry as perhaps the last standing layout from the CSS 3 era that is left without a baked-in solution. I might argue that masonry is no longer en vogue so to speak, but there clearly are use cases for packing items with varying sizes into columns based on available space. And masonry is still very much in the wild.

Steam is picking up on a formal solution. We even have a CSSWG draft specification for it. But notice how the draft breaks things out.

Table screenshot from the CSS specification with information on two competing syntaxes for CSS masonry.

Grid-integrated syntax? Grid-independent syntax? We’ve done gone and multiplied CSS!

That’s the context for this batch of notes. There are two competing proposals for CSS masonry at the time of writing and many opinions are flying around advocating one or the other. I have personal thoughts on it, but that’s not important. I’ll be happy with whatever the consensus happens to be. Both proposals have merits and come with potential challenges — it’s a matter of what you prioritize which, in this case, I believe is a choice between leveraging existing CSS layout features and the ergonomics of a fresh new approach.

But let’s get to some notes from discussions that are already happening to help get a clearer picture of things!

What is masonry layout?

Think of it like erecting a wall of stones or bricks.

Closeup of a slate gray stone wall.

The sizes of the bricks and stones don’t matter — the column (or less commonly a row) is the boss of sizing things. Pack as many stones or bricks in the nearest column and then those adapt to the column’s width. Or more concisely, we’re laying out unevenly sized items in a column such that there aren’t uneven gaps between them.

Examples, please?

Here’s perhaps the most widely seen example in a CodePen, courtesy of Dave DeSandro, using his Masonry.js tool:

I use this example because, if I remember correctly, Masonry.js was what stoked the masonry trend in, like 2010 or something. Dave implemented it on Beyoncé’s website which certainly gave masonry a highly visible profile. Sometimes you might hear masonry called a “Pinterest-style” layout because, well, that’s been the site’s signature design — perhaps even its brand — since day one.

Pinterest webpage with a masonry layout of inspirational quotes.

Here’s a faux example Jhey put together using flexbox:

Chris also rounded up a bunch of other workarounds in 2019 that get us somewhat there, under ideal conditions. But none of these are based on standardized approaches or features. I mean, columns and flexbox are specced but weren’t designed with masonry in mind. But with masonry having a long track record of being used, it most certainly deserves a place in the CSS specs.

There are two competing proposals

This isn’t exactly news. In fact, we can get earlier whiffs of this looking back to 2020. Rachel Andrew introduced the concept of making masonry a sub-feature of grid in a Smashing Magazine article.

Let’s fast-forward to 2022. We had an editor’s draft for CSS Masonry baked into the CSS Grid Layout Module 3 specification. Jenn Simmons motioned for the CSSWG to move it forward to be a first public working draft. Five days later, Chromium engineer Ian Kilpatrick raised two concerns about moving things forward as part of the CSS Grid Layout module, the first being related to sizing column tracks and grid’s layout algorithm:

Grid works by placing everything in the grid ahead of time, then sizing the rows/columns to fit the items. Masonry fundamentally doesn’t work this way as you need to size the rows/columns ahead of time – then place items within those rows/columns.

As a result the way the current specification re-uses the grid sizing logic leads to poor results when intrinsically sizing tracks, and if the grid is intrinsically-sized itself (e.g. if its within a grid/flex/table, etc).

Good point! Grid places grid items in advance ahead of sizing them to fit into the available space. Again, it’s the column’s size that bosses things around in masonry. It logically follows that we would need to declare masonry and configure the column track sizes in advance to place things according to space. The other concern concerns accessibility as far as visual and reading order.

That stopped Jenn’s motion for first public working draft status dead in its tracks in early 2023. If we fast-forward to July of this year, we get Ian’s points for an alternative path forward for masonry. That garnered support from all sorts of CSS heavyweights, including Rachel Andrew who authored the CSS Grid specification.

And, just a mere three weeks ago from today, fantasai shared a draft for an alternate proposal put together with Tab Atkins. This proposal, you’ll see, is specific to masonry as its own module.

And thus we have two competing proposals to solve masonry in CSS.

The case for merging masonry and grid

Rounding up comments from GitHub tickets and blog posts…

Flexbox is really designed for putting things into a line and distributing spare space. So that initial behaviour of putting all your things in a row is a great starting point for whatever you might want to do. It may be all you need to do. It’s not difficult as a teacher to then unpack how to add space inside or outside items, align them, or make it a column rather than a row. Step by step, from the defaults.

I want to be able to take the same approach with display: masonry.

[…]

We can’t do that as easily with grid, because of the pre-existing initial values. The good defaults for grid don’t work as well for masonry. Currently you’d need to:

  1. Add display: grid, to get a single column grid layout.
  2. Add grid-template-columns: <track-listing>, and at the moment there’s no way to auto-fill auto sized tracks so you’ll need to decide on how many. Using grid-template-columns: repeat(3, auto), for example.
  3. Add grid-template-rows: masonry.
  4. Want to define rows instead? Switch the masonry value to apply to  grid-template-columns and now define your rows. Once again, you have to explicitly define rows.
Rachel Andrew, Masonry and good defaults”

For what it’s worth, Rachel has been waving this flag since at least 2020. The ergonomics of display: masonry with default configurations that solve baseline functionality are clear and compelling. The default behavior oughta match the feature’s purpose and grid just ain’t a great set of default configurations to jump into a masonry layout. Rachel’s point is that teaching and learning grid to get to understand masonry behavior unnecessarily lumps two different formatting contexts into one, which is a certain path to confusion. I find it tough to refute this, as I also come at this from a teaching perspective. Seen this way, we might say that merging features is another lost entry point into front-end development.

In recent years, the two primary methods we’ve used to pull off masonry layouts are:

  • Flexbox for consistent row sizes. We adjust the flex-basis based on the item’s expected percentage of the total row width.
  • Grid for consistent column sizes. We set the row span based on the expected aspect ratio of the content, either server-side for imagery or client-side for dynamic content.

What I’ve personally observed is:

  • Neither feels more intuitive than the other as a starting point for masonry. So it feels a little itchy to single out Grid as a foundation.
  • While there is friction when teaching folks when to use a Flexbox versus a Grid, it’s a much bigger leap for contributors to wrap their heads around properties that significantly change behavior (such as flex-wrap or grid-auto-flow: dense).
Tyler Sticka, commenting on GitHub Issue #9041

It’s true! If I had to single out either flexbox or grid as the starting poit for masonry (and I doubt I would either way), I might lean flexbox purely for the default behavior of aligning flexible items in a column.

The syntax and semantics of the CSS that will drive masonry layout is a concern that is separate from the actual layout mechanics itself, which internally in implementation by user agents can still re-use parts of the existing mechanics for grids, including subgrids. For cases where masonry is nested inside grid, or grid inside masonry, the relationship between the two can be made explicit.

@jgotten, commenting on GitHub Issue #9041

Rachel again, this time speaking on behalf of the Chrome team:

There are two related reasons why we feel that masonry is better defined outside of grid layout—the potential of layout performance issues, and the fact that both masonry and grid have features that make sense in one layout method but not the other.

The case for keeping masonry separate from grid

One of the key benefits of integrating masonry into the grid layout (as in CASE 2) is the ability to leverage existing grid features, such as subgrids. Subgrids allow for cohesive designs among child elements within a grid, something highly desirable in many masonry layouts as well. Additionally, I believe that future enhancements to the grid layout will also be beneficial for masonry, making their integration even more valuable. By treating masonry as an extension of the grid layout, developers would be able to start using it immediately, without needing to learn a completely new system.

Kokomi, commenting on GitHub Issue #9041

It really would be a shame if keeping masonry separate from grid prevents masonry from being as powerful as it could be with access to grid’s feature set:

I think the arguments for a separate display: masonry focus too much on the potential simplicity at the expense of functionality. Excluding Grid’s powerful features would hinder developers who want or need more than basic layouts. Plus, introducing another display type could lead to confusion and fragmentation in the layout ecosystem.

Angel Ponce, commenting on GitHub Issue #9041

Rachel counters that, though.

I want express my strong support for adding masonry to display:grid. The fact that it gracefully degrades to a traditional grid is a huge benefit IMO. But also, masonry layout is already possible (with some constraints) in Grid layout today!

Naman Goel, Angel Ponce, commenting on GitHub Issue #9041

Chris mildly voiced interest in merging the two in 2020 before the debate got larger and more heated. Not exactly a ringing endorsement, but rather an acknowledgment that it could make sense:

I like the grid-template-rows: masonry; syntax because I think it clearly communicates: “You aren’t setting these rows. In fact, there aren’t even really rows at all anymore, we’ll take care of that.” Which I guess means there are no rows to inherit in subgrid, which also makes sense.

Where we at?

Collecting feedback. Rachel, Ian, and Tab published a joint call for folks like you and me to add our thoughts to the bag. That was eight days ago as of this writing. Not only is it a call to action, but it’s also an excellent overview of the two competing ideas and considerations for each one. You’ll want to add your feedback to GitHub Issue #9041.


CSS Masonry & CSS Grid originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/bFmycqK
via IFTTT

Sunday, September 29, 2024

Clear today!



With a high of F and a low of 54F. Currently, it's 65F and Clear outside.

Current wind speeds: 12 from the South

Pollen: 0

Sunrise: September 29, 2024 at 06:46PM

Sunset: September 30, 2024 at 06:36AM

UV index: 0

Humidity: 31%

via https://ift.tt/ub5WVA8

September 30, 2024 at 10:02AM

Saturday, September 28, 2024

Clear today!



With a high of F and a low of 53F. Currently, it's 63F and Clear outside.

Current wind speeds: 9 from the Southeast

Pollen: 0

Sunrise: September 28, 2024 at 06:45PM

Sunset: September 29, 2024 at 06:37AM

UV index: 0

Humidity: 31%

via https://ift.tt/1JYS4uz

September 29, 2024 at 10:02AM

Friday, September 27, 2024

Clear today!



With a high of F and a low of 50F. Currently, it's 64F and Clear outside.

Current wind speeds: 5 from the East

Pollen: 0

Sunrise: September 27, 2024 at 06:44PM

Sunset: September 28, 2024 at 06:39AM

UV index: 0

Humidity: 50%

via https://ift.tt/VJGjXwC

September 28, 2024 at 10:02AM

Slide Through Unlimited Dimensions With CSS Scroll Timelines

The creator of CSS has said he originally envisaged CSS as the main web technology to control behavior on web pages, with scripting as a fallback when things weren’t possible declaratively in CSS. The rationale for a CSS-first approach was that “scripting is programming and programming is hard.” Since introducing the :hover pseudo-class, CSS has been standardizing patterns developers create in JavaScript and “harvesting” them into CSS standards. When you think about it like that, it’s almost as if JavaScript is the hack and CSS is the official way.

We can, therefore, feel less dirty implementing script-like behavior with CSS, and we shouldn’t be surprised that something like the new scroll-timeline feature has appeared with pretty good browser support. Too many developers implemented clever parallax scrolling websites, which has summoned the CSS feature genie we cannot put back in its bottle. If you don’t want janky main-thread animations for your next parallax-scrolling website, you must now come to the dark side of hacking CSS. Just kidding, there is also a new JavaScript API for scroll-linked animations if imperative programming better fits your use case.

Migrating a JavaScript sample to CSS

It was satisfyingly simple to fork Chris Coyier’s pre-scroll-timeline example of a scroll-linked animation by replacing the CSS Chris was using to control the animations with just one line of CSS and completely deleting the JavaScript!

body, .progress, .cube {
  animation-timeline: scroll();
}

Using the scroll() function without parameters sets up an “anonymous scroll progress timeline” meaning the browser will base the animation on the nearest ancestor that can scroll vertically if our writing mode is English. Unfortunately, it seems we can only choose to animate based on scrolling along the x or y-axis of a particular element but not both, which would be useful. Being a function, we can pass parameters to scroll(), which provides more control over how we want scrolling to run our animation.

Experimenting with multiple dimensions

Even better is the scroll-scope property. Applying that to a container element means we can animate properties on any chosen ancestor element based on any scrollable element that has the same assigned scope. That got me thinking… Since CSS Houdini lets us register animation-friendly, inheritable properties in CSS, we can combine animations on the same element based on multiple scrollable areas on the page. That opens the door for interesting instructional design possibilities such as my experiment below.

Scrolling the horizontal narrative on the light green card rotates the 3D NES console horizontally and scrolling the vertical narrative on the dark green card rotates the NES console vertically. In my previous article, I noted that my past CSS hacks have always boiled down to hiding and showing finite possibilities using CSS. What interests me about this scroll-based experiment is the combinatorial explosion of combined vertical and horizontal rotations. Animation timelines provide an interactivity in pure CSS that hasn’t been possible in the past.

The implementation details are less important than the timeline-scope usage and the custom properties. We register two custom angle properties:

@property --my-y-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}

@property --my-x-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: -35deg;
}

Then, we “borrow” the NES 3D model from the samples in Julian Garner’s amazing CSS 3D modeling app. We update the .scene class for the 3D to base the rotation on our new variables like this:

.scene {
  transform: rotateY(var(--my-y-angle)) rotateX(var(--my-x-angle));
}

Next, we give the <body> element a timeline-scope with two custom-named scopes.

body {
  timeline-scope: --myScroller,--myScroller2; 
}

I haven’t seen anything officially documented about passing in multiple scopes, but it does work in Google Chrome and Edge. If it’s not a formally supported feature, I hope it will become part of the standard because it is ridiculously handy.

Next, we define the named timelines for the two scrollable cards and the axes we want to trigger our animations.

.card:first-child {
  scroll-timeline-axis: x;
  scroll-timeline-name: --myScroller;
}

.card:nth-child(2) {
  scroll-timeline-axis: y;
  scroll-timeline-name: --myScroller2;
}

And add the animations to the scene:

.scene {
  animation: rotateHorizontal,rotateVertical;
  animation-timeline: --myScroller,--myScroller2;
}

@keyframes rotateHorizontal {
  to {
    --my-y-angle: 360deg;
  }
}

@keyframes rotateVertical {
  to {
    --my-x-angle: 360deg;
  }
}

Since the 3D model inherits the x and y angles from the document body, scrolling the cards now rotates the model in combinations of vertical and horizontal angle changes.

User-controlled animations beyond scrollbars

When you think about it, this behavior isn’t just useful for scroll-driven animations. In the above experiment, we are using the scrollable areas more like sliders that control the properties of our 3D model. After getting it working, I went for a walk and was daydreaming about how cool it would be if actual range inputs could control animation timelines. Then I found out they can! At least in Chrome. Pure CSS CMS anyone?

While we’re commandeering 3D models from Julian Garner, let’s see if we can use range inputs to control his X-wing model.

It’s mind-boggling that we can achieve this with just CSS, and we could do it with an arbitrary number of properties. It doesn’t go far enough for me. I would love to see other input controls that can manipulate animation timelines. Imagine text fields progressing animations as you fill them out, or buttons able to play or reverse animations. The latter can be somewhat achieved by combining the :active pseudo-class with the animation-play-state property. But in my experience when you try to use that to animate multiple custom properties, the browser can get confused. By contrast, animation timelines have been implemented with this use case in mind and therefore work smoothly and exactly as I expected.

I’m not the only one who has noticed the potential for hacking this emergent CSS feature. Someone has already implemented this clever Doom clone by combining scroll-timeline with checkbox hacks. The problem I have is it still doesn’t go far enough. We have enough in Chrome to implement avatar builders using scrollbars and range inputs as game controls. I am excited to experiment with unpredictable, sophisticated experiences that are unprecedented in the era before the scroll-timeline feature. After all, if you had to explain the definition of a video game to an alien, wouldn’t you say it is just a hyper-interactive animation?


Slide Through Unlimited Dimensions With CSS Scroll Timelines originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/NdcJqPI
via IFTTT

Aggregating my distributed self

Miriam Suzanne’s in the middle of a redesign of her personal website. It began in August 2022. She’s made an entire series out of the work that’s worth your time, but I wanted to call out the fifth and latest installment because she presents a problem that I think we can all relate to:

But the walls got in my way. Instead of minimal renovation, I got just far enough to live with it and then started a brand new Eleventy repo.

The plan was to prototype […] and bring back well-formed solutions. To echo Dave Rupert, prototyping is useful. It’s easier to play with new ideas when you’re not carrying a decade of content and old code along with you.

But prototyping evolved into what I would call tinkering (complimentary). Maybe I mean procrastinating (also complimentary), but it’s a wandering process that also helps me better understand what I want from a website. I might not make visible progress over two years, but I start to form a point of view […]. Keeping things easy is always where things get complicated. And it brings me back to where my redesign started – a desire to clarify the information architecture. Not only for visitors, but for myself.

Don’t even tell me you’ve never been there! Jim Neilsen blogged along similar lines. You get a stroke of inspiration that’s the kernel of some idea that motivates you to start, you know, working on it. There’s no real plan, perhaps. The idea and inspiration are more than enough to get you going… that is until you hit a snag. And what I appreciate about Miriam’s post is that she’s calling out content as the snag. Well, not so much a snag as a return to the founding principle for the redesign: a refined content architecture.

  • Sometimes I do events where I speak, or teach a workshop, or perform. Events happen at a time and place.
  • Sometimes I create artifacts like a book or an album, a website, or specification. Artifacts often have a home URL. They might have a launch date, but they are not date-specific.
  • Some of my projects are other channels with their own feeds, their own events and artifacts.
  • Those channels are often maintained by an organization that I work with long-term. A band, a web agency, a performance company, etc.

These boundaries aren’t always clean. A post that remains relevant could be considered an artifact. Events can generate artifacts, and vice versa. An entire organization might exist to curate a single channel.

So, Miriam’s done poking at visual prototypes and ready to pour the filling into the pie crust. I relate with this having recently futzed with the content architecure of this site. I find it tough to start with a solidified design before I know what content is going into it. But I also find it tough to work with no shape at all. In my case, CSS-Tricks has a well-established design that’s evolved, mostly outside of me. I love the design but it’s an inherited one and I’m integrating content around it. Design is the constraint. If I had the luxury of stripping the building to the studs, I might take a different approach because then I could “paint” around it. Content would be the constraint.

It’s yet another version of the Chicken-Egg dilemma. I still think of the (capital-W) Web as a content medium at least in a UA style sense in that it’s the default. It’s more than that, of course. I’m a content designer at heart (and trade) but I’m hesitant to cry “content is king” which reminded me of something I wrote for an end-of-year series we did here answering the question: What is one thing people can do to make their website better? My answer: Read your website.

We start to see the power of content when we open up our understanding of what it is, what it does, and where it’s used. That might make content one of the most extensible problem-solving tools in your metaphorical shed—it makes sites more accessible, extracts Google-juicing superpowers, converts sales, and creates pathways for users to accomplish what they need to do.

And as far as prioritizing content or design, or…?

The two work hand-in-hand. I’d even go so far as to say that a lot of design is about enhancing what is communicated on a page. There is no upstaging one or the other. Think of content and design as supporting one another, where the sum of both creates a compelling call-to-action, long-form post, hero banner, and so on. We often think of patterns in a design system as a collection of components that are stitched together to create something new. Pairing content and design works much the same way.

I’d forgotten those words, so I appreciate Miriam giving me a reason to revisit them. We all need to be recalibrated every so often — swap out air filters, top off the fluids, and rotate the ol’ tires. And an old dog like me needs it a little more often. I spent a few more minutes in that end-of-year series and found a few other choice quotes about the content-design continuum that may serve as inspiration for you, me, or maybe even Miriam as she continues the process of aggragating her distributed self.

This sounds serious, but don’t worry — the site’s purpose is key. If you’re building a personal portfolio, go wild! However, if someone’s trying to file a tax return, whimsical loading animations aren’t likely to be well-received. On the other hand, an animated progress bar could be a nice touch while providing visual feedback on the user’s action.

Cassie Evans, “Empathetic Animation”

Remember, the web is an interactive platform — take advantage of that, where appropriate (less is more, accessibility is integral, and you need to know your audience). Whether that’s scrollytelling, captioned video, and heck, maybe for your audience, now’s the time to start looking into AR/VR! Who knows. Sometimes you just need to try stuff out and see what sticks. Just be careful. Experimentation is great, but we need to make sure we’re bringing everyone along for the ride.

Mel Choyce, “Show, Don’t Tell”

Your personal site is a statement of who you are and what you want to do. If you showcase your favorite type of work, you’ll get more requests for similar projects or jobs — feeding back into a virtuous cycle of doing more of what you love.

Amelia Wattenberger, “Exactly What You Want”

And one of my favorites:

But the prime reason to have a personal website is in the name: it is your personalhome on the web. Since its early days, the web has been about sharing information and freedom of expression. Personal websites still deliver on that promise. Nowhere else do you have that much freedom to create and share your work and to tell your personal story. It is your chance to show what you stand for, to be different, and to be specific. Your site lets you be uniquely you and it can be whatever you imagine it to be.

So if you have a personal site, make sure to put in the work and attention to make it truly yours. Make it personal. Fine-tune the typography, add a theme switcher, or incorporate other quirky little details that add personality. As Sarah Drasner writes, you can feel it if a site is done with care and excitement. Those are the sites that are a joy to visit and will be remembered.

Matthias Ott, “Make it Personal”

That last one has the added perk of reminding me how incredibly great Sarah Drasner is.


Aggregating my distributed self originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/LhVZATu
via IFTTT

Thursday, September 26, 2024

Mostly Clear today!



With a high of F and a low of 58F. Currently, it's 68F and Clear outside.

Current wind speeds: 11 from the South

Pollen: 0

Sunrise: September 26, 2024 at 06:43PM

Sunset: September 27, 2024 at 06:40AM

UV index: 0

Humidity: 42%

via https://ift.tt/zbfXwvB

September 27, 2024 at 10:02AM

Catching Up on the WordPress 🚫 WP Engine Sitch

Many of you — perhaps most of you — have been sitting on the sidelines while WordPress and WP Engine trade legal attacks on one another. It’s been widely covered as we watch it unfold in the open; ironically, in a sense.

These things can take twists and turns and it doesn’t help that this just so happens to be an emotionally charged topic in certain circles. WordPress is still the leading CMS after all these years and by a long shot. Many developers make their living in the WordPress ecosystem. All of those developers need hosting. WP Engine is still the leading WordPress-flavored host after many years. Many developers host their agencies there and use it to administrate their clients’ sites.

And I haven’t even gotten to the drama. That’s not really the point. The point is that there’s a bunch of heated words flying around and it can be difficult to know where they’re coming from, who they are aimed at, and most importantly, why they’re being said in the first place. So, I’m going to round up a few key voices contributing to the discussion for the sake of context and to help catch up.

Editor’s Note: Even though CSS-Tricks has no involvement with either company, I think it’s mentioning that Automattic was a looooooong time sponsor. This site was also once hosted by Flywheel, a company acquired by WP Engine before we moved to Cloudways following the DigitalOcean acquisition. Me? My personal site runs on WP Engine, but I’m not precious about it having only been there one year.

Prelude to a tweet

We had fair warning that something was coming up when WordPress co-founder Matt Mullenweg sent this out over X:

There’s the ammo: Don’t let private equity bully you into speaking up against the company you work for when its contributions to WordPress are on the slim side of things.

Private equity. Lack of participation in the WordPress community. Making a big public deal of it. Remember these things because this is one day before…

WordCamp US 2024

Matt spoke at WordCamp US (WCUS) 2024 in Portland, OR, last week. September 20 to be exact. Making big, bold statements at WCUS isn’t a new thing for Matt, as many of us still have “Learn JavaScript deeply” tattooed on the brain from 2016.

Matt’s statements this year were less inspirational (instructional?) as they took direct aim at WP Engine as part of a presentation on the merits of open-source collaboration. You can watch and listen to where the first jab was thrown roughly around the 10:05 marker of the recording.

Let’s break down the deal. Matt begins by comparing the open-source contributions to WordPress from his company, Automattic, to those of WP Engine. These things are tracked on WordPress.org as part of a campaign called “Five for the Future” that’s designed to give organizations an influential seat at the table to form the future of WordPress in exchange for open-source contributions back to the WordPress project. Automattic has a page totaling its contributions. So does WP Engine.

Before Matt reveals the numbers, he goes out of his way to call out the fact that both Automattic and WP Engine are large players in the neighborhood of $500 million dollars. That’s the setup for Matt to demonstrate how relatively little WP Engine contributes to WordPress against Matt’s own company. Granted, I neither have absolutely no clue what factors into contributions, nor how the pages are administrated or updated. But here’s what they show…

Automattic 116 contributors with 3,968 hours per week. WP Engine 11 contributors with 40 hours per week.

Quite the discrepancy! I’d imagine Automattic dwarfs every other company that’s pledged to the campaign. Maybe it would be better to compare the contributions of another non-Automattic pledge that has a fairly strong reputation for participating in WordPress community. 10up is one of the companies that comes straight to my mind and they are showing up for 191 hours per week, or roughly five times WP Engine’s reported time. I get conflicting info on 10up’s revenue, valuation, and size, so maybe the comparison isn’t fair. Or maybe it is fair because 10up is certainly smaller than WP Engine, and no estimate I saw was even close to the $500 million mark.

Whatever the case, bottom line: Matt calls out WP Engine for its lack of effort on a very public stage — maybe the largest — in WordPress Land. He doesn’t stop there, going on to namecheck Silver Lake, a ginormous private equity firm bankrolling the company. The insinuation is clear: there’s plenty of money and resources, so pony up.

That’s bad enough for attendees to raise eyebrows, but it doesn’t end there. Matt encourages users and developers alike to vote with money by not purchasing hosting from WP Engine (11:31) and seems to suggest (23:05) that he’ll provide financial support to any WP Engine employees who lose their jobs from speaking up against their employer.

I think I can get behind the general idea that some companies need a little prodding to pull their weight to something like the Five for the Future campaign. Encouraging developers to pull their projects from a company and employees to jeopardize their careers? Eek.

“WP Engine is not WordPress”

This is when I believe things got noisy. It’s one thing to strongarm a company (or its investors) into doing more for the community. But in a post on his personal blog the day after WCUS, Matt ups the ante alleging that “WP Engine isn’t WordPress.” You’d think this is part of the tough-guy stance he had from the stage, but his argument is much different in this post. Notice it’s about how WP Engine uses WordPress in its business rather than how much the company invests in it:

WordPress is a content management system, and the content is sacred. Every change you make to every page, every post, is tracked in a revision system, just like the Wikipedia. This means if you make a mistake, you can always undo it. It also means if you’re trying to figure out why something is on a page, you can see precisely the history and edits that led to it. These revisions are stored in our database. This is very important, it’s at the core of the user promise of protecting your data, and it’s why WordPress is architected and designed to never lose anything.

WP Engine turns this off. They disable revisions because it costs them more money to store the history of the changes in the database, and they don’t want to spend that to protect your content. It strikes to the very heart of what WordPress does, and they shatter it, the integrity of your content.

OK, gloves off. This is more personal. It’s no longer about community contributions but community trust and how WP Engine erodes trust by preventing WordPress users from accessing core WordPress features for their own profit.

Required reading

That’s where I’d like to end this, at least for now. Several days have elapsed since Matt’s blog post and there are many, many more words flying around from him, community members, other companies, and maybe even your Great Aunt. But if you’re looking for more signal than noise, I’ve rounded up a few choice selections that I feel contribute to the (heated) discussion.

Reddit: Matt Mullenweg needs to step down from WordPress.org leadership ASAP

Matt responds to the requisite calls for him to step down, starting with:

To be very clear, I was 100% cordial and polite to everyone at the booth, my message was:

* I know this isn’t about them, it’s happening several levels above, it’s even above their CEO, it’s coming from their owner, Silver Lake and particularly their board member Lee Wittlinger.

* Several people inside WP Engine have been anonymously leaking information to me about their bad behavior, and I wanted to let them know if they were caught or faced retaliation that I would support them in every way possible, including covering their salaries until they found a new job.

* That *if* we had to take down the WP Engine booth and ban WP Engine that evening, my colleague Chloé could print them all new personal badges if they still wanted to attend the conference personally, as they are community members, not just their company.

This was delivered calmly, and they said thank you, and their head of comms, Lauren Cox, who was there asked that they have time to regroup and discuss.

Automattic’s Actionable Misconduct Directed to WP Engine

WP Engine issues a cease and desist letter designed to stop Matt from disparaging them publicly. But hold up, because there’s another juicy claim in there:

In the days leading up to Mr. Mullenweg’s September 20th keynote address at the WordCamp US Convention, Automattic suddenly began demanding that WP Engine pay Automattic large sums of money, and if it didn’t, Automattic would wage a war against WP Engine.

And yes, they did issue it from their own site’s /wp-content directory. That’s easy to lose, so I’ve downloaded it to link it for posterity.

Open Source, Trademarks, and WP Engine

Just today, Matt published a cease and desist letter to the Auttomatic blog where he alleges that WP Engine’s commercial modifications to WordPress Core violate the WordPress trademark. Again, this has become about licensing, not contributions:

WP Engine’s business model is based on extensive and unauthorized use of these trademarks in ways that mislead consumers into believing that WP Engine is synonymous with WordPress. It’s not.

This is trademark abuse, not fair competition.

This is no longer WordPress vs. WP Engine. It’s more like Automattic vs. WP Engine. But with Matt’s name quite literally in the name Automattic, let’s be real and call this Matt Mullenweg vs. WP Engine.

WP Tavern coverage

WP Tavern is still the closest thing we have to an official WordPress news outlet. Nevermind that it’s funded and hired by Automattic (among others). I respect it, though I honestly have been less attentive to it since the team turned earlier this year. It’s still a great spot to catch up on the post-event coverage:

There’s another more recent WP Tavern article I want to call out because it’s a huge development in this saga…

WP Engine Banned from Using WordPress.org Resources

Dang. This is the point of no return. It not only affects WP Engine proper, but the Flywheel hosting it also owns.

WordPress.org has blocked WP Engine customers from updating and installing plugins and themes via WP Admin. 

I was able to update plugins on my site as recently as yesterday, but let’s see as of this morning.

Aww, biscuits.

Maybe I can still see details about my installed plugins…

Double biscuits!

This is a bad, bad situatiuon. I have thoughts about it and neither side looks good. Using real people with no dog in the fight to make a point is never gonna be a good look. Then again, both sides have valid points and I can see where they’re coming from. I just hate to see it come to a head like this.


Catching Up on the WordPress 🚫 WP Engine Sitch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/F0E59Lb
via IFTTT

BCD Watch

A new tool from Eric Meyer, Brian Kardell, and Stephanie Stimac backed with Igalia’s support. Brian announced it on his blog, as did Eric, describing it like this:

What BCD Watch does is, it grabs releases of the Browser Compatibility Data (BCD) repository that underpins the support tables on MDN and services like caniuse.com.  It then analyzes what’s changed since the previous release.

Every Monday, BCD Watch produces two reports. The Weekly Changes Report lists all the changes to BCD that happened in the previous week — what’s been added, removed, or renamed in the whole of BCD.  It also tells you which of the Big Three browsers newly support (or dropped support for) each listed feature, along with a progress bar showing how close the feature is to attaining Baseline status.

Browser support data is at MDN. There’s also plenty at Caniuse.com. The two share data, in fact, though not all of it. We now have Baseline, which is also cited in MDN and Caniuse alike. It’s nice to see an effort at cracking a central spot for all this — organized by date, no less.

Oh, and hey, there’s a feed. Even better.

You can also poke at its repo. Thanks a bunch, Eric, Brian, Stephanie, and Igalia! This is super helpful and already part of my toolkit.


BCD Watch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/3uXNBlk
via IFTTT

Wednesday, September 25, 2024

Clear today!



With a high of F and a low of 50F. Currently, it's 63F and Clear outside.

Current wind speeds: 11 from the South

Pollen: 0

Sunrise: September 25, 2024 at 06:42PM

Sunset: September 26, 2024 at 06:42AM

UV index: 0

Humidity: 44%

via https://ift.tt/uRVXKg5

September 26, 2024 at 10:02AM

How to Make a “Scroll to Select” Form Control

The <select> element is a fairly straightforward concept: focus on it to reveal a set of <option>s that can be selected as the input’s value. That’s a great pattern and I’m not suggesting we change it. That said, I do enjoy poking at things and found an interesting way to turn a <select> into a dial of sorts — where options are selected by scrolling them into position, not totally unlike a combination lock or iOS date pickers. Anyone who’s expanded a <select> for selecting a country knows how painfully long lists can be and this could be one way to prevent that.

Here’s what I’m talking about:

It’s fairly common knowledge that styling <select> in CSS is not the easiest thing in the world. But here’s the trick: we’re not working with <select> at all. No, we’re not going to do anything like building our own <select> by jamming a bunch of JavaScript into a <div>. We’re still working with semantic form controls, only it’s radio buttons.

<section class=scroll-container>
  <label for="madrid" class="scroll-item">
      Madrid 
      <abbr>MAD</abbr>
      <input id="madrid" type="radio" name="items">
  </label>
  <label for="malta" class="scroll-item">
      Malta 
      <abbr>MLA</abbr>
      <input id="malta" type="radio" name="items">
  </label>
  <!-- etc. -->
</section>

What we need is to style the list of selectable controls where we are capable of managing their sizes and spacing in CSS. I’ve gone with a group of labels with nested radio boxes as far as the markup goes. The exact styling is totally up to you, of course, but you can use these base styles I wrote up if you want a starting point.

.scroll-container {
  /* SIZING & LAYOUT */
  --itemHeight: 60px;
  --itemGap: 10px;
  --containerHeight: calc((var(--itemHeight) * 7) + (var(--itemGap) * 6));

  width: 400px; 
  height: var(--containerHeight);
  align-items: center;
  row-gap: var(--itemGap);
  border-radius: 4px;

  /* PAINT */
  --topBit: calc((var(--containerHeight) - var(--itemHeight))/2);
  --footBit: calc((var(--containerHeight) + var(--itemHeight))/2);

  background: linear-gradient(
    rgb(254 251 240), 
    rgb(254 251 240) var(--topBit), 
    rgb(229 50 34 / .5) var(--topBit), 
    rgb(229 50 34 / .5) var(--footBit), 
    rgb(254 251 240) 
    var(--footBit));
  box-shadow: 0 0 10px #eee;
}

A couple of details on this:

  • --itemHeight is the height of each item in the list.
  • --itemGap is meant to be the space between two items.
  • The --containerHeight variable is the .scroll-container’s height. It’s the sum of the item sizes and the gaps between them, ensuring that we display, at maximum, seven items at once. (An odd number of items gives us a nice balance where the selected item is directly in the vertical center of the list). 
  • The background is a striped gradient that highlights the middle area, i.e., the location of the currently selected item. 
  •  The --topBit and –-footBit variables are color stops that visually paint in the middle area (which is orange in the demo) to represent the currently selected item.

I’ll arrange the controls in a vertical column with flexbox declared on the .scroll-container:

.scroll-container {
  display: flex; 
  flex-direction: column;
  /* rest of styles */
}

With layout work done, we can focus on the scrolling part of this. If you haven’t worked with CSS Scroll Snapping before, it’s a convenient way to direct a container’s scrolling behavior. For example, we can tell the .scroll-container that we want to enable scrolling in the vertical direction. That way, it’s possible to scroll to the rest of the items that are not in view.

.scroll-container {
  overflow-y: scroll;
  /* rest of styles */
}

Next, we reach for the scroll-snap-style property that can be used to tell the .scroll-container that we want scrolling to stop on an item — not near an item, but directly on it.

.scroll-container {
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  /* rest of styles */
}

Now items “snap” onto an item instead of allowing a scroll to end wherever it wants. One more little detail I like to include is overscroll-behavior, specifically along the y-axis as far as this demo goes:

.scroll-container {
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  overscroll-behavior-y: none;
  /* rest of styles */
}

overscroll-behavior-y: none isn’t required to make this work, but when someone scrolls through the .scroll-container (along the y-axis), scrolling stops once the boundary is reached, and any further continued scrolling action will not trigger scrolling in any nearby scroll containers. Just a form of defensive CSS.

Time to move to the items inside the scroll container. But before we go there, here are some base styles for the items themselves that you can use as a starting point:

.scroll-item {
  /* SIZING & LAYOUT */
  width: 90%;
  box-sizing: border-box;
  padding-inline: 20px;
  border-radius: inherit; 

  /* PAINT & FONT */
  background: linear-gradient(to right, rgb(242 194 66), rgb(235 122 51));
  box-shadow: 0 0 4px rgb(235 122 51);
  font: 16pt/var(--itemHeight) system-ui;
  color: #fff;

  input { appearance: none; } 
  abbr { float: right; } /* The airport code */
}

As I mentioned earlier, the --itemHeight variable is setting as the size of each item and we’re declaring it on the flex property — flex: 0 0 var(--itemHeight). Margin is added before and after the first and last items, respectively, so that every item can reach the middle of the container through scrolling. 

The scroll-snap-align property is there to give the .scroll-container a snap point for the items. A center alignment, for instance, snaps an item’s center (vertical center, in this case) with the .scroll-container‘s center (vertical center as well). Since the items are meant to be selected through scrolling alone pointer-events: none is added to prevent selection from clicks.

One last little styling detail is to set a new background on an item when it is in a :checked state:

.scroll-item {
  /* Same styles as before */

  /* If input="radio" is :checked */
  &:has(:checked) {
    background: rgb(229 50 34);
  }
}

But wait! You’re probably wondering how in the world an item can be :checked when we’re removing pointer-events. Good question! We’re all finished with styling, so let’s move on to figuring some way to “select” an item purely through scrolling. In other words, whatever item scrolls into view and “snaps” into the container’s vertical center needs to behave like a typical form control selection. Yes, we’ll need JavaScript for that. 

let observer = new IntersectionObserver(entries => { 
  entries.forEach(entry => {
    with(entry) if(isIntersecting) target.children[1].checked = true;
  });
}, { 
  root: document.querySelector(`.scroll-container`), rootMargin: `-51% 0px -49% 0px`
});

document.querySelectorAll(`.scroll-item`).forEach(item => observer.observe(item));

The IntersectionObserver object is used to monitor (or “observe”) if and when an element (called a target) crosses through (or “intersects”) another element. That other element could be the viewport itself, but in this case, we’re observing the .scroll-container for when a .scroll-item intersects it. We’ve established the observed boundary with rootMargin:"-51% 0px -49% 0px".  

A callback function is executed when that happens, and we can use that to apply changes to the target element, which is the currently selected .scroll-item. In our case, we want to select a .scroll-item that is at the halfway mark in the .scroll-containertarget.children[1].checked = true.

That completes the code. Now, as we scroll through the items, whichever one snaps into the center position is the selected item. Here’s a look at the final demo again:

Let’s say that, instead of selecting an item that snaps into the .scroll-container‘s vertical center, the selection point we need to watch is the top of the container. No worries! All we do is update the scroll-snap-align property value from center to start in the CSS and remove the :first-of-type‘s top margin. From there, it’s only a matter of updating the scroll container’s background gradient so that the color stops highlight the top instead of the center. Like this:

And if one of the items has to be pre-selected when the page loads, we can get its position in JavaScript (getBoundingClientRect()) and use the scrollTo() method to scroll the container to where that specific item’s position is at the point of selection (which we’ll say is the center in keeping with our original demo). We’ll append a .selected class on that .scroll-item

<section class="scroll-container">
  <!-- more items -->
  <label class="scroll-items selected">
    2024
    <input type=radio name=items />
  </label>

  <!-- more items -->
</section>

Let’s select the .selected class, get its dimensions, and automatically scroll to it on page load:

let selected_item = (document.querySelector(".selected")).getBoundingClientRect();
let scroll_container = document.querySelector(".scroll-container");
scroll_container.scrollTo(0, selected_item.top - scroll_container.offsetHeight - selected_item.height);

It’s a little tough to demo this in a typical CodePen embed, so here’s a live demo in a GitHub Page (source code). I’ll drop a video in as well:

That’s it! You can build up this control or use it as a starting point to experiment with different layouts, styles, animations, and such. It’s important the UX clearly conveys to the users how the selection is done and which item is currently selected. And if I was doing this in a production environment, I’d want to make sure there’s a good fallback experience for when JavaScript might be unavailable and that my markup performs well on a screen reader.

References and further reading


How to Make a “Scroll to Select” Form Control originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/GBPDqX5
via IFTTT

Tuesday, September 24, 2024

Clear today!



With a high of F and a low of 49F. Currently, it's 57F and Clear outside.

Current wind speeds: 3 from the Southwest

Pollen: 0

Sunrise: September 24, 2024 at 06:41PM

Sunset: September 25, 2024 at 06:44AM

UV index: 0

Humidity: 52%

via https://ift.tt/IcjVing

September 25, 2024 at 10:02AM

Color Mixing With Animation Composition

Mixing colors in CSS is pretty much a solved deal, thanks to the more recent color-mix() function as it gains support. Pass in two color values — any two color values at all — and optionally set the proportions.

background-color: color-mix(#000 30%, #fff 70%);

We also have the relative color syntax that can manipulate colors from one color space to another and modify them from there. The preeminent use case being a way to add opacity to color values that don’t support it, such as named colors.

background-color: hsl(from black h s l); /* hsl(0 0% 0%) */
background-color: hsl(from black h s l / 50%); /* hsl(0 0% 0% / 50%) */

We can get hacky and overlay one opaque element with another, I suppose.

Same general idea maybe, but with mix-blend-mode?

Another roundabout way of getting there is something I saw this morning when looking over the updates that Ryan added to the animation property in the Almanac. Now, we all know that animation is shorthand for about a gajillion other properties (the order of which always eludes me). One of those is animation-composition and it’s used to… well, Ryan nails the explanation:

Defining a property in CSS also sets what is considered the underlying value of the property. By default, keyframe animations will ignore the underlying value, as they only consider the effect values defined within the animation. Keyframes create a stack of effect values, which determines the order in which the animation renders to the browser. Composite operations are how CSS handles the underlying effect combined with the keyframe effect value.

Manuel Matuzović and Robin Rendle also have excellent ways of explaining the property, the former of which sparked us to update the Almanac.

OK! We have three values supported by animation-composition to replace the underlying property value in favor of the effect value defined in keyframes, add to them, or accumulate for combining multiple values. The add value is what’s interesting to us because… oh gosh, let’s just let Ryan take it:

[I]nstead of replacing an underlying background-color property value with the keyframe’s effect value, the color type values are combined, creating new colors.

A-ha! The example goes like this:

See that? The add value blends the two colors as one transitions to the other. Notice, too, how much smoother that transition is than the replace value, although we wind up with a completely new color at the 100% mark rather than the color we declared in the keyframes. What if we pause the animation at some arbitrary point? Can we extract a new color value from it?

Ryan made this so that hovering on the elements pauses the animation. If we crack open DevTools and force the :hover pseudo on the element, maybe we can head over to the Computed tab to get the new color value.

DevTools showing an RGB color value for the demo's background color property equal to rgb(241, 212, 255).

Interestingly, we get some RGB conversions in there. Probably because updating color channels is easier than converting one hex to another? Browsers do smart stuff.

Now I want to go update my old color interpolation demo…

Hmm, not any different to my untrained eye. Maybe that’s only because we’re changing the HSL’s hue channel and it’s super subtle. Whatever the case, animation-composition can produce new computed color values. What you need those for and what you’d do with them? I dunno, but go wild.


Color Mixing With Animation Composition originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/JlysZVx
via IFTTT

Monday, September 23, 2024

Mostly Cloudy today!



With a high of F and a low of 51F. Currently, it's 60F and Fair outside.

Current wind speeds: 9 from the Southwest

Pollen: 0

Sunrise: September 23, 2024 at 06:40PM

Sunset: September 24, 2024 at 06:45AM

UV index: 0

Humidity: 52%

via https://ift.tt/sJzt9aT

September 24, 2024 at 10:02AM

The selectmenu Element is No More…Long Live select!

I was looking over an older article Patrick Brosset penned for us introducing <selectmenu>, a new proposal at the time for a more style-able cousin to <select>. From there, I clicked the linked-up <selectmenu> explainer and got… this:

OK, link rot is a thing and happens all the time. Perhaps the site needs a little URL designing? But no, it’s not that at all. I searched a bit and found Jared White’s post saying that <selectmenu> is no more, which came by way of Una’s post over at the Chrome Developer Blog seeking feedback on a “customizable select”. And Adam Argyle’s got a wonderful demo dedicated to it, no surprise there.

I’m only sharing the links for now but plan to spend some time with it and jot down notes on Open UI’s new page for the Customizable <select>. I enjoyed looking at the boilerplate from Adam’s demo as a first glance:

select {
  &, &::picker(select) {
    appearance: base-select;
  }
  
  &::picker(select) {
    transition: 
      display allow-discrete 1s, 
      opacity 1s, 
      overlay 1s allow-discrete
    ;
  }
  
  &:not(:open)::picker(select) {
    opacity: 0;
  }
  
  &:open::picker(select) {
    opacity: 1;
    
    @starting-style {
      opacity: 0;
    }
  }
}

I see the ::picker(select) there that’s driving all of it. If I sneak a peek at Una’s post, I see that there are more ways to select different <select> parts, including:

  • <selectedoption> (the current selection)
  • <option> (which now accepts HTML in between the tags!)
    • option::before
    • option:checked (a little confusion here with the selected option)
  • <button> (the little chevron arrow marker thingy)

So, perhaps Chrome is more of a fan of extending the native <select> with additional CSS features for selecting the existing parts rather than moving forward with a completely new element. That’s cool, as one of Una’s demos shows how we still get the default <select> behavior even if a browser does not support the new selectors.


The selectmenu Element is No More…Long Live select! originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/KznRop3
via IFTTT

Mostly Clear today!

With a high of F and a low of 15F. Currently, it's 14F and Clear outside. Current wind speeds: 13 from the Southwest Pollen: 0 S...