CSS Scroll Snap Slide Deck That Supports Live Coding

Virtual conferences have changed the game in terms of how a presenter is able to deliver content to an audience. At a live event it’s likely you just have your laptop, but at home, you may have multiple monitors so that you can move around windows and make off-screen changes when delivering live coding demos. However, as some events go back to in-person, you may be in a similar boat as me wondering how to bring an equivalent experience to a live venue.

With a bit of creativity using native web functionality and modern CSS, like CSS scroll snap, we’ll be building a no-JavaScript slide deck that allows live editing of CSS demos. The final deck will be responsive and shareable, thanks to living inside of a CodePen.

To make this slide deck, we’ll learn about:

  • CSS scroll snap, counters, and grid layout
  • The contenteditable attribute
  • Using custom properties and HSL for theming
  • Gradient text
  • Styling the <style> element

Slide templates

When making a slide deck of a bunch of different slides, it’s likely that you’ll need different types of slides. So we’ll create these three essential templates:

  • Text: open for any text you need to include
  • Title: emphasizing a headline to break up sections of content
  • Demo: split layout with a code block and the preview
Screenshot of the text slide containing a heading, byline, and Twitter handle. The text is dark blue and the background has a light blue. There is the number one in white inside a bright blue circle located in the bottom-left corner of the slide indicating the page title.
Text presentation slide
A slide with the text Topic 1 in dark blue and a soft linear gradient that goes from a super light blue to a brighter blue, going from left to right.
Title presentation slide

Slide deck screenshot showing the split view with live code on the left and the output on the right. The page number of the slide is shown in the bottom-left corner and includes the word CSS after the page number.
Demo presentation slide

HTML templates

Let’s start creating our HTML. We’ll use an ordered list with the ID of slides and go ahead and populate a text and title slide.

Each slide is one of the list elements with the class of slide, as well as a modifier class to indicate the template type. For these text-based slides, we’ve nested a <div> with the class of content and then added a bit of boilerplate text.

<ol id="slides">
  <li class="slide slide--text">
    <div class="content">
      <h1>Presentation Title</h1>
      <p>Presented by Your Name</p>
      <p><a target="_blank" href="<https://twitter.com/5t3ph>">@5t3ph</a></p>
    </div>
  </li>
  <li class="slide slide--title">
    <div class="content">
      <h2>Topic 1</h2>
    </div>
  </li>
</ol>

We’re using target="_blank" on the link due to CodePen using iframes for the preview, so it’s necessary to “escape” the iframe and load the link.

Base styles

Next, we’ll begin to add some styles. If you are using CodePen, these styles assume you’re not loading one of the resets. Our reset wipes out margin and ensures the <body> element takes up the total available height, which is all we really need here. And, we’ll make a basic font stack update.

* {
  margin: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  font-family: system-ui, sans-serif;
  font-size: 1.5rem;
}

Next, we’ll define that all our major layout elements will use a CSS grid, remove list styling from #slides, and make each slide take up the size of the viewport. Finally, we’ll use the place-content shorthand to center the slide--text and slide--title slide content.

body,
#slides,
.slide {
  display: grid;
}

#slides {
  list-style: none;
  padding: 0;
  margin: 0;
}

.slide {
  width: 100vw;
  height: 100vh;
}

.slide--text,
.slide--title {
  place-content: center;
}

Then, we’ll add some lightweight text styles. Since this is intended to be a presentation with one big point being made at a time, as opposed to an article-like format, we’ll bump the base font-size to 2rem. Be sure to adjust this value as you test out your final slides in full screen. You may decide it feels too small for your content versus your presentation viewport size.

h1, h2 {
  line-height: 1.1;
}

a {
  color: inherit;
}

.content {
  padding: 2rem;
  font-size: 2rem;
  line-height: 1.5;
}

.content * + * {
  margin-top: 0.5em;
}

.slide--text .content {
  max-width: 40ch;
}

At this point, we have some large text centered within a container the size of the viewport. Let’s add a touch of color by creating a simple theme system.

We’ll be using the hsl color space for the theme while setting a custom property of --theme-hue and --theme-saturation. The hue value of 230 corresponds to a blue. For ease of use, we’ll then combine those into the --theme-hs value to drop into instances of hsl.

:root {
  --theme-hue: 230;
  --theme-saturation: 85%;
  --theme-hs: var(--theme-hue), var(--theme-saturation);
}

We can adjust the lightness values for backgrounds and text. The slides will feel cohesive since they will be tints of that base hue.

Back in our main <body> style, we can apply this idea to create a very light version of the color for a background, and a dark version for the text.

body {
  /* ... existing styles */
  background-color: hsl(var(--theme-hs), 95%);
  color: hsl(var(--theme-hs), 25%);
}
Screenshot of a CSS scroll snap slide  with the presentation title, a byline, and a Twitter handle. The text is dark blue and the background is a light blue.

Let’s also give .slide--title a little bit of extra pizazz by adding a subtle gradient background.

