Tag: Easier

A Trick That Makes Drawing SVG Lines Way Easier

When drawing lines with SVG, you often have a <path> element with a stroke. You set a stroke-dasharray that is as long as the path itself, as well as a stroke-offset that extends so far that you that it’s initially hidden. Then you animate the stroke-offset back to 0 so you can watch it “draw” the shape.

Figuring out the length of the path is the trick, which fortunately you can do in JavaScript by selecting the path and doing pathEl.getTotalLength(). It’ll probably be some weird decimal. A smidge unfortunate we can’t get that in CSS, but c’est la vie.

Here’s the trick!

You don’t have to measure the length of the path, because you can set it.

So you do like:

<path d="M66.039,133.545 ... " pathLength="1" />

That doesn’t do anything by itself (as far as I know). It’s not like that only draws part of the path — it still draws the whole thing like as if you did nothing, only now the “math” of the path length is based on a value of 1.

Now we can set the stroke-dasharray to 1, and animate the offset in CSS!

.path {   stroke-dasharray: 1;   stroke-dashoffset: 1;   animation: dash 5s linear alternate infinite; }  @keyframes dash {   from {     stroke-dashoffset: 1;   }   to {     stroke-dashoffset: 0;   } }

Which works:

See the Pen
Basic Example of SVG Line Drawing, Backward and Forward
by Chris Coyier (@chriscoyier)
on CodePen.

High five to Adam Haskell who emailed me about this a few months back.


Hey, speaking of SVG line drawing: Lemonade made a landing page for their 2019 charity that uses scroll-triggered SVG line drawing up and down the entire page. They did a behind-the-scenes look at it, which I always appreciate.

animated GIF of line drawing on Lemonade page - as page scrolls down a teddy bear shape is drawn

The post A Trick That Makes Drawing SVG Lines Way Easier appeared first on CSS-Tricks.

CSS-Tricks

, , , ,

Is Web Design Easier or Harder Than it was 10 Years Ago?

Is it harder or easier to build a website now than 10 years ago? Has the bar gone up or down? I don’t have any data for you, but I can shell out some loosey-goosey opinions.

HTML

HTML5 was the only big HTML change in the last decade, and it wasn’t particularly dramatic. It’s cool it’s the looser variant (instead of getting XHTML3 or something). More compatible this way. Maybe I’ll close my <br /> and maybe I <br> won’t. Having better semantic tags (e.g. <article>) is great. Input types are wonderful. But none of this pushes HTML to be significantly easier or harder.

Same.

CSS

CSS has gotten easier. We use way fewer “hacks” all the time. I can literally feel it. The CSS we write today feels so intentional and direct. 10 years ago I feel like every other element had some kind of weird hack on it, and today, almost none. If CSS feels any harder, I’d wager it’s because the sites we’re building are bigger and more complex so the styling systems for them need to be all the more robust and the dangers of getting it wrong more stark.

Easier.

JavaScript

I’m sure there are strong arguments to be made both ways here. The language, perhaps, with all its recent syntactic innovation… perhaps easier. But what JavaScript is being asked to do, and what we’re doing with it, is so astronomically larger that more difficulty comes along for the ride. It’s similar to CSS in that way, but even more pronounced since we’re not just doing what we were before on a new scale; we’re building entire interfaces with the language in a way we just weren’t before.

Harder.

Domains

I mention this one because it’s such a crucial step in any given person’s ability to go from zero to actually having a website.

I don’t think buying a domain name is any easier. Domain names are a commodity market, so the companies selling you them are selling you them for some other reason, meaning the incentive is very high for them to push other products on you. For someone entirely green, I can imagine the confusion is either high or they don’t know enough for the confusion to settle in yet. Do I buy it through this page builder thing? Do I have to buy it through this page builder thing? Do I need the WHOIS protection? Oh god, what even is DNS? I guess I do want email, right? Or is that like some weird special hosted email? Ughjakd. I’m gonna call it a wash. Nothing has made this any easier or harder in a decade.

Same.

Hosting

There is so much money in hosting it kind of blows my mind that we don’t see deeper innovation here. I might argue it’s a little easier these days. But commodity low-end hosting isn’t terribly different or being any more or less helpful than it was a decade ago. We’re still largely stringing together our own bespoke build and deployment processes like we were 10 years ago.

Large-scale stuff might have seen a lot of innovation, a la AWS, but nobody is going to argue that stuff is anywhere near easy.

The most innovation we’ve seen is from companies like Netlify and Zeit who are looking at the developer experience wholistically from helping you run things locally, to testing builds in staging, to immutable deploys. I’d love to see all hosting companies realize that every single one of their customers needs to get their code onto their platforms and they have a massive opportunity to help us do that directly.

Slightly easier.

How people actually do it

I like thinking about HTML, CSS, and JavaScript. But of course, precious few people actually start with those technologies to build actual websites from scratch. Really they end up being treated as underlying technologies you dabble in amongst a slew of other tech.

