Tag: HTML

Using the HTML title attribute

 Steve Faulkner:

User groups not well served by use of the title attribute

• Mobile phone users.
• Keyboard only users.
• Screen magnifier users.
• Screen reader users.
• Users with fine motor skill impairments.
• Users with cognitive impairments.

Sounds like in 2020, the only useful thing the title attribute can do is label an <iframe title="Contact Form"></iframe>.

Direct Link to ArticlePermalink

The post Using the HTML title attribute appeared first on CSS-Tricks.

CSS-Tricks

, , ,

HTML: The Inaccessible Parts

<input type="number">, <input type="date">, <input type="search">, <select multiple>, <progress>, <meter>, <dialog>, <details><summary>, <video>, <div onclick>, <div aria-label>, <a href><div>Block Links</div></a>, aria-controls, role="tablist"

😬😬😬😬😬😬😬😬😬😬😬😬

Direct Link to ArticlePermalink

The post HTML: The Inaccessible Parts appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Inspiring high school students with HTML and CSS

Here’s a heartwarming post from Stephanie Stimac on her experience teaching kids the very basics of web development:

[…] the response from that class of high school students delighted me and grounded me in a way I haven’t experienced before. What I view as a simple code was absolute magic to them. And for all of us who code, I think we forget it is magic. Computational magic but still magic. HTML and CSS are magic.

Publishing anything on the web is always going to be magic to some degree but sometimes it’s easy to forget on a day to day basis. We have to brush off the cobwebs! Shake our tailfeathers! And remind ourselves and everyone around us that the basics of web development are precious and fun and exciting still. Especially so we can help inspire the next generation of web designers and developers.

Direct Link to ArticlePermalink

The post Inspiring high school students with HTML and CSS appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Same HTML, Different CSS

Ahmad Shadeed covers the idea of a card component that has a fixed set of semantic HTML with some BEMy classes on it. There is a title, author, image, and tags. Then he redesigns the card into five totally different designs without touching any of the HTML just the CSS.

If this is an ah-ha moment for you, awesome! It might be worth knowing that this exact concept essentially excited an entire generation of front-end developers, in no small part due to the concept of the CSS Zen Garden, where the entire website was a fixed set of HTML and only CSS changes birthed some incredible creativity.

Of course, we typically do get our hands into HTML when doing redesign work, but this is still a fun exercise that drives home the power of CSS. I wonder if JavaScript-powered components are what delivers this awe today, because they have a similar power of abstraction: make changes to a component and see the impact across an entire site. Only instead of the idea being rooted in constraint, there are no constraints.

Direct Link to ArticlePermalink

The post Same HTML, Different CSS appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Why JavaScript is Eating HTML

Web development is always changing. One trend in particular has become very popular lately, and it fundamentally goes against the conventional wisdom about how a web page should be made. It is exciting for some but frustrating for others, and the reasons for both are difficult to explain.

A web page is traditionally made up of three separate parts with separate responsibilities: HTML code defines the structure and meaning of the content on a page, CSS code defines its appearance, and JavaScript code defines its behavior. On teams with dedicated designers, HTML/CSS developers and JavaScript developers, this separation of concerns aligns nicely with job roles: Designers determine the visuals and user interactions on a page, HTML and CSS developers reproduce those visuals in a web browser, and JavaScript developers add the user interaction to tie it all together and “make it work.” People can work on one piece without getting involved with all three.

In recent years, JavaScript developers have realized that by defining a page’s structure in JavaScript instead of in HTML (using frameworks such as React), they can simplify the development and maintenance of user interaction code that is otherwise much more complex to build. Of course, when you tell someone that the HTML they wrote needs to be chopped up and mixed in with JavaScript they don’t know anything about, they can (understandably) become frustrated and start asking what the heck we’re getting out of this.

As a JavaScript developer on a cross-functional team, I get this question occasionally and I often have trouble answering it. All of the materials I’ve found on this topic are written for an audience that is already familiar with JavaScript — which is not terribly useful to those who focus on HTML and CSS. But this HTML-in-JS pattern (or something else that provides the same benefits) will likely be around for a while, so I think it’s an important thing that everyone involved in web development should understand.

This article will include code examples for those interested, but my goal is to explain this concept in a way that can be understood without them.

Background: HTML, CSS, and JavaScript

To broaden the audience of this article as much as possible, I want to give a quick background on the types of code involved in creating a web page and their traditional roles. If you have experience with these, you can skip ahead.

HTML is for structure and semantic meaning

HTML (HyperText Markup Language) code defines the structure and meaning of the content on a page. For example, this article’s HTML contains the text you’re reading right now, the fact that it is in a paragraph, and the fact that it comes after a heading and before a CodePen.

Let’s say we want to build a simple shopping list app. We might start with some HTML like this:

We can save this code in a file, open it in a web browser, and the browser will display the rendered result. As you can see, the HTML code in this example represents a section of a page that contains a heading reading “Shopping List (2 items),” a text input box, a button reading “Add Item,” and a list with two items reading “Eggs” and “Butter.” In a traditional website, a user would navigate to an address in their web browser, then the browser would request this HTML from a server, load it and display it. If there are already items in the list, the server could deliver HTML with the items already in place, like they are in this example.