.slide--title {
  background-image: 
    linear-gradient(125deg, 
      hsl(var(--theme-hs), 95%), 
      hsl(var(--theme-hs), 75%)
    );
}
A slide with the text Topic 1 in dark blue and a soft linear gradient that goes from a super light blue to a brighter blue, going from left to right.

Demo slide template

Our demo slide breaks the mold so far and requires two main elements:

  • a .style container around an inline <style> element with actual written styles that you intend to both be visible on screen and apply to the demo
  • a .demo container to hold the demo preview with whatever markup is appropriate for that

If you’re using CodePen to create this deck, you’ll want to update the “Behavior” setting to turn off “Format on Save.” This is because we don’t want extra tabs/spaces prior to the styles block. Exactly why will become clear in a moment.

Screenshot of a CodePen's HTMLand CSS code panels. The settings menu for the HTML panel is open and highlighting the first item, which is Format HTML.

Here’s our demo slide content:

<li class="slide slide--demo">
  <div class="style">
  <style contenteditable="true"> 
.modern-container {
  --container-width: 40ch;

  width: min(
    var(--container-width), 100% - 3rem
  );
  margin-inline: auto;
}
  </style>
  </div>
  <div class="demo">
    <div class="modern-container">
      <div class="box">container</div>
    </div>
  </div>
</li>

Note that extra contenteditable="true" attribute on the <style> block . This is a native HTML feature that allows you to mark any element as editable. It is not a replacement for form inputs and textareas and typically requires JavaScript for more full-featured functionality. But for our purposes, it’s the magic that enables “live” coding. Ultimately, we’ll be able to make changes to the content in here and the style changes will apply immediately. Pretty fancy, hold tight.

However, if you view this so far, you won’t see the style block displayed. You will see the outcome of the .modern-container demo styles are being applied, though.

Another relevant note here is that HTML5 included validating a <style> block anywhere; not just in the <head>.

What we’re going to do next will feel strange, but we can actually use display properties on <style> to make it visible. We’ve placed it within another container to use a little extra positioning for it and make it a resizable area. Then, we’ve set the <style> element itself to display: block and applied properties to give it a code editor look and feel.

.style {
  display: grid;
  align-items: center;
  background-color: hsl(var(--theme-hs), 5%);
  padding-inline: max(5vw, 2rem) 3rem;
  font-size: 1.35rem;
  overflow-y: hidden;
  resize: horizontal;
}

style {
  display: block;
  outline: none;
  font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
  color: hsl(var(--theme-hs), 85%);
  background: none;
  white-space: pre;
  line-height: 1.65;
  tab-size: 2;
  hyphens: none;
}

Then, we need to create the .slide--demo rule and use CSS grid to display the styles and demo, side-by-side. As a reminder, we’ve already set up the base .slide class to use grid, so now we’ll create a rule for grid-template-columns just for this template.

.slide--demo {
  grid-template-columns: fit-content(85ch) 1fr;
}

If you’re unfamiliar with the grid function fit-content(), it allows an element to use its intrinsic width up until the maximum value defined in the function. So, this rule says the style block can grow to a maximum of 85ch wide. When your <style> content is narrow, the column will only be as wide as it needs to be. This is really nice visually as it won’t create extra horizontal space while still ultimately capping the allowed width.

To round out this template, we’ll add some padding for the .demo. You may have also noticed that extra class within the demo of .box. This is a convention I like to use for demos to provide a visual of element boundaries when the size and position of something are important.

.demo {
  padding: 2rem;
}

.box {
  background-color: hsl(var(--theme-hs), 85%);
  border: 2px dashed;
  border-radius: .5em;
  padding: 1rem;
  font-size: 1.35rem;
  text-align: center;
}

Here’s the result of our code template:

Screenshot of a slide that's split in half vertically, the left side with a almost black dark blue background and code that is a lighter blue in a mono font. The right side has a light blue background and an element at the top that says container, with a dashed border and slightly darker blue background.

Live-editing functionality

Interacting with the displayed styles will actually update the preview! Additionally, since we created the .style container as a resizable area, you can grab the resize handle in the lower right to grow and shrink the preview area as needed.

The one caveat for our live-editing ability is that browsers treat it differently.

  • Firefox: This provides the best result as it allows both changing the loaded styles and full functionality of adding new properties and even new rules.
  • Chromium and Safari: These allow changing values in loaded styles, but not adding new properties or new rules.

As a presenter, you’ll likely want to use Firefox. As for viewers utilizing the presentation link, they’ll still be able to get the intention of your slides and shouldn’t have issues with the display (unless their browser doesn’t support your demoed code). But outside of Firefox, they may be unable to manipulate the demos as fully as you may show in your presentation.

You may want to “Fork” your finished presentation pen and actually remove the editable behavior on <style> blocks and instead display final versions of your demos styles, as applicable.

Reminder: styles you include in demos can potentially affect slide layout and other demos! You may want to scope demo styles under a slide-specific class to prevent unintended style changes across your deck.

Code highlighting

While we won’t be able to achieve full syntax highlighting without JavaScript, we can create a method to highlight certain parts of the code block for emphasis.