You can build a website from just an index.html file. I’d argue more people should. But people reach for more “complete” solutions and customize from there. I know I did. The first websites I ever created were WordPress because it was a whole website in a box (with its own struggles) and I customized it. People still do that today, probably more now than 10 years ago, and I don’t feel like it’s significantly easier or harder. Or they reach for something familiar. I made a one-page index.html site not long ago, only to have it picked up by another developer who turned it into a create-react-app site but otherwise changed nothing. They just didn’t know how to work on it without React.

Or they use WordPress.com, or Squarespace, or Wix, or Shopify, or BigCommerce, or you know what I mean. This isn’t about what people can do, it’s about what people do do. And for most people, these apps significantly lower the bar of creating a website.

So, for the average person, is it easier or harder to go from zero to having some kind of website?

Much easier.

Can people actually do it?

If we’re talking about creating from scratch, it’s interesting to see who feels like they even hold those keys anymore. The whole idea for this post came from a conversation I had with someone who has been a front-end developer and was asked to build a website by a friend. They declined because they didn’t know how.

Some part of that doesn’t surprise me. As I write, the world is awfully full of React-specific developers working on huge sites (partially due to boot camps, partially due to market demand). They understand that very specific ecosystem and are perfectly productive within it, but don’t have a wider understanding of how it all comes together to make the complete site.

Specialists are specialists!

Another part of me is surprised. You know an index.html file with “Hello, World!” in it can be a website, right? Even React devs are generally highly aware of create-react-app and how that scaffolds out a ready-to-rock site. Tools like Stackbit slap together a JAMstack site for you that can go anywhere. For developers, it seems to be going from zero to website is a heck of a lot easier these days.

Much easier.

The post Is Web Design Easier or Harder Than it was 10 Years Ago? appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Filtering Lists Dynamically With Vue on the Server Side is Easier Than You’d Think

I recently attended the ARTIFACT conference in Austin, TX, and was inspired by a few talks about accessibility through the lens of site performance. It became clear to me that there is this tendency to rely on big JavaScript frameworks to handle the work — like React, Vue, and Angular — but that can be overkill in some cases. That is, negatively affecting site performance, and thus accessibility. At the same time, these frameworks can make development easier and more efficient for developers. My big takeaway from the conference was to see how a fast, performant experience can be balanced with my own development process.

This was on my mind as I was building a list-filtering feature on a project a few days after the conference. Pretty standard stuff: I needed a list of posts and some category filtering. I was using CraftCMS for front-end routes and templating as well as some Vue components here and there for some added JavaScript juiciness. Not a full-on “single page app” but more like a sprinkle of Vue.

The typical way one might approach this is to:

  1. render the page with an empty div using Craft/Twig
  2. mount a Vue component to that div
  3. make an Ajax call from the Vue component to an API to gather the posts as JSON
  4. render the posts and tie in the filtering.

Since the posts are held as an array within Vue, dynamic list rendering is a pretty cut and dry task.

Simple. Done, right? Well… that extra Ajax request means the user is presented with no content on the initial load depending on the user’s network, which might take some time. We could add a loading indicator, but maybe we can do better?

Preferably, the posts are rendered on the initial page request from the CMS.

But how do we get the static HTML “hooked up” with Vue for the filtering?

After taking a step back to rethink the problem, I realized I could use v-if directives to achieve the same thing with some inline JavaScript from Twig (“in the loop”). Below, I’ll show how I went about it.

My original project used CraftCMS, but I’m going to do the demos below in WordPress. This is just a concept. It can be applied to CraftCMS/Twig or any other CMS/templating engine combo.

First we need a filtering UI. This will likely go above the start of the loop in an archive template.

