Tag: Event

Some Things I Took Away From An Event Apart 2022 in Denver

An Event Apart 2022 Denver wrapped up yesterday. And while I was unable to make it to all three days this time, I did catch yesterday’s action — and it was awesome. I’m not very social or outgoing, but this was the first conference I’ve been to in at least a couple of years, and seeing folks in person was incredibly refreshing.

I took notes, of course! I thought I’d post ’em here because sharing is caring. At least, that’s what my six-year-old told me the other day when asking for a bite of my dessert last night.

I’ll break this down by speaker. Fair warning: I’m all about handwritten notes and a pretty visual fella, so my notes tend to be less… structured than most. And these notes are just things that stood out to me. They may not even be the presenter’s main idea, but they caught my attention!

Chris Coyier: Websites Are Good Now

High-resolution

Chris has given this talk before (we linked it up just last week), but this time expanded it substantially, particularly with details on container relative units which, when combined with clamp(), make for more accurate responsiveness because the values are relative to the container rather than the viewport. So, you know how we often use viewport width (vh) units for fluid type?

font-size: clamp(1rem, 1rem + 2vw, 2rem);

Well, we can use a container relative unit like container query inline-size (cqi) instead, where 1cqi is equal to 1% of the container’s inline size (here’s the draft spec on that):

font-size: clamp(1rem, 1rem + 1cqi, 2rem);

Chris also talked quite a bit about the performance benefits of hosting at the edge. Probably no surprise because he’s written about it here more than a few times. Even as someone who had already read those articles, I honestly didn’t realize the complete concept of computing at the edge.

The idea is deceptively simple: global CDNs can serve assets quickly because they host them geographically close to the user. That’s pretty standard practice for serving raster images. But it has extended to static files, such as the same HTML, CSS, and JavaScript files that power a site — build them in advance and serve the already compiled and optimized files from the speedy global CDN. That’s the whole Jamstack concept!

But what if you still require a server response from it? That ain’t very edge-y, is it? Well, now we have handlers capable of running on a single URL fetching data in advance, and injecting it ahead of render — directly from the CDN. Sure, there’s extra work happening in the background. Still, the fact that we can dynamically fetch data, inject it, pre-build it, serve it statically on demand, and have it run geographically closer to the user makes this blazingly fast.

Tolu Adegbite: How to Win at ARIA and Influence Web Accessibility

High resolution

Good gosh was this an excellent presentation! Tolu Adegbite schooled me so hard on WAI-ARIA that I had a hard time jotting down all the gems she shared — Roles! States! Labeling! Descriptions! Everything was extraordinarily well-covered, and stuff that I know I’ll be coming back to time and again.

But one specific thing that caught my attention is the accessibility of inline SVG. Even though SVG is related to other types of design assets, the fact that it is markup at the end of the day sets it apart because it isn’t always identified as an image.

<!-- Image tag is easily recognized as an image --> <img src="cat.svg" alt="An illustrated brown and white tabby kitten looking lovingly into the camera.">  <!-- Could be an image, maybe not? --> <svg viewBox="0 0 100 100">   <!-- etc. --> </svg>

Assistive tech is more likely to read inline SVG as an image by giving it a proper accessible role and label:

<svg    role="image"    aria-label="An illustrated brown and white tabby kitten looking lovingly into the camera."   viewBox="0 0 100 100" >   <!-- etc. --> </svg>

Miriam Suzanne: Cascading Layers of !mportance

High resolution

Hey, another CSS-Tricks alum! Miriam has been spending a bunch of time and effort on the Cascade Layers specification. She also wrote a big ol’ guide about them here at CSS-Tricks and talked about them at An Event Apart.

What has stuck with me most is how big of a mental shift this is. The concept isn’t complicated, per se. Declare @layer at the top of the CSS document, list the layers in order of specificity, then write styles in those layers. But for an old dinosaur like me who has been writing CSS for a while, I’m going to have to get used to the fact that Cascade Layers make it possible for a simple class selector to beat out something that usually wields a higher specificity, like an ID.

🤯

Miriam also reminded the room that Cascade Layers are just one tool we have in our specificity-managing toolbelt, in addition to selectors that affect specificity (e.g., :is(), :where(), and :has()).