Try to type something in the input box and click the “Add Item” button. You’ll notice nothing happens. The button isn’t connected to any code that can change the HTML, and the HTML can’t change itself. We’ll get to that in a moment.

CSS is for appearance

CSS (Cascading Style Sheets) code defines the appearance of a page. For example, this article’s CSS contains the font, spacing, and color of the text you’re reading.

You may have noticed that our shopping list example looks very plain. There is no way for HTML to specify things like spacing, font sizes, and colors. This is where CSS (Cascading Style Sheets) comes in. On the same page as the HTML above, we could add CSS code to style things up a bit:

As you can see, this CSS changed the font sizes and weights and gave the section a nice background color (designers, please don’t @ me; I know this is still ugly). A developer can write style rules like these and they will be applied consistently to any HTML structure: if we add more <section>, <button> or <ul> elements to this page, they will have the same font changes applied.

The button still doesn’t do anything, though: that’s where JavaScript comes in.

JavaScript is for behavior

JavaScript code defines the behavior of interactive or dynamic elements on a page. For example, the embedded CodePen examples in this article are powered by JavaScript.

Without JavaScript, to make the Add Item button in our example work would require us to use special HTML to make it submit data back to the server (<form action="...">, if you’re curious). Then the browser would discard the entire page and reload an updated version of the entire HTML file. If this shopping list was part of a larger page, anything else the user was doing would be lost. Scrolled down? You’re back at the top. Watching a video? It starts over. This is how all web applications worked for a long time: any time a user interacted with a webpage, it was as if they closed their web browser and opened it again. That’s not a big deal for this simple example, but for a large complex page which could take a while to load, it’s not efficient for either the browser or the server.

If we want anything to change on a webpage without reloading the entire page, we need JavaScript (not to be confused with Java, which is an entirely different language… don’t get me started). Let’s try adding some:

Now when we type some text in the box and click the “Add Item” button, our new item is added to the list and the item count at the top is updated! In a real app, we would also add some code to send the new item to the server in the background so that it will still show up the next time we load the page.

Separating JavaScript from the HTML and CSS makes sense in this simple example. Traditionally, even more complicated interactions would be added this way: HTML is loaded and displayed, and JavaScript runs afterwards to add things to it and change it. As things get more complex, however, we start needing to keep better track of things in our JavaScript.

If we were to keep building this shopping list app, next we’d probably add buttons for editing or removing items from the list. Let’s say we write the JavaScript for a button that removes an item, but we forget to add the code that updates the item total at the top of the page. Suddenly we have a bug: after a user removes an item, the total on the page won’t match the list! Once we notice the bug, we fix it by adding that same totalText.innerHTML line from our “Add Item” code to the “Remove Item” code. Now we have the same code duplicated in more than one place. Later on, let’s say we want to change that code so that instead of “(2 items)” at the top of the page it reads “Items: 2.” We’ll have to make sure we update it in all three places: in the HTML, in the JavaScript for the “Add Item” button, and in the JavaScript for the “Remove Item” button. If we don’t, we’ll have another bug where that text abruptly changes after a user interaction.

In this simple example, we can already see how quickly these things can get messy. There are ways to organize our JavaScript to make this kind of problem easier to deal with, but as things continue to get more complex, we’ll need to keep restructuring and rewriting things to keep up. As long as HTML and JavaScript are kept separate, a lot of effort can be required to make sure everything is kept in sync between them. That’s one of the reasons why new JavaScript frameworks, like React, have gained traction: they are designed to show the relationships between things like HTML and JavaScript. To understand how that works, we first need to understand just a teeny bit of computer science.

Two kinds of programming

The key concept to understand here involves the distinction between two common programming styles. (There are other programming styles, of course, but we’re only dealing with two of them here.) Most programming languages lend themselves to one or the other of these, and some can be used in both ways. It’s important to grasp both in order to understand the main benefit of HTML-in-JS from a JavaScript developer’s perspective.

  • Imperative programming: The word “imperative” here implies commanding a computer to do something. A line of imperative code is a lot like an imperative sentence in English: it gives the computer a specific instruction to follow. In imperative programming, we must tell the computer exactly how to do every little thing we need it to do. In web development, this is starting to be considered “the old way” of doing things and it’s what you do with vanilla JavaScript, or libraries like jQuery. The JavaScript in my shopping list example above is imperative code.
    • Imperative: “Do X, then do Y, then do Z”.
    • Example: When the user selects this element, add the .selected class to it; and when the user de-selects it, remove the .selected class from it.
  • Declarative programming: This is a more abstract layer above imperative programming. Instead of giving the computer instructions, we instead “declare” what we want the results to be after the computer does something. Our tools (e.g. React) figure out the how for us automatically. These tools are built with imperative code on the inside that we don’t have to pay attention to from the outside.
    • Declarative: “The result should be XYZ. Do whatever you need to do to make that happen.”
    • Example: This element has the .selected class if the user has selected it.