To do this, we’ll pair up linear-gradient with the -webkit properties that enable using an element’s background as the text effect. Then, using custom properties, we can define how many “lines” of the style block to highlight.

First, we’ll place the required -webkit properties directly on the <style> element. This will cause the visible text to disappear, but we’ll make it visible in a moment by adding a background. Although these are -webkit prefixed, they are supported cross-browser.

style {
  /* ...existing styles */
  -webkit-text-fill-color: transparent;
  -webkit-background-clip: text;
}

The highlighting effect will work by creating a linear-gradient with two colors where the lighter color shows through as the text color for the lines to highlight. As a default, we’ll bookend the highlight with a darker color such that it appears that the first property is highlighted.

Here’s a preview of the initial effect:

An up-close screenshot of the live code panel of the slide, with the second line of code a lighter blue than the rest, indicating that it is emphasized.

To create this effect, we need to work out how to calculate the height of the highlight color. In our <style> element’s rules, we’ve already set the line-height to 1.65, which corresponds to a total computed line height of 1.65em. So, you may think that we multiply that by the number of lines and call it a day.

However, due to the visible style block being rendered using white-space: pre to preserve line breaks, there’s technically a sneaky invisible line before the first line of text. This is created from formatting the <style> tag on an actual line prior to the first line of CSS code. This is also why I noted that preventing auto-formatting in CodePen is important — otherwise, you would also have extra left padding.

With these caveats in mind, we’ll set up three custom properties to help compute the values we need and add them to the beginning of our .style ruleset. The final --lines height value first takes into account that invisible line and the selector.

style {
  --line-height: 1.65em;
  --highlight-start: calc(2 * var(--line-height));
  --lines: calc(var(--highlight-start) + var(--num-lines, 1) * var(--line-height));
}

Now we can apply the values to create the linear-gradient. To create the sharp transitions we need for this effect, we ensure the gradient stops from one color to the next match.

style {
  background-image: linear-gradient(
    hsl(var(--theme-hs), 75%) 0 var(--highlight-start),
    hsl(var(--theme-hs), 90%) var(--highlight-start) var(--lines),
    hsl(var(--theme-hs), 75%) var(--lines) 100%
  );
}

To help visualize what’s happening, I’ve commented out the -webkit lines to reveal the gradient being created.

A close-up screenshot of the live code example, but with a bright blue background to reveal the near-white gradient that highlights the second line of code.

Within our --lines calculation, we also included a --num-lines property. This will let you adjust the number of lines to highlight per demo via an inline style. This example adjusts the highlight to three lines:

<style contenteditable="true" style="--num-lines: 3">

We can also pass a recalculated --highlight-start to change the initial line highlighted:

<style contenteditable="true" style="--num-lines: 3; --highlight-start: calc(4 * var(--line-height))">

Let’s look at the outcome of the previous adjustment:

Showing the live code example with lines 3 through 6 highlighted in a lighter blue than the rest of the code.

Now, if you add or remove lines during your presentation, the highlighting will not adjust. But it’s still nice as a tool to help direct your viewers’ attention.

There are two utility classes we’ll add for highlighting the rule only or removing highlighting altogether. To use, apply directly to the <style> element for the demo.

.highlight--rule-only {
  --highlight-start: calc(1 * var(--line-height))
}

.highlight--none {
  background-image: none;
  background-color: currentColor;
}

Slide motion with CSS scroll snap

Alright, we have some nice-looking initial slides. But it’s not quite feeling like a slide deck yet. We’ll resolve that in two parts:

  1. Reflow the slides horizontally
  2. Use CSS scroll snap to enforce scrolling one slide at a time

Our initial styles already defined the #slides ordered list as a grid container. To accomplish a horizontal layout, we need to add one extra property since the .slides have already included dimensions to fill the viewport.

#slides {
  /* ...existing styles */
  grid-auto-flow: column;
}

For CSS scroll snap to work, we need to define which axis allows overflow, so for horizontal scrolling, that’s x:

#slides {
  overflow-x: auto;
}

The final property we need for scroll snapping for the #slides container is to define scroll-snap-type. This is a shorthand where we select the x axis, and the mandatory behavior, which means initiating scrolling should always trigger snapping to the next element.

#slides {
  scroll-snap-type: x mandatory;
}

If you try it at this point, you won’t experience the scroll snapping behavior yet because we have two properties to add to the child .slide elements. Use of scroll-snap-align tells the browser where to “snap” to, and setting scroll-snap-stopto always prevents scrolling past one of the child elements.

.slide {
  /* ...existing styles */
  scroll-snap-align: center;
  scroll-snap-stop: always;
}

The scroll snapping behavior should work either by scrolling across your slide or using left and right arrow keys.

There are more properties that can be set for CSS scroll snap, you can review the MDN docs to learn what all is available. CSS scroll snap also has a bit different behavior cross-browser, and across input types, like touch versus mouse, or touchpad versus mouse wheel, or via scrollbar arrows. For our presentation, if you find that scrolling isn’t very smooth or “snapping” then try using arrow keys instead.