Oh, and this is an interesting tidbit. As Miriam walked through the history of specificity in CSS, she recalled that !important was initially designed as a tool for users to override user agent and author styles. But somewhere down the line, we’ve adopted it to force author styles to the top. Cascade Layers help remove the excuse need to use !important because they provide us the power to “prioritize layers and protect inheritance.”

That is beautifully said, Miriam!

Dave Rupert: Unblocking Your Accessibility Backlog

High resolution

Imagine waking up one day to hundreds of GitHub notifications about reported issues on your site. Where do you even begin? Maybe close your laptop and get a root canal instead? That happened to Dave! An automated accessibility audit returned a massive pile of errors and assigned them as tickets for Dave to fix.

But he noticed a pattern after taking an Excel spreadsheet of those issues, moving them to Notion for a better view, hiding unnecessary columns, categorizing everything, and displaying the results in logical groups. Many of the reported issues were the same issue repeated on multiple pages. Just because an automated test returns a handful of errors doesn’t mean they’re all unique. That reduced a nice chunk of the tickets.

He went on to show how — with relatively little effort — the backlog of issues dwindled by nearly 50%.

There’s a lot to glean there, especially regarding how we process and organize our work. The biggest takeaway for me is when Dave said we have to emphasize individuals and interactions over processes and tools. Tools like the one scanning for accessibility errors are helpful, but they might not tell the entire story. Rather than take them at their words, it’s worth asking questions and gaining more context before diving into the mess.

As a bonus, reorganizing the issues in Notion allowed Dave to group issues in a way that clearly shows which impairments his product was actively discriminating against, giving him greater empathy for those misses and how to prioritize them.


One more virtual session by Hui Jing Chen capped the day, but admittedly, I missed about half of it because I was having a hallway conversation. The conversation was worth it, even though I am bummed I missed the presentation. I’ll be watching the video of it when it’s published!


Some Things I Took Away From An Event Apart 2022 in Denver originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , , , , , , ,

An Event Apart Full Summit! (Use Coupon AEACSST21)

(This is a sponsored post.)

The web’s premier conference is online this fall, October 11–13, 2021: An Event Apart Full Summit. If you already know how good of a conference this is (i.e. that some of the web’s biggest ideas debut at AEA) then just go buy tickets and please enjoy yourself. You can buy literally any combination of the three days. That coupon code, AEACSST21, is good for $ 100 off if you buy two or more days.

That’s only half!

If you’d like to know more, just have a peek at the speaker list — every name there has changed the game in this industry for the better in their own way, including five speakers hitting the AEA stage for the first time ever. Or, read up on why you should attend.

Spanning the spectrum from climate-conscious development to design beyond the screen, and from advanced CSS to inclusive design and development, An Event Apart Online Together: Fall Summit 2021 will give you deep insights into where we are now, and where things are going next.

Direct Link to ArticlePermalink


The post An Event Apart Full Summit! (Use Coupon AEACSST21) appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,
[Top]

An Event Apart Spring Summit 2021

Hey, look at that, An Event Apart is back with a new event taking place online from April 19-21. That’s three jam-packed days of absolute gems from a stellar lineup of speakers!

Guess what? I’m going to be there, along with my ShopTalk Show co-host Dave Rupert doing a live show which could include questions and comments from you. Dave will be doing a talk as well, on Web Components, which I’ll be in the virtual front row for.

What else? You’ll learn about advanced CSS from Rachel Andrew and Miriam Suzanne (believe me, there is a lot going on in CSS land to know about), inclusive and cross-cultural design from Derek Featherstone and Senongo Akpem, PWAs from Ire Aderinokun, user research from Cyd Harrell, and much, much more. Huge. Check out the detailed Spring Summit three-day schedule and prepare to be wowed by all the names on that list.

You can join the fun by registering today. An Event Apart actually gave us a discount code just for CSS-Tricks readers like yourself. Use AEACSST21 at checkout and that’ll knock $ 100 of the price of a multi-day pass.


The post An Event Apart Spring Summit 2021 appeared first on CSS-Tricks.

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

CSS-Tricks

, , , ,
[Top]

Using AbortController as an Alternative for Removing Event Listeners

The idea of an “abortable” fetch came to life in 2017 when AbortController was released. That gives us a way to bail on an API request initiated by fetch() — even multiple calls — whenever we want.