HTML is a declarative language

Forget about JavaScript for a moment. Here’s an important fact: HTML on its own is a declarative language. In an HTML file, you can declare something like:

<section>   <h1>Hello</h1>   <p>My name is Mike.</p> </section>

When a web browser reads this HTML, it will figure out these imperative steps for you and execute them:

  1. Create a section element
  2. Create a heading element of level 1
  3. Set the inner text of the heading element to “Hello”
  4. Place the heading element into the section element
  5. Create a paragraph element
  6. Set the inner text of the paragraph element to “My name is Mike”
  7. Place the paragraph element into the section element
  8. Place the section element into the document
  9. Display the document on the screen

As a web developer, the details of how a browser does these things is irrelevant; all that matters is that it does them. This is a perfect example of the difference between these two kinds of programming. In short, HTML is a declarative abstraction wrapped around a web browser’s imperative display engine. It takes care of the “how” so you only have to worry about the “what.” You can enjoy life writing declarative HTML because the fine people at Mozilla or Google or Apple wrote the imperative code for you when they built your web browser.

JavaScript is an imperative language

We’ve already looked at a simple example of imperative JavaScript in the shopping list example above, and I mentioned how the complexity of an app’s features has ripple effects on the effort required to implement them and the potential for bugs in that implementation. Now let’s look at a slightly more complex feature and see how it can be simplified by using a declarative approach.

Imagine a webpage that contains the following:

  • A list of labelled checkboxes, each row of which changes to a different color when it is selected
  • Text at the bottom like “1 of 4 selected” that should update when the checkboxes change
  • A “Select All” button which should be disabled if all checkboxes are already selected
  • A “Select None” button which should be disabled if no checkboxes are selected

Here’s an implementation of this in plain HTML, CSS and imperative JavaScript:

There isn’t much CSS code here because I’m using the wonderful PatternFly design system, which provides most of the CSS for my example. I imported their CSS file in the CodePen settings.

All the small things

In order to implement this feature with imperative JavaScript, we need to give the browser several granular instructions. This is the English-language equivalent to the code in my example above:

  • In our HTML, we declare the initial structure of the page:
    • There are four row elements, each containing a checkbox. The third box is checked.
    • There is some summary text which reads “1 of 4 selected.”
    • There is a “Select All” button which is enabled.
    • There is a “Select None” button which is disabled.
  • In our JavaScript, we write instructions for what to change when each of these events occurs:
    • When a checkbox changes from unchecked to checked:
      • Find the row element containing the checkbox and add the .selected CSS class to it.
      • Find all the checkbox elements in the list and count how many are checked and how many are not checked.
      • Find the summary text element and update it with the checked number and the total number.
      • Find the “Select None” button element and enable it if it was disabled.
      • If all checkboxes are now checked, find the “Select All” button element and disable it.
    • When a checkbox changes from checked to unchecked:
      • Find the row element containing the checkbox and remove the .selected class from it.
      • Find all the checkbox elements in the list and count how many are checked and not checked.
      • Find the summary text element and update it with the checked number and the total number.
      • Find the “Select All” button element and enable it if it was disabled.
      • If all checkboxes are now unchecked, find the “Select None” button element and disable it.
    • When the “Select All” button is clicked:
      • Find all the checkbox elements in the list and check them all.
      • Find all the row elements in the list and add the .selected class to them.
      • Find the summary text element and update it.
      • Find the “Select All” button and disable it.
      • Find the “Select None” button and enable it.
    • When the “Select None” button is clicked:
      • Find all the checkbox elements in the list and uncheck them all.
      • Find all the row elements in the list and remove the .selected class from them.
      • Find the summary text element and update it.
      • Find the “Select All” button and enable it.
      • Find the “Select None” button and disable it.

Wow. That’s a lot, right? Well, we better remember to write code for each and every one of those things. If we forget or screw up any of those instructions, we will end up with a bug where the totals don’t match the checkboxes, or a button is enabled that doesn’t do anything when you click it, or a row ends up with the wrong color, or something else we didn’t think of and won’t find out about until a user complains.

The big problem here is that there is no single source of truth for the state of our app, which in this case is “which checkboxes are checked?” The checkboxes know whether or not they are checked, of course, but, the row styles also have to know, the summary text has to know, and each button has to know. Five copies of this information are stored separately all around the HTML, and when it changes in any of those places the JavaScript developer needs to catch that and write imperative code to keep the others in sync.

This is still only a simple example of one small component of a page. If that sounds like a headache, imagine how complex and fragile an application becomes when you need to write the whole thing this way. For many complex modern web applications, it’s not a scalable solution.

Moving towards a single source of truth

Tools, like React, allow us to use JavaScript in a declarative way. Just as HTML is a declarative abstraction wrapped around the web browser’s display instructions, React is a declarative abstraction wrapped around JavaScript.