Currently, there isn’t a way to customize the CSS scroll snap sliding animation easing or speed. Perhaps that is important to you for your presentation, and you don’t need the other features we’ve developed for modifying the code samples. In that case, you may want to choose a “real” presentation application.

CSS scroll snap is very cool but also has some caveats to be aware of if you’re thinking of using it beyond our slide deck context. Check out another scroll snapping demo and more information on SmolCSS.dev.

Slide numbers

An optional feature is adding visible slide numbers. Using a CSS counter, we can get the current slide number and display it however we’d like as the value of a pseudo-element. And using data attributes, we can even append the current topic.

The first step is giving our counter a name, which is done via the counter-reset property. This is placed on the element that contains items to be counted, so we’ll add it to #slides.

#slides {
  counter-reset: slides;
}

Then, on the elements to be counted (.slide), we add the counter-increment property and callback to the name of the counter we defined.

.slide {
  counter-increment: slides;
}

To access the current count, we’ll set up a pseudo element. Within the content property, the counter() function is available. This function accepts the name of our counter and returns the current number.

.slide::before {
  content: counter(slides);
}

The number is now appearing but not where we want it. Because our slide content is variable, we’ll use classic absolute positioning to place the slide number in the bottom-left corner. And we’ll add some visual styles to make it enclosed in a nice little circle.

.slide::before {
  content: counter(slides);
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  width: 1.65em;
  height: 1.65em;
  display: grid;
  place-content: center;
  border-radius: 50%;
  font-size: 1.25rem;
  color: hsl(var(--theme-hs), 95%);
  background-color: hsl(var(--theme-hs), 55%);
}
Screenshot of the text slide containing a heading, byline, and Twitter handle. The text is dark blue and the background has a light blue. There is the number one in white inside a bright blue circle located in the bottom-left corner of the slide indicating the page title.

We can enhance our slide numbers by grabbing the value of a data attribute to also append a short topic title. This means first adding an attribute to each <li> element where we want this to happen. We’ll add data-topic to the <li> for the title and code demo slides. The value can be whatever you want, but shorter strings will display best.

<li class="slide slide--title" data-topic="CSS">

We’ll use the attribute as a selector to change the pseudo element. We can get the value by using the attr() function, which we’ll concatenate with the slide number and add a colon for a separator. Since the element was previously a circle, there are a few other properties to update.

[data-topic]::before {
  content: counter(slides) ": " attr(data-topic);
  padding: 0.25em 0.4em;
  width: auto;
  border-radius: 0.5rem;
}

With that added, here’s the code demo slide showing the added topic of “CSS”:

Slide deck screenshot showing the split view with live code on the left and the output on the right. The page number of the slide is shown in the bottom-left corner and includes the word CSS after the page number.

Small viewport styles

Our slides are already somewhat responsive, but eventually, there will be problems with horizontal scrolling on smaller viewports. My suggestion is to remove the CSS scroll snap and let the slides flow vertically.

To accomplish this will just be a handful of updates, including adding a border to help separate slide content.

First, we’ll move the CSS scroll snap related properties for #slides into a media query to only apply above 120ch.

@media screen and (min-width: 120ch) {
  #slides {
    grid-auto-flow: column;
    overflow-x: auto; 
    scroll-snap-type: x mandatory;
  }
}

Next, we’ll move the CSS scroll snap and dimension properties for .slide into this media query as well.

@media screen and (min-width: 120ch) {
  .slide {
    width: 100vw;
    height: 100vh;
    scroll-snap-align: center;
    scroll-snap-stop: always;
  }
}

To stack the demo content, we’ll move our entire rule for .slide--demo into this media query:

@media screen and (min-width: 120ch) {
  .slide--demo {
    grid-template-columns: fit-content(85ch) 1fr;
  }
}

Now everything is stacked, but we want to bring back a minimum height for each slide and then add the border I mentioned earlier:

@media (max-width: 120ch) {
  .slide {
    min-height: 80vh;
  }

  .slide + .slide {
    border-top: 1px dashed;
  }
}

Your content also might be at risk of overflow on smaller viewports, so we’ll do a couple of adjustments for .content to try to prevent that We’ll add a default width that will be used on small viewports, and move our previous max-width constraint into the media query. Also shown is a quick method updating our <h1> to use fluid type.

h1 {
  font-size: clamp(2rem, 8vw + 1rem, 3.25rem);
}

.content {
  /* remove max-width rule from here */
  width: calc(100vw - 2rem);
}

@media screen and (min-width: 120ch) {
  .content {
    width: unset;
    max-width: 45ch;
  }
}

Additionally, I found it helps to reposition the slide counter. For that, we’ll adjust the initial styles to place it in the top-left, then move it back to the bottom in our media query.

.slide {
  /* adjust default here, removing the old "bottom" value */
  top: 0.25rem;
  left: 0.25rem;
}

@media (min-width: 120ch) {
  .slide::before {
    top: auto;
    bottom: 1rem;
    left: 1rem;
  }
}

Final slide deck