Here’s a super simple example using AbortController to cancel a fetch() request:

const controller = new AbortController(); const res = fetch('/', { signal: controller.signal }); controller.abort(); console.log(res); // => Promise(rejected): "DOMException: The user aborted a request"

You can really see its value when used for a modern interface of setTimeout. This way, making a fetch timeout after, say 10 seconds, is pretty straightforward:

function timeout(duration, signal) {   return new Promise((resolve, reject) => {     const handle = setTimeout(resolve, duration);     signal?.addEventListener('abort', e => {       clearTimeout(handle);       reject(new Error('aborted'));     });   }); }  // Usage const controller = new AbortController(); const promise = timeout(10000, controller.signal); controller.abort(); console.log(promise); // => Promise(rejected): "Error: aborted"

But the big news is that addEventListener now accepts an Abort Signal as of Chrome 88. What’s cool about that? It can be used as an alternate of removeEventListener:

const controller = new AbortController(); eventTarget.addEventListener('event-type', handler, { signal: controller.signal }); controller.abort();

What’s even cooler than that? Well, because AbortController is capable of aborting multiple cancelable requests at once, it streamlines the process of removing multiple listeners in one fell swoop. I’ve already found it particularly for drag and drop.

Here’s how I would have written a drag and drop script without AbortController, relying two removeEventListener instances to wipe out two different events:

// With removeEventListener el.addEventListener('mousedown', e => {   if (e.buttons !== 1) return;    const onMousemove = e => {     if (e.buttons !== 1) return;     /* work */   }    const onMouseup = e => {     if (e.buttons & 1) return;     window.removeEventListener('mousemove', onMousemove);     window.removeEventListener('mouseup', onMouseup);   }    window.addEventListener('mousemove', onMousemove);   window.addEventListener('mouseup', onMouseup); // Can’t use `once: true` here because we want to remove the event only when primary button is up }); 

With the latest update, addEventListener accepts the signal property as its second argument, allowing us to call abort() once to stop all event listeners when they’re no longer needed:

// With AbortController el.addEventListener('mousedown', e => {   if (e.buttons !== 1) return;    const controller = new AbortController();    window.addEventListener('mousemove', e => {     if (e.buttons !== 1) return;     /* work */   }, { signal: controller.signal });    window.addEventListener('mouseup', e => {     if (e.buttons & 1) return;     controller.abort();   }, { signal: abortController.signal }); });

Again, Chrome 88 is currently the only place where addEventListener officially accepts an AbortSignal. While other major browsers, including Firefox and Safari, support AbortController, integrating its signal with addEventListener is a no go at the moment… and there are no signals (pun sorta intended) that they plan to work on it. That said, a polyfill is available.


The post Using AbortController as an Alternative for Removing Event Listeners appeared first on CSS-Tricks.

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

CSS-Tricks

, , , , ,
[Top]

Let’s Create a Lightweight Native Event Bus in JavaScript

An event bus is a design pattern (and while we’ll be talking about JavaScript here, it’s a design pattern in any language) that can be used to simplify communications between different components. It can also be thought of as publish/subscribe or pubsub.

The idea is that components can listen to the event bus to know when to do the things they do. For example, a “tab panel” component might listen for events telling it to change the active tab. Sure, that might happen from a click on one of the tabs, and thus handled entirely within that component. But with an event bus, some other elements could tell the tab to change. Imagine a form submission which causes an error that the user needs to be alerted to within a specific tab, so the form sends a message to the event bus telling the tabs component to change the active tab to the one with the error. That’s what it looks like aboard an event bus.

Pseudo-code for that situation would be like…

// Tab Component Tabs.changeTab = id =&gt; {   // DOM work to change the active tab. } MyEventBus.subscribe("change-tab", Tabs.changeTab(id));  // Some other component... // something happens, then: MyEventBus.publish(&quot;change-tab&quot;, 2);  

Do you need a JavaScript library to this? (Trick question: you never need a JavaScript library). Well, there are lots of options out there:

Also, check out Mitt which is a library that’s only 200 bytes gzipped. There is something about this simple pattern that inspires people to tackle it themselves in the most succincet way possible.

Let’s do that ourselves! We’ll use no third-party library at all and leverage an event listening system that is already built into JavaScript with the addEventListener we all know and love.