Remember how HTML let us focus on the structure of a page and not the details of how the browser displays that structure? Well, when we use React, we can focus on the structure again by defining it based on data stored in a single place. When that source of truth changes, React will update the structure of the page for us automatically. It will take care of the imperative steps behind the scenes, just like the web browser does for HTML. (Although React is used as an example here, this concept is not unique to React and is used by other frameworks, such as Vue.)

Let’s go back to our list of checkboxes from the example above. In this case, the truth we care about is simple: which checkboxes are checked? The other details on the page (e.g. what the summary says, the color of the rows, whether or not the buttons are enabled) are effects derived from that same truth. So, why should they need to have their own copy of this information? They should just use the single source of truth for reference, and everything on the page should “just know” which checkboxes are checked and conduct themselves accordingly. You might say that the row elements, summary text, and buttons should all be able to automatically react to a checkbox being checked or unchecked. (See what I did there?)

Tell me what you want (what you really, really want)

In order to implement this page with React, we can replace the list with a few simple declarations of facts:

  • There is a list of true/false values called checkboxValues that represents which boxes are checked.
    • Example:  checkboxValues = [false, false, true, false]
    • This list represents the truth that we have four checkboxes, and that the third one is checked.
  • For each value in checkboxValues, there is a row element which:
    • has a CSS class called .selected if the value is true, and
    • contains a checkbox, which is checked if the value is true.
  • There is a summary text element that contains the text “{x} of {y} selected” where {x} is the number of true values in checkboxValues and {y} is the total number of values in checkboxValues.
  • There is a “Select All” button that is enabled if there are any false values in checkboxValues.
  • There is a “Select None” button that is enabled if there are any true values in checkboxValues.
  • When a checkbox is clicked, its corresponding value changes in checkboxValues.
  • When the “Select All” button is clicked, it sets all values in checkboxValues to true.
  • When the “Select None” button is clicked, it sets all values in checkboxValues to false.

You’ll notice that the last three items are still imperative instructions (“When this happens, do that”), but that’s the only imperative code we need to write. It’s three lines of code, and they all update the single source of truth. The rest of those bullets are declarations (“there is a…”) which are now built right into the definition of the page’s structure. In order to do this, we write our elements in a special JavaScript syntax provided by React called JSX, which resembles HTML but can contain JavaScript logic. That gives us the ability to mix logic like “if” and “for each” with the HTML structure, so the structure can be different depending on the contents of checkboxValues at any given time.

Here’s the same shopping list example as above, this time implemented with React:

JSX is definitely weird. When I first encountered it, it just felt wrong. My initial reaction was, “What the heck is this? HTML doesn’t belong in JavaScript!” I wasn’t alone. That said, it’s not HTML, but rather JavaScript dressed up to look like HTML. It is also quite powerful.

Remember that list of 20 imperative instructions above? Now we have three. For the price of defining our HTML inside our JavaScript, the rest of them come for free. React just does them for us whenever checkboxValues changes.

With this code, it is now impossible for the summary to not match the checkboxes, or for the color of a row to be wrong, or for a button to be enabled when it should be disabled. There is an entire category of bugs which are now impossible for us to have in our app: sources of truth being out of sync. Everything flows down from the single source of truth, and we developers can write less code and sleep better at night. Well, JavaScript developers can, at least…

It’s a trade-off

As web applications become more complex, maintaining the classic separation of concerns between HTML and JavaScript comes at an increasingly painful cost. HTML was originally designed for static documents, and in order to add more complex interactive functionality to those documents, imperative JavaScript has to keep track of more things and become more confusing and fragile.

The upside: predictability, reusability and composition

The ability to use a single source of truth is the most important benefit of this pattern, but the trade-off gives us other benefits, too. Defining elements of our page as JavaScript code means that we can turn chunks of it into reusable components, preventing us from copying and pasting the same HTML in multiple places. If we need to change a component, we can make that change in one place and it will update everywhere in our application (or in many applications, if we’re publishing reusable components to other teams).

We can take these simple components and compose them together like LEGO bricks, creating more complex and useful components, without making them too confusing to work with. And if we’re using components built by others, we can easily update them when they release improvements or fix bugs without having to rewrite our code.

The downside: it’s JavaScript all the way down

All of those benefits do come at a cost. There are good reasons people value keeping HTML and JavaScript separate, and to get these other benefits, we need to combine them into one. As I mentioned before, moving away from simple HTML files complicates the workflow of someone who didn’t need to worry about JavaScript before. It may mean that someone who previously could make changes to an application on their own must now learn additional complex skills to maintain that autonomy.

There can also be technical downsides. For example, some tools like linters and parsers expect regular HTML, and some third-party imperative JavaScript plugins can become harder to work with. Also, JavaScript isn’t the best-designed language; it’s just what we happen to have in our web browsers. Newer tools and features are making it better, but it still has some pitfalls you need to learn about before you can be productive with it.

Another potential problem is that when the semantic structure of a page is broken up into abstract components, it can become easy for developers to stop thinking about what actual HTML elements are being generated at the end. Specific HTML tags like <section> and <aside> have specific semantic meanings that are lost when using generic tags like <div> and <span>, even if they look the same visually on a page. This is especially important for accessibility. For example, these choices will impact how screen reader software behaves for visually impaired users. It might not be the most exciting part, but JavaScript developers should always remember that semantic HTML is the most important part of a web page.