The embed will likely be showing the stacked small viewport version, so be sure to open the full version in CodePen, or jump to the live view. As a reminder, the editing ability works best in Firefox.

If you’re interested in seeing a fully finished deck in action, I used this technique to present my modern CSS toolkit.


CSS Scroll Snap Slide Deck That Supports Live Coding originally published on CSS-Tricks. You should get the newsletter and become a supporter.

Quality Sense Podcast: Lisi Hocke, Accountability and Conquering Personal Challenges

How To Push Yourself To Achieve Big Goals, Lisi’s Personal Growth Journey, and More

Tune into this episode of Quality Sense where the conversation takes a bit of a turn! Instead of focusing on testing, Federico chats with Elisabeth Hocke aka “Lisi” about how she systematically pursues new goals that help her not only in her professional career but also to grow as a person. She blogs about each as she goes, which has helped her, among other things to be named the “Most Influential Agile Testing Professional” in 2019.

Episode Highlights

  • How Lisi got involved in software development despite not coming from a technical background
  • Lisi’s journey into learning more about bias and anti-racism
  • How she started her personal challenges that she began to document on her blog to share with others
  • What’s important to have in an accountability partner to achieve your goals (no matter how scary they may seem)
  • How to become a better tester even if you’re a lone tester in your organization

Listen Here:

Quality Sense, a Software Testing Podcast · S2E3 – Lisi Hocke – Personal challenges & thoughts on the article “I’m white”

Episode Transcript:

(Lightly edited for clarity.)

Emcee Tips for a Conference or Meetup

There are some great resources out there to help conference speakers give better talks, but fewer for people who are preparing to take on the role of emcee at meetup or conference.

I've been fortunate enough to emcee conferences more than 20 times now, most recently JAMstack_conf which I help organize. I also enjoy hosting smaller, less formal meetups which benefit just as much from having somebody to keep things rolling nicely along.

Since emcee-ing is a rather visible role, I often get asked, "Got any tips for emcee-ing?" I do. At the same time, note that there is no substitute for finding the approach that fits you and lets you be yourself. But I've found what works for me, and what I enjoy in an emcee when I'm attending or speaking at a conference.

Here's my advice:

Biggest tip: Enjoy yourself.

I find that trying to relax (yeah, easy to say) and remembering that the audience want you to succeed really helps. When you remember that you're not hosting the Oscars (if you are reading this in preparation for hosting the Oscars, please contact me directly. DMs are open), and that people are very happy with you being human and personable, it gives you license to relax and talk to the room as if everyone is your friend. That’s liberating and helps you to be more natural.

The crowd's view of the stage at Vue.js London. Image copyright www.edtelling.com.

To err is human

While we all want things to run as smoothly as possible, mistakes happen. Don’t panic or let them throw you off too much. I find that owning mistakes and communicating them honestly to the audience can be a feature rather than a bug. It also helps them trust you and be on your side. (I believe that there is only one “side” at a conference anyway. And this can help to establish that.)

Many of the moments I consider highlights have come from some silly mistake I’ve made on stage, like giving the wrong information and being corrected by the audience. It’s fine. We’re in it together. Have a little fun with it.

Technical difficulties

It’s really common for there to be technical difficulties during a conference. They often only take a few moments to resolve, but they can occasionally drag on and become a little uncomfortable.

As a speaker it is horrible to think that you are on your own to fix things while a room full of people impatiently watches on. As an emcee, you can help enormously by being ready to jump in if it looks like things might need some time and concentration from the speaker, or if a helpful member of the audio-visual team is sprinting to the stage.

I like to step back on the stage to provide a little buffer. No need to panic. Often just a little company on stage and some headspace is all that is required. My trick is to keep a little pocket-sized notebook on me all day. I keep a few notes ready, things like news and announcements for the audience. Where will the refreshments be later? Who are the sponsors and where can you find them? What are the details for the social later on? Those kinds of things. You may need them at the start of the next break anyway, but you can buy a little time for the speakers and save time for later by being ready to share that at this "handy opportunity."

“Me again! We’ll get this fixed in a second. While we have a mo...”

Even when there isn’t a problem, the speaker might still take a little time to plug in their laptop, be certain that they can see their speaker notes, and so on. If the conference does need each speaker to plug in as they come to the stage, I like to invite them up while I introduce them, and then check that they are ready when it looks like they have stopped tinkering with their setup. This doesn’t need to be a secret from the audience. “It looks like Jina is ready to go. Are you all set? Excellent! OK, a big round of applause please, for...”

Longer pauses. Oh this is getting awwwwwkward!

Every once in a while, there is a larger technical issue. The audio-visual team is on it, but you’ve used up all your padding material, pulled a couple of jokes from your back pocket, and now you and the speaker are stranded on stage with nothing to say and that horrible feeling of not knowing where to put your hands so that you look natural. Not to worry. Be honest.

Eventually the audience will start to feel awkward too, so cut this off at the pass. If things look like they really do need a few minutes, tell the audience. A bright and breezy update buys you some time and some good will.