<?php $  terms = get_terms( [   'taxonomy' => 'post_tag', // I used tags in this example, but any taxonomy would do   'hide_empty' => true,   'fields' => 'names' ] );  if(!empty($  terms)): ?>   <div>     Filter:      <ul class="filters">       <li class="filters__item"><button class="filters__button" :class="{'filters__button--active': tag === ''}" @click="tag = ''">All</button></li>       <?php foreach($  terms as $  term): ?>       <li class="filters__item">         <button class="filters__button" :class="{'filters__button--active': tag === '<?php echo $  term; ?>'}" @click="tag = '<?php echo $  term; ?>'"><?php echo $  term; ?></button>       </li>       <?php endforeach; ?>     </ul>     <p aria-live="polite">Showing posts tagged {{ tag ? tag : 'all' }}.</p>   </div> <?php endif; ?>

Following along with the code, we get some tags from WordPress with get_terms() and output them in a foreach loop. You’ll notice the button for each tag has some Vue directives we’ll use later.

We have our loop!

    <div class="posts">       <?php       // Start the Loop.       while ( have_posts() ) : the_post();              <article id="post-<?php the_ID(); ?>"           <?php post_class(); ?>           v-if='<?php echo json_encode(wp_get_post_tags(get_the_ID(),  ['fields' => 'names'])); ?>.includes(tag) || tag === ""'         >           <header class="entry-header">             <h2><?php the_title(); ?></h2>           </header>                <div class="entry-content">             <?php the_excerpt(); ?>           </div>         </article>            // End the loop.       endwhile; ?>     </div>

This is a pretty standard WordPress loop for posts. You’ll notice some Vue directives that make use of PHP outputting CMS content.

Aside from some styling, all that’s left is the Vue “app.” Are you ready for it? Here it is:

new Vue({   el: '#filterablePosts',   data: {     'tag': ''   } });

Yes, really, that’s all that’s needed in the JavaScript file to get this to work!

So, what’s going on here?

Well, instead of some JSON array of posts that gets fed into Vue, we output the posts on the initial page load with WordPress. The trick is to use PHP to output what’s needed in the Vue directives: v-if and :class.

What’s happening on the filter buttons is an onclick event handler (@click) that sets the Vue variable “tag” to the value of the WordPress post tag.

@click="tag = '<?php echo $  term; ?>'"

Also, if that Vue variable equals the value of the button (in the :class directive), it adds an active class for the button. This is just for styling.

:class="{'filters__button--active': tag === '<?php echo $  term; ?>'}"

For the list of articles, we conditionally display them based on the value of the Vue “tag” variable:

v-if='<?php echo json_encode(wp_get_post_tags(get_the_ID(),  ['fields' => 'names'])); ?>.includes(tag) || tag === ""'

The PHP function json_encode allows us to output an array of post tags as JavaScript, which means we can use .includes() to see if the Vue “tag” variable is in that array. We also want to show the article if no tag is selected.

Here it is put together using the Twenty Nineteen theme template archive.php as a base:

<?php get_header(); ?>   <section id="primary" class="content-area">     <main id="main" class="site-main">       <?php if ( have_posts() ) : ?>         <header class="page-header">           <?php the_archive_title( '<h1 class="page-title">', '</h1>' ); ?>         </header>          <div class="postArchive" id="filterablePosts">           <?php $  terms = get_terms( [               'taxonomy' => 'post_tag',               'hide_empty' => true,               'fields' => 'names'           ] );            if(!empty($  terms)): ?>             <div class="postArchive__filters">               Filter:                <ul class="postArchive__filterList filters">                 <li class="filters__item"><button class="filters__button" :class="{'filters__button--active': tag === ''}" @click="tag = ''" aria-controls="postArchive__posts">All</button></li>                    <?php foreach($  terms as $  term): ?>                   <li class="filters__item">                     <button class="filters__button" :class="{'filters__button--active': tag === '<?php echo $  term; ?>'}" @click="tag = '<?php echo $  term; ?>'" aria-controls="postArchive__posts"><?php echo $  term; ?></button>                   </li>                 <?php endforeach; ?>                  </ul>                  <p aria-live="polite">Showing {{ postCount }} posts tagged {{ tag ? tag : 'all' }}.</p>             </div>           <?php endif; ?>              <div class="postArchive__posts">               <?php               // Start the Loop.               while ( have_posts() ) : the_post(); ?>                 <article                   id="post-<?php the_ID(); ?>"                   <?php post_class(); ?>                   v-if='<?php echo json_encode(wp_get_post_tags(get_the_ID(), ['fields' => 'names'])); ?>.includes(tag) || tag === ""'                 >                   <header class="entry-header">                     <h2><?php the_title(); ?></h2>                   </header>                            <div class="entry-content">                       <?php the_excerpt(); ?>                   </div>                  </article>               <?php endwhile; // End the loop. ?>           </div>         </div>               <?php       // If no content, include the "No posts found" template.       else :         get_template_part( 'template-parts/content/content', 'none' );       endif; ?>     </main>   </section>  <?php get_footer();

Here’s a working example on CodePen

See the Pen
Dynamic List Filtering in Vue using Server-side data fetching
by Dan Brellis (@danbrellis)
on CodePen.

Bonus time!

You may have noticed that I added in an aria-live="polite" notifier below the filter button list to let assistive tech users know the content has changed.

<p aria-live="polite">Showing {{ postCount }} posts tagged {{ tag ? tag : 'all' }}.</p>

To get the postCount Vue variable, we add some extra JavaScript to our Vue component:

new Vue({   el: '#filterablePosts',   data: {     'tag': '',     'postCount': '' },   methods: {     getCount: function(){       let posts = this.$  el.getElementsByTagName('article');       return posts.length;   }   },   beforeMount: function(){     this.postCount = this.getCount();   },   updated: function(){     this.postCount = this.getCount();   } });</p>

The new method getCount is used to select the article elements in our component div and return the length. Before the Vue component mounts we get the count to add to our new Vue postCount variable. Then, when the component updates after the user selects a tag, we get the count again and update our variable.

CSS-Tricks

, , , , , , , ,
[Top]