Use it if it helps you, not because it’s “what’s hot right now”

It’s become a trend for developers to reach for frameworks on every single project. Some people are of the mindset that separating HTML and JavaScript is obsolete, but this isn’t true. For a simple static website that doesn’t need much user interaction, it’s not worth the trouble. The more enthusiastic React fans might disagree with me here, but if all your JavaScript is doing is creating a non-interactive webpage, you shouldn’t be using JavaScript. JavaScript doesn’t load as fast as regular HTML, so if you’re not getting a significant developer experience or code reliability improvement, it’s doing more harm than good.

You also don’t have to build your entire website in React! Or Vue! Or Whatever! A lot of people don’t know this because all the tutorials out there show how to use React for the whole thing. If you only have one little complex widget on an otherwise simple website, you can use React for that one component. You don’t always need to worry about webpack or Redux or Gatsby or any of the other crap people will tell you are “best practices” for your React app.

For a sufficiently complex application, declarative programming is absolutely worth the trouble. It is a game changer that has empowered developers the world over to build amazing, robust and reliable software with confidence and without having to sweat the small stuff. Is React in particular the best possible solution to these problems? No. Will it just be replaced by the next thing? Eventually. But declarative programming is not going anywhere, and the next thing will probably just do it better.

What’s this I’ve heard about CSS-in-JS?

I’m not touching that one.

The post Why JavaScript is Eating HTML appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

How to Create an Animated Countdown Timer With HTML, CSS and JavaScript

Have you ever needed a countdown timer on a project? For something like that, it might be natural to reach for a plugin, but it’s actually a lot more straightforward to make one than you might think and only requires the trifecta of HTML, CSS and JavaScript. Let’s make one together!

This is what we’re aiming for:

Here are a few things the timer does that we’ll be covering in this post:

  • Displays the initial time remaining
  • Converts the time value to a MM:SS format
  • Calculates the difference between the initial time remaining and how much time has passed
  • Changes color as the time remaining nears zero
  • Displays the progress of time remaining as an animated ring

OK, that’s what we want, so let’s make it happen!

Step 1: Start with the basic markup and styles

Let’s start with creating a basic template for our timer. We will add an svg with a circle element inside to draw a timer ring that will indicate the passing time and add a span to show the remaining time value. Note that we’re writing the HTML in JavaScript and injecting into the DOM by targeting the #app element. Sure, we could move a lot of it into an HTML file, if that’s more your thing.

document.getElementById("app").innerHTML = ` <div class="base-timer">   <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">     <g class="base-timer__circle">       <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45" />     </g>   </svg>   <span>     <!-- Remaining time label -->   </span> </div> `;

Now that we have some markup to work with, let’s style it up a bit so we have a good visual to start with. Specifically, we’re going to:

  • Set the timer’s size
  • Remove the fill and stroke from the circle wrapper element so we get the shape but let the elapsed time show through
  • Set the ring’s width and color
/* Sets the containers height and width */ .base-timer {   position: relative;   height: 300px;   width: 300px; }  /* Removes SVG styling that would hide the time label */ .base-timer__circle {   fill: none;   stroke: none; }  /* The SVG path that displays the timer's progress */ .base-timer__path-elapsed {   stroke-width: 7px;   stroke: grey; }

Having that done we end up with a basic template that looks like this.

Step 2: Setting up the time label

As you probably noticed, the template includes an empty <span> that’s going to hold the time remaining. We will fill that place with a proper value. We said earlier that the time will be in MM:SS format. To do that we will create a method called formatTimeLeft:

function formatTimeLeft(time) {   // The largest round integer less than or equal to the result of time divided being by 60.   const minutes = Math.floor(time / 60);      // Seconds are the remainder of the time divided by 60 (modulus operator)   let seconds = time % 60;      // If the value of seconds is less than 10, then display seconds with a leading zero   if (seconds < 10) {     seconds = `0$ {seconds}`;   }    // The output in MM:SS format   return `$ {minutes}:$ {seconds}`; }

Then we will use our method in the template:

document.getElementById("app").innerHTML = ` <div class="base-timer">   <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">     <g class="base-timer__circle">       <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle>     </g>   </svg>   <span id="base-timer-label" class="base-timer__label">     $ {formatTime(timeLeft)}   </span> </div> `

To show the value inside the ring we need to update our styles a bit.

.base-timer__label {   position: absolute;      /* Size should match the parent container */   width: 300px;   height: 300px;      /* Keep the label aligned to the top */   top: 0;      /* Create a flexible box that centers content vertically and horizontally */   display: flex;   align-items: center;   justify-content: center;    /* Sort of an arbitrary number; adjust to your liking */   font-size: 48px; }

OK, we are ready to play with the timeLeft  value, but the value doesn’t exist yet. Let’s create it and set the initial value to our time limit.

// Start with an initial value of 20 seconds const TIME_LIMIT = 20;  // Initially, no time has passed, but this will count up // and subtract from the TIME_LIMIT let timePassed = 0; let timeLeft = TIME_LIMIT;

And we are one step closer.

Right on! Now we have a timer that starts at 20 seconds… but it doesn’t do any counting just yet. Let’s bring it to life so it counts down to zero seconds.

Step 3: Counting down

Let’s think about what we need to count down the time. Right now, we have a timeLimit value that represents our initial time, and a timePassed value that indicates how much time has passed once the countdown starts.

What we need to do is increase the value of timePassed by one unit per second and recompute the timeLeft value based on the new timePassed value. We can achieve that using the setInterval function.

Let’s implement a method called startTimer that will:

  • Set counter interval
  • Increment the timePassed value each second
  • Recompute the new value of timeLeft
  • Update the label value in the template

We also need to keep the reference to that interval object to clear it when needed — that’s why we will create a timerInterval variable.

let timerInterval = null;  document.getElementById("app").innerHTML = `...`  function startTimer() {   timerInterval = setInterval(() => {          // The amount of time passed increments by one     timePassed = timePassed += 1;     timeLeft = TIME_LIMIT - timePassed;          // The time left label is updated     document.getElementById("base-timer-label").innerHTML = formatTime(timeLeft);   }, 1000); }

We have a method that starts the timer but we do not call it anywhere. Let’s start our timer immediately on load.

document.getElementById("app").innerHTML = `...` startTimer();

That’s it! Our timer will now count down the time. While that’s great and all, it would be nicer if we could add some color to the ring around the time label and change the color at different time values.

Step 4: Cover the timer ring with another ring

To visualize time passing, we need to add a second layer to our ring that handles the animation. What we’re doing is essentially stacking a new green ring on top of the original gray ring so that the green ring animates to reveal the gray ring as time passes, like a progress bar.

Let’s first add a path element in our SVG element.

document.getElementById("app").innerHTML = ` <div class="base-timer">   <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">     <g class="base-timer__circle">       <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle>       <path         id="base-timer-path-remaining"         stroke-dasharray="283"         class="base-timer__path-remaining $ {remainingPathColor}"         d="           M 50, 50           m -45, 0           a 45,45 0 1,0 90,0           a 45,45 0 1,0 -90,0         "       ></path>     </g>   </svg>   <span id="base-timer-label" class="base-timer__label">     $ {formatTime(timeLeft)}   </span> </div> `;

Next, let’s create an initial color for the remaining time path.

const COLOR_CODES = {   info: {     color: "green"   } };  let remainingPathColor = COLOR_CODES.info.color;

Finally, let’s add few styles to make the circular path look like our original gray ring. The important thing here is to make sure the stroke-width is the same size as the original ring and that the duration of the transition is set to one second so that it animates smoothly and corresponds with the time remaining in the time label.

.base-timer__path-remaining {   /* Just as thick as the original ring */   stroke-width: 7px;    /* Rounds the line endings to create a seamless circle */   stroke-linecap: round;    /* Makes sure the animation starts at the top of the circle */   transform: rotate(90deg);   transform-origin: center;    /* One second aligns with the speed of the countdown timer */   transition: 1s linear all;    /* Allows the ring to change color when the color value updates */   stroke: currentColor; }  .base-timer__svg {   /* Flips the svg and makes the animation to move left-to-right */   transform: scaleX(-1); }

This will output a stroke that covers the timer ring like it should, but it doesn’t animate just yet to reveal the timer ring as time passes.

To animate the length of the remaining time line we are going to use the stroke-dasharray property. Chris explains how it’s used to create the illusion of an element “drawing” itself. And there’s more detail about the property and examples of it in the CSS-Tricks almanac.

Step 5: Animate the progress ring

Let’s see how our ring will look like with different stroke-dasharray values:

What we can see is that the value of stroke-dasharray is actually cutting our remaining time ring into equal-length sections, where the length is the time remaining value. That is happening when we set the value of stroke-dasharray to a single-digit number (i.e. 1-9).

The name dasharray suggests that we can set multiple values as an array. Let’s see how it will behave if we set two numbers instead of one; in this case, those values are 10 and 30.

stroke-dasharray: 10 30

That sets the first section (remaining time) length to 10 and the second section (passed time) to 30. We can use that in our timer with a little trick. What we need initially is for the ring to cover the full length of the circle, meaning the remaining time equals the length of our ring.

What’s that length? Get out your old geometry textbook, because we can calculate the length an arc with some math:

Length = 2πr = 2 * π * 45 = 282,6

That’s the value we want to use when the ring initially mounted. Let’s see how it looks.

stroke-dasharray: 283 283

That works!

OK, the first value in the array is our remaining time, and the second marks how much time has passed. What we need to do now is to manipulate the first value. Let’s see below what we can expect when we change the first value.

We will create two methods, one responsible for calculating what fraction of the initial time is left, and one responsible for calculating the stroke-dasharray value and updating the <path> element that represents our remaining time.

// Divides time left by the defined time limit. function calculateTimeFraction() {   return timeLeft / TIME_LIMIT; }      // Update the dasharray value as time passes, starting with 283 function setCircleDasharray() {   const circleDasharray = `$ {(     calculateTimeFraction() * FULL_DASH_ARRAY   ).toFixed(0)} 283`;   document     .getElementById("base-timer-path-remaining")     .setAttribute("stroke-dasharray", circleDasharray); }

We also need to update our path each second that passes. That means we need to call the newly created setCircleDasharray method inside our timerInterval.

function startTimer() {   timerInterval = setInterval(() => {     timePassed = timePassed += 1;     timeLeft = TIME_LIMIT - timePassed;     document.getElementById("base-timer-label").innerHTML = formatTime(timeLeft);          setCircleDasharray();   }, 1000); }

Now we can see things moving!

Woohoo, it works… but… look closely, especially at the end. It looks like our animation is lagging by one second. When we reach 0 a small piece of the ring is still visible.

This is due to the animation’s duration being set to one second. When the value of remaining time is set to zero, it still takes one second to actually animate the ring to zero. We can get rid of that by reducing the length of the ring gradually during the countdown. We do that in our calculateTimeFraction method.

function calculateTimeFraction() {   const rawTimeFraction = timeLeft / TIME_LIMIT;   return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction); }

There we go!

Oops… there is one more thing. We said we wanted to change the color of the progress indicator when when the time remaining reaches certain points — sort of like letting the user know that time is almost up.

Step 6: Change the progress color at certain points of time

First, we need to add two thresholds that will indicate when we should change to the warning and alert states and add colors for each of that states. We’re starting with green, then go to orange as a warning, followed by red when time is nearly up.

// Warning occurs at 10s const WARNING_THRESHOLD = 10; // Alert occurs at 5s const ALERT_THRESHOLD = 5;  const COLOR_CODES = {   info: {     color: "green"   },   warning: {     color: "orange",     threshold: WARNING_THRESHOLD   },   alert: {     color: "red",     threshold: ALERT_THRESHOLD   } };

Now, let’s create a method that’s responsible for checking if the threshold exceeded and changing the progress color when that happens.

function setRemainingPathColor(timeLeft) {   const { alert, warning, info } = COLOR_CODES;    // If the remaining time is less than or equal to 5, remove the "warning" class and apply the "alert" class.   if (timeLeft <= alert.threshold) {     document       .getElementById("base-timer-path-remaining")       .classList.remove(warning.color);     document       .getElementById("base-timer-path-remaining")       .classList.add(alert.color);    // If the remaining time is less than or equal to 10, remove the base color and apply the "warning" class.   } else if (timeLeft <= warning.threshold) {     document       .getElementById("base-timer-path-remaining")       .classList.remove(info.color);     document       .getElementById("base-timer-path-remaining")       .classList.add(warning.color);   } }

So, we’re basically removing one CSS class when the timer reaches a point and adding another one in its place. We’re going to need to define those classes.

.base-timer__path-remaining.green {   color: rgb(65, 184, 131); }  .base-timer__path-remaining.orange {   color: orange; }  .base-timer__path-remaining.red {   color: red; }

Voilà, there we have it. Here’s the demo again with everything put together.

The post How to Create an Animated Countdown Timer With HTML, CSS and JavaScript appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

Smaller HTML Payloads with Service Workers

Short story: Philip Walton has a clever idea for using service workers to cache the top and bottom of HTML files, reducing a lot of network weight.

Longer thoughts: When you’re building a really simple website, you can get away with literally writing raw HTML. It doesn’t take long to need a bit more abstraction than that. Even if you’re building a three-page site, that’s three HTML files, and your programmer’s mind will be looking for ways to not repeat yourself. You’ll probably find a way to “include” all the stuff at the top and bottom of the HTML, and just change the content in the middle.

I have tended to reach for PHP for that sort of thing in the past (<?php include('header.php); ?>), although these days I’m feeling much more jamstacky and I’d probably do it with Eleventy and Nunjucks.

Or, you could go down the SPA (Single Page App) route just for this basic abstraction if you want. Next and Nuxt are perhaps a little heavy-handed for a few includes, but hey, at least they are easy to work with and the result is a nice static site. The thing about these JavaScript-powered SPA frameworks (Gatsby is in here, too), is that they “hydrate” from static sites into SPAs as the JavaScript loads. Part of the reason for that is speed. No longer does the browser need to reload and request a whole big HTML page again to render; it just asks for whatever smaller amount of data it needs and replaces it on the fly.

So in a sense, you might build a SPA because you have a common header and footer and just want to replace the guts, for efficiencies sake.

Here’s Phil:

In a traditional client-server setup, the server always needs to send a full HTML page to the client for every request (otherwise the response would be invalid). But when you think about it, that’s pretty wasteful. Most sites on the internet have a lot of repetition in their HTML payloads because their pages share a lot of common elements (e.g. the <head>, navigation bars, banners, sidebars, footers etc.). But in an ideal world, you wouldn’t have to send so much of the same HTML, over and over again, with every single page request.

With service workers, there’s a solution to this problem. A service worker can request just the bare minimum of data it needs from the server (e.g. an HTML content partial, a Markdown file, JSON data, etc.), and then it can programmatically transform that data into a full HTML document.

So rather than PHP, Eleventy, a JavaScript framework, or any other solution, Phil’s idea is that a service worker (a native browser technology) can save a cache of a site’s header and footer. Then server requests only need to be made for the “guts” while the full HTML document can be created on the fly.

It’s a super fancy idea, and no joke to implement, but the fact that it could be done with less tooling might be appealing to some. On Phil’s site:

 on this site over the past 30 days, page loads from a service worker had a 47.6% smaller network payloads, and a median First Contentful Paint (FCP) that was 52.3% faster than page loads without a service worker (416ms vs. 851ms).

Aside from configuring a service worker, I’d think the most finicky part is having to configure your server/API to deliver a content-only version of your stuff or build two flat file versions of everything.

Direct Link to ArticlePermalink

The post Smaller HTML Payloads with Service Workers appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

What’s the Difference Between Width/Height in CSS and Width/Height HTML attributes?

Some HTML elements accept width and height as attributes. Some do not. For example:

<!-- valid, works, is a good idea --> <img width="500" height="400" src="..." alt="..."> <iframe width="600" height="400" src="..."></iframe> <svg width="20" height="20"></svg>  <!-- not valid, doesn't work, not a good idea --> <div width="40" height="40"></div> <span width="100" height="10"></span>

Those attributes are sometimes referred to as presentational attributes. The thing to know about them is that they are overridden by any other styling information whatsoever. That makes them ideal as a fallback.

So, if CSS loads and has a declaration like:

img {   width: 400px; }

…that is going to override the width="500" on the <img> tag above. Presentational attributes are the weakest kind of styling, so they are overridden by any CSS, even selectors with very low specificity.

What might be a smidge confusing is that presentational attributes seem like they would have high specificity. These inline styles, for instance, are very strong:

<img style="width: 500px; height: 400px;" src="..." alt="...">

Using an inline style (which works on any element, not a select few), we’ve moved from the weakest way to apply width and height to one of the strongest. Regular CSS will not override this, with a selector of any specificity strength. If we need to override them from CSS, we’ll need !important rules.

img {   width: 400px !important; }

To reiterate, presentational attributes on elements that accept them (e.g. <img>, <iframe>, <canvas>, <svg>, <video>) are a good idea. They are fallback sizing and sizing information as the page is loading. They are particularly useful on <svg>, which may size themselves enormously in an awkward way if they have a viewBox and lack width and height attributes. Browsers even do special magic with images, where the width and height are used to reserve the correct aspect-ratio derived space in a situation with fluid images, which is great for a smooth page loading experience.

But presentational attributes are also weak and are usually overridden in the CSS.

The post What’s the Difference Between Width/Height in CSS and Width/Height HTML attributes? appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

A Web Component with Different HTML for Desktop and Mobile

Christian Schaefer has a great big write-up about dealing with web advertisements. The whole thing is interesting, first documenting all the challenges that ads present, and then presenting modern solutions to each of them.

One code snippet that caught my eye was a simple way to design a component that renders different HTML depending on the screen size.

<div class="ad">   <template class="ad__mobile">     // Mobile ad HTML code with inline script   </template>   <template class="ad__desktop">     // Desktop ad HTML code with inline script   </template>   <script>     const isMobile = matchMedia('(max-device-width: 20em)').matches;     const ad = document.currentScript.closest('.ad');     const content = ad       .querySelector(isMobile ? '.ad__mobile' : '.ad__desktop')       .content;          ad.appendChild(document.importNode(content, true));   </script> </div> 

Clever. Although note that Christian ends up going a totally different route in the article.

Here’s that same code where I use a custom element and move the JavaScript to JavaScript just ‘cuz.

See the Pen
A Web Component with Different HTML for Desktop and Mobile
by Chris Coyier (@chriscoyier)
on CodePen.

The post A Web Component with Different HTML for Desktop and Mobile appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Why do we use .html instead of .htm?

Interesting question from Andy:

The most likely answer from the thread: DOS was a massive operating system for PCs for a long time and it had a three-character limit on file extensions.

Interesting that the first book on HTML covers this specifically:

Where my mind went was server software. I know that web servers automatically do different things with different file types. In a test on my own server (set up to serve a WordPress site), I put some files at the root that all contain the exact same content: <h1>Cool</h1>

  • file.text = file is rendered as plain text in browser (Content-Type: text/plain)
  • file.html = file renders as HTML in browser (Content-Type: text/html)
  • file.htm = file renders as HTML in browser (Content-Type: text/html)
  • file.fart = file is downloaded by browser (Content-Type: application/octet-stream)

You can write code to serve files with whatever content types you want, but in lieu of that, file extensions do matter because they affect how default web servers choose to serve file type headers.

The post Why do we use .html instead of .htm? appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]