"It looks like we still need a couple more minutes to figure this out, so we’ll step off stage for a moment and then come on again to enjoy a second, bonus round of applause. Don’t go anywhere, we’ll be right back!"

This sort of thing can take the pressure off everyone. Including the audience. And you can milk that second round of applause for the speaker as they return.

Just be honest. Everyone is on your side, remember.

Practice all the names

A mistake that makes me uncomfortable is botching somebody's name when I introduce them. That is a bit of a fear I still have and I've done it many times despite my best efforts. I like to watch YouTube videos of all the speakers that I don't already know to get a sense of what they've spoken about in the past, and also as a chance to listen to how they introduce themselves. I practice them out loud and write them down phonetically if they are tricky.

If you find a name particularly difficult, you can even use the voice recorder on your phone to capture how they pronounce it on YouTube, or your own best try, and then have it ready as a last-minute primer just before you need it.

Know more than the speaker's bio

Speakers often get introduced by someone reading out their bio. I don't think this gives the impression that you have enthusiasm for, or awareness of them. Both of which are, I think, valuable for creating trust with the audience and comfort for the speaker. I like to look them up and make some notes based on previous talks, the links on their own sites, or whatever else I can scrounge. I like to have an intro that goes beyond the bio that the attendees all have and will recognize as being read verbatim when they hear it.

Introducing Divya Sasidharan onstage at Vue.js London. Image copyright www.edtelling.com.

Jake has a good thought related to this:

... it shouldn't matter if the speaker has published 18 books, or if they're just an intern starting out their career, their talk content is what matters.

Yes! Listing their full resume isn't the point at all. I personally just like to convey that I know who this is, and that I'm not encountering them for the first time as I read the schedule — and that I’m looking forward to hearing what they have to say, irrespective of how extensive their previous experience or fame may be.

It's also worth double-checking that the job title and company details you have for somebody are still correct. It's nice to make sure that you didn't miss a recent role change.

Another good nugget from Jake is to avoid surprising the speaker. I've wandered into this territory before where I've enthused about a speaker in their introduction and mentioned a bunch of things that they were planning to say for themselves in their intro. As he says:

Make the speaker aware of the kind of intro they'll get, so they can adjust their own intro accordingly.

That's good. Communicating with the speaker ahead of time so that you can tune your own intro is likely to be easier than them adjusting their own content, what with slides and timings, etc.

"No surprises" is probably a good motto for this.

Avoid "in jokes"

When you emcee, you might sometimes be introducing somebody you know. Perhaps it's a friend, a colleague, or somebody you shared a nice chat and giggle with at the reception or dinner the night before. While I think it's fine to reference a history or relationship in an intro for context, It's safer to focus on things that everyone can relate to and not just those who already know you or the speaker.

Private jokes don't mean anything to the vast majority of the audience, and can even alienate you a little by creating a bit of a clique as Jan thoughtfully mentioned on Twitter.

Don't assume or rely on "fame"

"This next speaker needs no introduction" is rarely true. Even if it's likely that a lot of people in the room might already know who a given speaker is, there will be some who don't.

As Luke observed:

Don't assume the audience knows who the speaker is.

Each speaker deserves a nice introduction. And there will always be some in the audience thinking "who dis?" Even a little background can be a helpful foundation and give the speaker a nice springboard to get started.

Announce and thank people with vigor