First, a little context

The addEventListener API in JavaScript is a member function of the EventTarget class. The reason we can bind a click event to a button is because the prototype interface of <button> (HTMLButtonElement) inherits from EventTarget indirectly.

Source: MDN Web Docs

Different from most other DOM interfaces, EventTarget can be created directly using the new keyword. It is supported in all modern browsers, but only fairly recently. As we can see in the screenshot above, Node inherits EventTarget, thus all DOM nodes have method addEventListener.

Here’s the trick

I’m suggesting an extremely lightweight Node type to act as our event-listening bus: an HTML comment (<!-- comment -->).

To a browser rendering engine, HTML comments are just notes in the code that have no functionality other than descriptive text for developers. But since comments are still written in HTML, they end up in the DOM as real nodes and have their own prototype interface—Comment—which inherits Node.

The Comment class can be created from new directly like EventTarget can:

const myEventBus = new Comment('my-event-bus');

We could also use the ancient, but widely-supported document.createComment API. It requires a data parameter, which is the content of the comment. It can even be an empty string:

const myEventBus = document.createComment('my-event-bus');

Now we can emit events using dispatchEvent, which accepts an Event Object. To pass user-defined event data, use CustomEvent, where the detail field can be used to contain any data.

myEventBus.dispatchEvent(   new CustomEvent('event-name', {      detail: 'event-data'   }) );

Internet Explorer 9-11 supports CustomEvent, but none of the versions support new CustomEvent. It’s complex to simulate it using document.createEvent, so if IE support is important to you, there’s a way to polyfill it.

Now we can bind event listeners:

myEventBus.addEventListener('event-name', ({ detail }) => {   console.log(detail); // => event-data });

If an event intends to be triggered only once, we may use { once: true } for one-time binding. Other options won’t fit here. To remove event listeners, we can use the native removeEventListener.

Debugging

The number of events bound to single event bus can be huge. There also can be memory leaks if you forget to remove them. What if we want to know how many events are bound to myEventBus?

myEventBus is a DOM node, so it can be inspected by DevTools in the browser. From there, we can find the events in the Elements → Event Listeners tab. Be sure to uncheck “Ancestors” to hide events bound on document and window.

An example

One drawback is that the syntax of EventTarget is slightly verbose. We can write a simple wrapper for it. Here is a demo in TypeScript below:

class EventBus<DetailType = any> {   private eventTarget: EventTarget;   constructor(description = '') { this.eventTarget = document.appendChild(document.createComment(description)); }   on(type: string, listener: (event: CustomEvent<DetailType>) => void) { this.eventTarget.addEventListener(type, listener); }   once(type: string, listener: (event: CustomEvent<DetailType>) => void) { this.eventTarget.addEventListener(type, listener, { once: true }); }   off(type: string, listener: (event: CustomEvent<DetailType>) => void) { this.eventTarget.removeEventListener(type, listener); }   emit(type: string, detail?: DetailType) { return this.eventTarget.dispatchEvent(new CustomEvent(type, { detail })); } }      // Usage const myEventBus = new EventBus<string>('my-event-bus'); myEventBus.on('event-name', ({ detail }) => {   console.log(detail); });  myEventBus.once('event-name', ({ detail }) => {   console.log(detail); });  myEventBus.emit('event-name', 'Hello'); // => HellonHello myEventBus.emit('event-name', 'World'); // => World

The following demo provides the compiled JavaScript.


And there we have it! We just created a dependency-free event-listening bus where one component can inform another component of changes to trigger an action. It doesn’t take a full library to do this sort of stuff, and the possibilities it opens up are pretty endless.


The post Let’s Create a Lightweight Native Event Bus in JavaScript appeared first on CSS-Tricks.

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

CSS-Tricks

, , , , ,
[Top]

Virtual Event Registrations with Wufoo Forms

(This is a sponsored post.)

We’ve seen many events shift from in-person to online this year. That may have required a huge change to how you collect attendee registrations in the past, but with a paid Wufoo account and Zoom — along with a sprinkle of Zapier — it’s easier than ever to go virtual.

First, set up a Zoom call

It doesn’t have to start right now but can be scheduled in advance so we have something to connect to. In Zoom, that’s just a click of the giants “Schedule” button on the welcome screen once the app has been launched.

“New Meeting” will launch something right away, whereas “Schedule” will set a call up in advance to start at a fitter date and time.

Next, we need a registration form

We’re talking about Wufoo’s bread and butter: making online forms! We can create one from scratch, of course, but Wufoo makes it even easier with a set of pre-made options that are specifically designed for registration.

Any of these can be used as-is, or as a starting point to make your own.

Whether you start with a clean slate or a template, the key things you’re going to want to collect are:

  • Name
  • Email address

Seriously, that’s it. Anything else is icing on the cake that can be used to collect additional information about attendees, like their age, gender, shirt size, allergies, or whatever else you think will be helpful to make a better event.

Is this a paid event?

Many events are! If you want to charge a fee for the event, Wufoo integrates with Stripe, Square, PayPal and a slew of other payment gateways that make collecting payments rather trivial. Plus, transactions are protected by 256-bit SSL encryption that’s super secure and PCI-compliant.

Purchasing a single ticket is pretty straightforward, but let’s say you want to allow folks to purchase multiple tickets at a time or have multiple tiers of ticket pricing. Not a problem at all in Wufoo! For example, it’s possible to set prices by the answer provided in a field.

Now, when someone selects an option in the “Number of Tickets” field, a price will calculated.

Is there a maximum number of “seats” available?

You may be cool with an unlimited number of attendees. But if you need to limit the head count, check out Wufoo’s Max Quantity feature, which is like creating a pool of tickets that each registration subtracts from. This is especially useful to create a more “intimate” presentation for, say, workshops or group activities.

The “Max Quantities” feature can restrict the number of people who can register for a specific workshop.

Connect to Zoom

We’re using Zoom in this example, but Wufoo is capable of connecting to other video services, including join.me, GoToMeeting, and Cisco Webex.

Wufoo’s integrations come by way of Zapier. If you’re new to it, Zapier is this thing that basically connects apps together, establishing communication between their APIs so that they interact with each other when something happens. In this case, when someone signs up for the virtual event, we want to add them as a guest on the Zoom call.

So, go into your Zapier account (or set one up for free). From there, we’ll create a new “zap” which Zapier’s slang for a new app connection. That means we select Wufoo as the first app we want to use and Zoom as the app we want to connect to.

Once the apps have been chosen, Zapier provides options for what to “watch for” in Wufoo (a form submission, or “New Entry” in this case) and actions we want to take place in Zoom when that trigger happens (“Create Webinar Registrant” in this case).

Click the “Use Zap” button and Zapier will walk through the rest of the steps, including what form to use in this integration and which scheduled Zoom webinar to create registrants.

Watch the registrations roll in!

Well, yes. We are technically done at this point, but we’ll want to do some housecleaning before we can actually start collecting registrations:

  • Finish designing the form. Wufoo has a lot of nice design options, and even takes custom CSS to fine-tune the way things look.
  • Embed the form. The form needs to go somewhere if we want folks to use it. A Wufoo form can be embedded just about anywhere (hey, we use on on our own Contact page). Or, simply link it up and use the public URL Wufoo generates for the form.
  • Customize the receipt email. Once a transaction is made, the user will get a receipt emailed to their inbox. It’s a good idea to give it a little love so it’s personalized.
  • Create a reminder email. Sending a reminder a few days before the event is a nice way to give folks a heads up that the event is coming up. Wufoo also integrates with both Mailchimp and Campaign Monitor, both of which can be used in a zap that adds attendees to an email list and sends triggered and automated messages.

There you go, a registration flow for a virtual event that is powerful and doesn’t require any code! If you don’t have a Wufoo account already, get one now — it’s free and worth exploring all the interesting things it can do.

Direct Link to ArticlePermalink


The post Virtual Event Registrations with Wufoo Forms appeared first on CSS-Tricks.

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

CSS-Tricks

, , , ,
[Top]

Register for An Event Apart’s Front-End Focus Online Conference

(This is a sponsored post.)

An Event Apart has been doing these single-day online “Online together” conferences. You can check out the last couple, which are available on-demand (buy it, watch it when you want) for a limited time:

The next event is one that anyone reading CSS-Tricks will really want to check out. It’s called “Front-End Focus” which is literally what we write about here all the time. Register today for the event! It takes place August 17 and features a schedule packed with amazing talks from amazing speakers, like design principles from Jeremy Keith, future-proofing CSS from Ire Aderinokun, and modern CSS tricks from Una Kravets, among several others.

Direct Link to ArticlePermalink


The post Register for An Event Apart’s Front-End Focus Online Conference appeared first on CSS-Tricks.

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

CSS-Tricks

, , , , , ,
[Top]

Save Big on An Event Apart for a Limited Time!

(This is a sponsored post.)

If you could get one gift from your boss this holiday season, what would you want it to be? You know, other than the usual mouse pad, picture frame or, my favorite, the ol’ coffee mug and Starbucks card combo.

What if you were to receive something, hmm, more substantial? Like something that keeps giving three days instead of one. Or something that levels up your front-end chops. Or something that lets you network with your peers and gain invaluable experience by learning from the brightest minds in the biz?

Yes, all of that would be awesome — nay — epic! And, yes, you can get all of that together with one ticket to An Event Apart.

There truly is no better gift for front-enders. It’s a break from the desk into a three-day haven of learning about the most important movements in web development and design from the folks who are leading the way. Seriously, just check out the lineup for the Washington D.C. installment.

This is where we’d normally share a special coupon code that scores you a $ 100 discount and gives us credit for sending you there. You can totally do that by entering AEACP at checkout. We rely on sponsorships around here and supporting our sponsors keeps this boat moving.

But! An Event Apart are feeling extra generous this season and offering a discount of $ 200 off any two- or three-day pass to any of their 2020 events. That includes stops in D.C., Seattle, Boston, Minneapolis, Orlando and San Francisco!

OK, so what’s that code? You’re just gonna have to watch out on Twitter, Facebook or their mailing list on Friday, December 13, to get it.

Learn More

Direct Link to ArticlePermalink

The post Save Big on An Event Apart for a Limited Time! appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Save Big on An Event Apart for a Limited Time!

(This is a sponsored post.)

If you could get one gift from your boss this holiday season, what would you want it to be? You know, other than the usual mouse pad, picture frame or, my favorite, the ol’ coffee mug and Starbucks card combo.

What if you were to receive something, hmm, more substantial? Like something that keeps giving three days instead of one. Or something that levels up your front-end chops. Or something that lets you network with your peers and gain invaluable experience by learning from the brightest minds in the biz?

Yes, all of that would be awesome — nay — epic! And, yes, you can get all of that together with one ticket to An Event Apart.

There truly is no better gift for front-enders. It’s a break from the desk into a three-day haven of learning about the most important movements in web development and design from the folks who are leading the way. Seriously, just check out the lineup for the Washington D.C. installment.

This is where we’d normally share a special coupon code that scores you a $ 100 discount and gives us credit for sending you there. You can totally do that by entering AEACP at checkout. We rely on sponsorships around here and supporting our sponsors keeps this boat moving.

But! An Event Apart are feeling extra generous this season and offering a discount of $ 200 off any two- or three-day pass to any of their 2020 events. That includes stops in D.C., Seattle, Boston, Minneapolis, Orlando and San Francisco!

OK, so what’s that code? You’re just gonna have to watch out on Twitter, Facebook or their mailing list on Friday, December 13, to get it.

Learn More

Direct Link to ArticlePermalink

The post Save Big on An Event Apart for a Limited Time! appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Register Now for An Event Apart 2019 in Chicago

(This is a sponsored post.)

An Event Apart juuuuust wrapped up its Washington D.C. event yesterday. We hope we got to see you at the event but if not, perhaps we’ll see you at the next one happening Aug. 28-28 in Chicago.

Why would you go, you might ask? It’s three days of experts imparting their knowledge on topics ranging from CSS Houdini to intrinsic layouts — and that’s just the first day!

Seriously, there are lot of reasons why you’d want to go. The speakers are top-notch, the opportunities to network with others will be aplenty and you’ll be upping your front-end development chops the entire time. Not a bad collection of perks, for sure.

The time to register is now and, when you do, use coupon code AEACP at checkout and get $ 100 off the price!

Register Today

Direct Link to ArticlePermalink

The post Register Now for An Event Apart 2019 in Chicago appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]