I've been introduced quite a few times in ways where I've been unsure whether the intro is over or not! I like to be sure that the final thing I say is the name of the speaker. (Not their talk title, although I'll likely mention that and possibly the themes in my introduction.)

An onstage introduction at Vue.js London. Image copyright www.edtelling.com.

Ending the intro with the speaker's name seems painfully obvious, but I do this even if I've used their name earlier in the intro. It makes the handoff emphatic and acts as an obvious cue for audience applause. Using an intonation which suggests "it's time to clap right now!" is also helpful. Again, it seems obvious but giving the audience clear cues is important.

Let the speakers give the talks

You might sometimes be opinionated about the topic of the next talk. Maybe you’ve given talks on the same subject yourself. Great, that will come in handy if you need to ask informed questions after the talk. But don’t fall into the temptation to show this off during your intro. The speakers are “the show” — not the emcee. And the person you are introducing is the one invited to share their expertise.

I sometimes show I value the upcoming topic, but I advise against flexing your knowledge muscles during an intro. You might cannibalize the content, or even contradict it. And you’ll never communicate it in an intro as well as the speaker can during the actual talk. You might come off as being cocky.

Don’t step on the speaker's toes. Let them present the content. This is why everyone is here.

Prep speakers for questions and answers

If there is Q&A that you’ll need to lead or curate, it’s important to know that in advance. It is one of the first things I’ll ask the organizer in the run up to a conference. I like to ask the speakers at the speaker dinner the night before the event or when they are getting mic'd up (but earlier really is better, especially when they have time to think while being relaxed) if there is anything they'd like me to ask or avoid saying altogether. There are often things people can't include due to time and this can be a chance to squeeze that in and also serve as a nice soft ball question to get things started and let them settle in.

Some speakers might not want to take questions. I like to make sure about that first, and steer the event organizers away from it if somebody prefers not to have it.

Housekeeping is a good boilerplate

At the opening of the day, I usually jump quickly into the various housekeeping stuff of toilets, exits, code of conduct, etc. soon after saying my initial hello and maintain an enthusiastic posture about the day. It doesn't require much imagination and can help you settle in.

Don't forget to introduce yourself too!

Ask the organizers what they need

Along the way, there might be a need to mention sponsors, inform people of food, or even other things. I like to check in with the organizers at every break to see if there is anything they need me to announce. Maybe there can be a private Slack channel or Whatsapp group so you can stay in contact with them. That way you can find out if they need to adjust timings or any other odds and ends as you go.

Most of all though, and to repeat my first point a little, allow yourself to enjoy the experience. It's so much fun when the speakers and audience are enjoying themselves.

Make sure you ride that wave and have fun too!

My checklist

I have this little checklist as a starting point for the events I'll be emcee-ing. It changes a bit depending on what the conference needs.

Prep speaker intro notes
Prep speaker name pronunciation notes
Confirm format for Q&A with organizers
Prep seed questions for each talk
Share event notes Google Doc with organizers
Access/create emcee slack channel or WhatsApp group
Confirm or create event intro/outro slides if appropriate
Get housekeeping notes from organizers
Get familiar with code of conduct and contact info to share
Confirm event hashtags to share
Get sponsor call-out requirements from organizers
Meet AV team and discuss transition format
Brief speakers on transition format and get ok for questions
Get water / pen / notepad / mic
Breath. Smile. Have fun.


What have I missed? Got any good tips? I'd love to hear them. Feel free to leave thoughts and suggestions in the comments.

The post Emcee Tips for a Conference or Meetup appeared first on CSS-Tricks.

So, You Wanna Submit a Proposal to Speak at an Event

You’ve been scouring the web for upcoming events. You’ve subscribed to Developer Avocados and you’ve bookmarked conferences.css-tricks.com. And now you’ve found a call for proposals (CFP) that you can’t wait to enter. You quickly fill out the online form and your pinky races towards the Enter button...

Stop. Take a deep breath. And move slowly away from the keyboard.

As a conference organizer, I’ve gone through hundreds — if not thousands — of speaking proposals. While many are excellent, there are always a bunch that show a profound misunderstanding of the event, audience, and duties of a speaker. These are the ones that immediately get dumped onto the "No Thanks" list on my Trello board. And, as a regular speaker, I’ve learned more than a few things about getting proposals accepted.

While there’s no magic bullet for fast tracking your talk, there are a number of habits you can develop and questions you can ask yourself before hitting "submit" to improve your chances of getting invited to events. If you’re a fan of checklists, I’ve put one together to guide you through the process of submitting a proposal.

It’s even available on CodePen. 😉

See the Pen
The CFP Checklist
by Jason Rodriguez (@rodriguezcommaj)
on CodePen.

Start with some research

The first thing before submitting a proposal is to research the heck out of the event.

There are a ton of events out there, each with its own unique audience and vibe. Some are big, some are small; some have huge budgets and some are bootstrapped and brand new. Your first task as a potential speaker is to learn as much as you can about the event to make sure that you’re a good fit for it and the audience. There are a few ways to do this.

First, check out the website to get a feel for the event. See when and where it is, check out past years (if there are any), and read every last bit of copy on the site. A few things to keep an eye out for: an FAQ page, a CFP page, info about sponsorships or speaking opportunities, lists of past speakers, and a hashtag. The event hashtag is important, as that will allow you to check out hype and past attendee experiences on Twitter, as well to as get a sense of excitement about the upcoming event. If there isn’t a hashtag, or all of the comments about the event are terrible, then perhaps it’s time to move on to the next CFP.

Next, do a search on YouTube, Speaker Deck, SlideShare, and Notist for past talks and slide decks. These will give you a great idea of what to expect at the event and what kinds of talks go over well with the audience.

After you’ve completed a first pass of research, it’s time to answer some key questions:

  • When and where is the event?
  • Who’s organizing it?
  • Do they have a code of conduct?
  • Do they value diversity and inclusion?
  • Are they looking for specific topics or proposals?
  • Do they cover travel/hotel?
  • Do they pay speakers?
  • Most importantly: who is their audience?

You may not be able to find an answer to all of these, but try your hardest. Feel free to reach out to organizers — most are happy to answer questions for potential speakers, and the more you know, the better you’ll be able to determine whether or not you’re a good fit for their event.

Add focus your idea

After you’ve done your research, it’s time to focus in on your proposal idea. Chances are good that you’re hunting around for events with a talk idea already in mind, but even so, you should take a few steps to make it’s as compelling for organizers as possible.

The main question you want to answer when developing a talk idea is, "What will attendees get out of my session?" This is where knowing about the audience and event — all of that research — pays off.

Far too many would-be speakers submit proposals for the wrong reasons. Many think of events as marketing and sales opportunities for their business. Others are looking to make a name for themselves so they can start charging on the speakers circuit. But the best talks come from sharing personal experiences, challenges, and solutions to problems you’ve experienced in your own work.

By researching the audience, you can determine what’s likely to be important to them. You get a feel for their challenges and interests, and you can think more deeply about how your experiences and skills can best serve them. Try to forget about the actual organizers and making a pitch to them, and instead focus all of your energy on clearly communicating how attendees’ lives and work will be improved after they sit in on your session.

A great exercise is to list out the key things attendees would take away from your talk. Try to focus on 3-5 things that people can put to work when they get back home. Making them as actionable as possible is a fantastic idea. While some proposals are all about inspiration, wrapping practical advice into inspirational examples is an excellent way to make that inspiration stick in people’s minds.

Another suggestion is to run your idea by colleagues, friends, or your partner. Put together a two-minute summary, stand up in front of them, and give them the ol’ elevator pitch. Not only will this force you to add a clear focus to your idea, but it’ll let you know if you’re ready to get up on stage in front of strangers. If you can’t give a short talk in a few minutes now, then you should probably sit back down and prepare some more before answering that call for proposals.

Craft your proposal into something worth reading

Finally, it’s time to craft your proposal and get it ready to submit.

Most CFPs consist of an online form. They can range from a few questions to multiple pages of inputs, but you’ll be filling something out for organizers to review. Although some speakers are able to fly through the forms and quickly hit "Submit," I’d recommend prepping your CFPs outside of the form first.

Open up a text file or make a note in your app of choice on one side of your screen and the CFP form on the other. Go through each field in the form and write down your response in your notes. Putting together a rough draft outside of the form gives you the opportunity to think through your answers and edit them until they clearly reflect your focused idea and the value for attendees. What’s better is that you can take that note and share it with someone you trust and respect. Gather feedback from them and use it to further refine your proposal.

A lot of CFP ask for supporting materials. These can be videos showing that you are a clear communicator, links to your website or social media accounts showing your personal interests, or even slides from previous talks. Instead of fumbling around and potentially timing out the CFPs form (and having to start all over), collect all of those materials in your note or a folder on your computer. If you’re a seasoned speaker, make sure you curate your materials to show your best and most recent talks.

Submit and wait

OK. You’ve done the research. You’ve focused your idea. You’ve even drafted the answers to the CFP, pitched the idea to your partner in the kitchen, and collected feedback from a co-worker or two. It’s time to scratch that itch and submit your proposal.

Go back to the CFP form, open up your notes and resources, and start copying and pasting. Take your time to work through the form and triple-check that you’ve filled everything out. Attach any supporting materials (seriously, how many times have we all sent an email that says "See attached file" without actually attaching anything?) and take a deep breath. Scroll to the top and read through every response as many times as you need to before you feel comfortable submitting.

Now, press "Submit." Do a little celebration, take another deep breath, and move on with your life.

It can take a long time for organizers to process submissions and figure out an agenda. Try to be patient. It’s tempting to email organizers and ask about the status of your proposal, but resist the urge. Organizers are extraordinarily busy — with the conference and their full-time jobs — and should be left to review proposals instead of fielding emails from impatient potential speakers.

A good organizer will get back to you when they’re ready and let you know the status of your submission — good or bad. If they don’t, chances are the event wasn’t that great to begin with. The key thing is to try to forget about your submission as much as possible (while still keeping the event on your calendar, just in case) and focus on more important things. Not only will this ease your anxiety but you’ll be in for a wonderful surprise when your proposal is accepted.


Speaking at events can be incredibly rewarding. Sure, it’s massively time-consuming and, depending on your disposition, extremely stressful, but it’s an excellent way to build connections and help others in the industry. While you could start spamming every event with proposals, your chances of being invited to speak all hinge on the amount of preparation you put into your submission. Taking the time to make sure you’re a good fit for an event, that you understand the audience, and that you have a focus and are able to clearly communicate your idea will up the odds of you standing onstage, clicking through slides, and (hopefully) solving some problems for the folks that paid to be there.

I’m definitely not the first person to write about answering CFPs. There are a ton of good tips out there for crafting the perfect proposal. Here are a few of my favorites:

Finally, if you have any hesitation about not being "good enough" to speak at conferences, read this excellent post from Sara Wachter-Boettcher. Then start crafting that perfect proposal.

The post So, You Wanna Submit a Proposal to Speak at an Event appeared first on CSS-Tricks.

Technical Presentation Delivery Notes

I’m writing this post as I’m sitting in the airport, leaving the CodeMash conference. This has been my first “true” conference for a while, because I was able to not just speak and stand in a sponsor booth but actually participate in a lot of sessions and talk to a lot of people. I had a blast, and both the IRS and my wife consider this a work trip.

I have been presenting in international conferences for over a decade now and I wanted to put in a few words for people who are speaking at a technical conference. None of this is new, mind you. If you have been reading any recommendations about how to present in conferences, I’m probably going to bore you. I’m writing this because I saw several sessions that had technical issues in how they were delivered. That is, the content was great, but the way it was delivered could be improved.