Thursday, 8 September 2022

What’s New With Forms in 2022?

Browsers are constantly adding new HTML, JavaScript and CSS features. Here are some useful additions to working with forms that you might have missed…

requestSubmit()

Safari 16 will be the final browser to add support for requestSubmit.

Before we look at how .requestSubmit() works, let’s remind ourselves how programmatically submitting a form with JavaScript works when using the .submit() method. Submitting a form with submit() does not trigger a submit event. So in the following code, the form is submitted, preventDefault() has no effect, and nothing is logged to the console:

const form = document.forms[0];
form.addEventListener('submit', function(event) {
  // code to submit the form goes here
  event.preventDefault();
  console.log('form submitted!');
});

document.querySelector('.btn').addEventListener('click', function() {
  form.submit();
})

.submit() will also ignore any HTML form validation. Given the following markup, the form will be submitted when the input is empty even though the input has a required attribute:

<form>   
  <label for="name">Name</label>
  <input required name="name" id="name" type="text">
</form>

.requestSubmit() is an alternative way to submit a form using JavaScript, but in contrast to .submit(), HTML form validation will prevent the form from being submitted. If all the data entered in the form passes validation, the submit event will be fired, meaning “form submitted!” would be logged to the console in the following example:

form.addEventListener('submit', function(event) {
  event.preventDefault();
  console.log('form submitted!');
});

document.querySelector('.btn').addEventListener('click', function() {
  form.requestSubmit();
})

You could already achieve this by programmatically clicking the form’s submit button, but requestSubmit is perhaps a more elegant solution.

submitter property of submit event

The SubmitEvent.submitter property gained full cross-browser support with the release of Safari 15.4. This read-only property specifies the <button> or <input type="submit"> element that caused a form to be submitted.

<form>
  <button name="foo" value="bar" type="submit">Bar</button>
  <button name="foo" value="baz" type="submit">Baz</button>
</form>

When you have multiple submit buttons or inputs, each with a different value, only the value of the button or input that was clicked on to submit the form will be sent to the server, rather than both values. That’s nothing new. What is new is that the event listener for the submit event now has access to the event.submitter property. You can use this to add a class to the button or input that triggered the form submission, for example, or to obtain its value or any other of its HTML attributes.

document.forms[0].addEventListener('submit', function(event) {
  event.preventDefault();
  console.log(event.submitter.value);
  console.log(event.submitter.formaction);
  event.submitter.classList.add('spinner-animation');
})

formdata event

This isn’t particularly new, but only achieved cross-browser support with the release of Safari 15. The main use case for the formdata event is enabling custom elements to take part in form submissions. Outside of web components, though, it can still be useful.

You add a formdata event listener to the form you want to interact with:

document.querySelector('form').addEventListener('formdata', handleFormdata);

The event is fired both by a regular HTML form submission and also by an occurrence of new FormData(). event.formData holds all of the data being submitted.

function handleFormdata(event) {
  for (const entry of event.formData.values()) {
    console.log(entry);
  }
}

The callback function for the formdata event listener runs before the data is sent to the server, giving you a chance to add to or modify the data being sent.

function handleFormdata(event) {
  event.formData.append('name', 'John');
}

You could have modified or appended the FormData inside the submit event handler but formdata allows you to separate out the logic. It’s also an alternative to using hidden inputs in the markup of your form in cases where you are submitting the form “the old fashioned way” — i.e. relying on the built-in functionality of HTML to submit the form rather than doing it with fetch.

showPicker() for input elements

showPicker() has been supported since Chrome 99, Firefox 101, and in the upcoming Safari 16. For an input element whose type attribute is either Date, Month, Week, Time, datetime-local, color, or file, showPicker() provides a programmatic way to display the selection UI. For color and file inputs, it’s always been possible to programmatically show the picker by calling .click on the input:

document.querySelector('input[type="color"]').click();

That approach doesn’t work on date inputs, which is why this new API was added. .showPicker() will also work with color and file inputs but there’s no real advantage to using it over .click().

Datepicker open to August 2022.

Inert attribute

It’s always been possible to disable multiple inputs at once by wrapping them in a HTML fieldset and disabling the fieldset:

Inert is a new HTML attribute. It isn’t only for forms, but forms are certainly a key use-case. Unlike the disabled attribute, inert can be applied to a form element itself. Everything within the form will be non-focusable and non-clickable. When it comes to assistive technologies, inert is similar to setting aria-hidden="true". Unlike the disabled attribute, inert does not apply any styling by default, but it’s easy to add your own:

form[inert] {
  opacity: .2;
}

There’s more to come…

The big one is styling <select> elements, something developers have wanted for decades. It looks set to finally become a reality sometime soon with the introduction of selectmenu.

But that’s it for now! The recent updates bring full browser support to form features we’ve been waiting for, making them prime for production use.


What’s New With Forms in 2022? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Wednesday, 7 September 2022

Overlapping Bar Charts

As the name suggests, overlapping charts visualize two different sets of data in a single diagram. The idea is that the overlapping bars allow us to compare data, say, year-over-year. They are also useful for things like tracking progress for a goal where one bar represents the goal and the other shows the current amount.

But they’re beautiful too!

A two-by-two grid of overlapping chart examples.

Your mind is probably like mine and is already starting to figure out how you’d go off and code that. Here’s how I tackled it.

The HTML

We’re going to start with markup because, well, that’s how we know what needs styling.

<div class="container">
  <div class="chart">
    <dl class="numbers">
      <dd><span>100%</span></dd>
      <!-- all the way to 0% -->
    </dl>
    <dl class="bars">
      <div>
          <dt>2018</dt>
          <dd>
            <div class="bar" data-percentage="50"></div>
            <div class="bar overlap" data-percentage="53"></div>
          </dd>
        </div>
      <div>
      <!-- more bars -->
    </dl>
  </div>
</div>

We will be using description lists (<dl>) as it is a much more semantic approach as compared to standard ordered and unordered lists. Another reason is that we are including a label within each bar. Normal lists do not have a tag within them to add a title or description unlike definition lists. In simple terms, it just makes more sense and is more readable too.

The first description list, .numbers, is the y-axis. The .bars is where the data is visualized and I’ve made a definition list to build the x-axis as well. Each list item contains a .bar and the label as a description term (dt).

And what’s up with the data attribute? The data-percentage is being used to specify the height of the bar, which ultimately represents its value on the y-axis. We could manually set it in CSS for each bar, but that is repetitive and a lot of extra code that can be replaced with a few lines of CSS.

The basic chart styles

We’re working with a lot of two-dimensional directions, so flexbox is going to be our friend for getting everything lined up. We can make the .chart element a flexible container that positions the y-axis labels and the chart beside one another in the row direction.

.chart {
  display: flex;
}

We don’t even need to specify the direction since flexbox defaults to row. Let’s do that and then add flexbox to the list of labels along the y-axis while we’re at it since we know those will run in the column direction.

.numbers {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0 15px 0 0;
  padding: 0;
}

Believe it or not, we can use flexbox again for the bars since, they too, are running in a row direction.

.bars {
  display: flex;
  flex: auto; /* fill up the rest of the `.chart` space */
  gap: 60px;
}

I’ve set this up so that the .bars automatically take up whatever space is leftover by the y-axis .numbers.

You probably noticed it in the HTML, but “bar” is actually two bars where one overlaps the other. I wrapped those in a generic <div> that we can use as yet another flexible container that holds the definition term (<dt>) we’re using as a label and the description details (<dd>) that holds both bar values:

.bars > div {
  align-items: center;
  display: flex;
  flex-direction: column;
  flex: 1;
  position: relative;
}

Each bar is going to be the same width, hence flex: 1. We’re relatively positioning the element while we’re at it because we’re about to absolutely position each bar and we want to make sure they stay in their containers.

Each bar has a percentage height that corresponds to the values along the vertical y-axis. You may also remember that we gave each bar a data-percentage attribute — we’re going to sprinkle in a little JavaScript that sets the height of each bar using those values.

var bars = document.querySelectorAll("dd .bar");
bars.forEach((bar) => {
  var height = bar.getAttribute("data-percentage");
  bar.style.height = height + "%";
});

That’s our basic chart!

We want to get this to where we can see the bars overlapping one another. That’s next!

Overlapping bars

The trick to get one bar to overlap another is funny because we’re often trying to prevent things from overlapping visually in CSS. But in this case, we actually want that to happen.

The bars are already overlapping; it’s just tough to tell. Notice in the HTML that the second .bar in each set has an additional .overlap class. Let’s use that to differentiate the bars. You’re totally free to choose your own styling for this. I’m adding a little padding to the .overlap bars so that they are wider than the other bars. Then I’m tweaking the stacking order using z-index so that the .overlap bars sit below the other bars.

Let’s add a legend

Legend. Such a great word, isn’t it? Packed with all kinds of meaning. In this case, it’s a more than a nice touch because, visually, we’re jamming two bars in spaces that are typically reserved for one bar. A legend provides context that explains what each bar represents.

<figure class="legend">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

Using a <figure> feels correct to me. They’re often used to wrap images, but the spec says they’re used “to annotate illustrations, diagrams, photos, code listings, etc.” and we’re working with a diagram. We could probably use an unordered list to hold the items, but I went with an unsemantic <div>. If anyone has an opinion on the best way to mark this up, I’m all ears in the comments!

Once again, styling is totally up to you:

Accessibility considerations

We’ve spent a bunch of our effort on making decisions for the markup and styling of our overlapping bar chart. It’s great so far, but we’re definitely not done because there’s more we can do to make this a more accessible experience. Not everyone is a sighted web surfer, so there’s some additional work to do to convey the content in those contexts.

Specifically, we need to:

  1. check that our colors have plenty of contrast between them,
  2. allow keyboard users to tab to each overlapping bar, and
  3. make sure screen readers announce the content.

Color contrasts

We need enough contrast between:

  • the overlapping bars
  • the bars and the chart background
  • the label text and background

I did a little homework in advance on the colors I used in the examples we’ve look at so far, making sure that there is enough contrast between the foregrounds and backgrounds to achieve WCAG AA compliance.

Here’s what I’m using:

  • Overlapping bars: (#25DEAA and #696969: 3.16:1 ratio)
  • Bars and chart background (#696969 and #111: 3.43:1 ratio)
  • Y-axis label text and background (#fff and #333: 12.63: 1 ratio)

Tabbing between bars

To get this where keyboard users can select each individual bar with the Tab key, we can reach for the HTML tabindex attribute. We can use the following JavaScript inside the for-each function to add this property to each bar (both of them). We will set the tab index to 0:

bar.setAttribute("tabindex", 0);

We can also add some CSS to improve the outline when the bar is selected while we’re at it:

.bar:focus {
  outline: 1.5px solid #f1f1f1;
}

Announcing content on screen readers

Another important aspect of accessibility is making sure screen readers can announce the bars and their percentages.

We’re working with two different charts in one: a chart that shows “Estimated” values and another that shows “Actual” values. It’d be great if the user knew which bar was being announced, so let’s label them with the aria-label attribute:

<div class="bar" data-percentage="50" aria-label="Estimate">50%</div>

Notice that we have the bar’s value directly in the HTML as well. That will get announced, but we still want to visually hide it. We could use transparent text for that, but another way is to use the classic .visually-hidden trick by wrapping the value in span:

<div class="bar" data-percentage="50" aria-label="Estimate">
  <span class="visually-hidden">50%</span>
</div>
.visually-hidden {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

While we’re talking about announcing content, we can probably prevent the y-axis labels from being read. It’s not like the user is missing information, as the actual percentages for each bar are already available and announced. We can use the aria-hidden attribute for that:

<dl class="numbers" aria-hidden="true">
  <dd><span>100%</span></dd>
  <dd><span>80%</span></dd>
  <dd><span>60%</span></dd>
  <dd><span>40%</span></dd>
  <dd><span>20%</span></dd>
  <dd><span>0%</span></dd>
</dl>

I also think it’s OK for screen readers to ignore the legend since it’s a visual aid:

<figure class="legend" aria-hidden="true">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

The final demo

That’s a wrap!

There we go, a chart with overlapping bars! It’s a nice way to compare data and I hope you can find a use for it on some project.

Are there other ways we could have approached this? Of course! Everything we covered here is merely walking you through my thought process. I imagine some of you would have taken a different approach — if that’s you, please share! It’d be great to see other CSS layout techniques and perspectives on nailing the accessibility.


Overlapping Bar Charts originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Tuesday, 6 September 2022

Hacking CSS Animation State and Playback Time

CSS-only Wolfenstein is a little project that I made a few weeks ago. It was an experiment with CSS 3D transformations and animations.

Inspired by the FPS demo and another Wolfenstein CodePen, I decided to build my own version. It is loosely based on Episode 1 – Floor 9 of the original Wolfenstein 3D game.

Editor: This game intentionally requires some quick reaction to avoid a Game Over screen.

Here is a playthrough video:

In a nutshell, my project is nothing but a carefully scripted long CSS animation. Plus a few instances of the checkbox hack.

:checked ~ div { animation-name: spin; }

The environment consists of 3D grid faces and the animations are mostly plain 3D translations and rotations. Nothing really fancy.

However, two problems were particularly tricky to solve:

  • Play the “weapon firing” animation whenever the player clicks on an enemy.
  • When the fast-moving boss got the last hit, enter a dramatic slow motion.

At a technical-level, this meant:

  • Replay an animation when the next checkbox is checked.
  • Slow down an animation, when a checkbox is checked.

In fact, neither was properly solved in my project! I either ended up using workarounds or just gave up.

On the other hand, after some digging, eventually I found the key to both problems: altering the properties of running CSS animations. In this article, we will explore further on this topic:

  • Lots of interactive examples.
  • Dissections: how does each example work (or not work)?
  • Behind-the-scene: how do browsers handle animation states?

Let me “toss my bricks”.

Problem 1: Replaying Animation

The first example: “just another checkbox”

My first intuition was “just add another checkbox”, which does not work:

Each checkbox works individually, but not both together. If one checkbox is already checked, the other no longer works.

Here’s how it works (or “does not work”):

  1. The animation-name of <div> is none by default.
  2. The user clicks on one checkbox, animation-name becomes spin, and the animation starts from the beginning.
  3. After a while, the user clicks on the other checkbox. A new CSS rule takes effect, but animation-name is still spin, which means no animation is added nor removed. The animation simply continues playing as if nothing happened.

The second example: “cloning the animation”

One working approach is to clone the animation:

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2; }

Here’s how it works:

  1. animation-name is none initially.
  2. The user clicks on “Spin!”, animation-name becomes spin1. The animation spin1 is started from the beginning because it was just added.
  3. The user clicks on “Spin again!”, animation-name becomes spin2. The animation spin2 is started from the beginning because it was just added.

Note that in Step #3, spin1 is removed because of the order of the CSS rules. It won’t work if “Spin again!” is checked first.

The third example: “appending the same animation”

Another working approach is to “append the same animation”:

#spin1:checked ~ div { animation-name: spin; }
#spin2:checked ~ div { animation-name: spin, spin; }

This is similar to the previous example. You can actually understand the behavior this way:

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2, spin1; }

Note that when “Spin again!” is checked, the old running animation becomes the second animation in the new list, which could be unintuitive. A direct consequence is: the trick won’t work if animation-fill-mode is forwards. Here’s a demo:

If you wonder why this is the case, here are some clues:

  • animation-fill-mode is none by default, which means “The animation has no effect at all if not playing”.
  • animation-fill-mode: forwards; means “After the animation finishes playing, it must stay at the last keyframe forever”.
  • spin1’s decision always override spin2’s because spin1 appears later in the list.
  • Suppose the user clicks on “Spin!”, waits for a full spin, then clicks on “Spin again!”. At this moment. spin1 is already finished, and spin2 just starts.

Discussion

Rule of thumb: you cannot “restart” an existing CSS animation. Instead, you want to add and play a new animation. This may be confirmed by the W3C spec:

Once an animation has started it continues until it ends or the animation-name is removed.

Now comparing the last two examples, I think in practice, “cloning animations” should often work better, especially when CSS preprocessor is available.

Problem 2: Slow Motion

One might think that slowing an animation is just a matter of setting a longer animation-duration:

div { animation-duration: 0.5s; }
#slowmo:checked ~ div { animation-duration: 1.5s; }

Indeed, this works:

… or does it?

With a few tweaks, it should be easier to see the issue.

Yes, the animation is slowed down. And no, it does not look good. The dog (almost) always “jumps” when you toggle the checkbox. Furthermore, the dog seems to jump to a random position rather than the initial one. How come?

It would be easier to understand it if we introduced two “shadow elements”:

Both shadow elements are running the same animations with different animation-duration. And they are not affected by the checkbox.

When you toggle the checkbox, the element just immediately switches between the states of two shadow elements.

Quoting the W3C spec:

Changes to the values of animation properties while the animation is running apply as if the animation had those values from when it began.

This follows the stateless design, which allows browsers to easily determine the animated value. The actual calculation is described here and here.

Another Attempt

One idea is to pause the current animation, then add a slower animation that takes over from there:

div {
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

So it works:

… or does it?

It does slow down when you click on “Slowmo!”. But if you wait for a full circle, you will see a “jump”. Actually, it always jumps to the position when “Slowmo!” is clicked on.

The reason is we don’t have a from keyframe defined – and we shouldn’t. When the user clicks on “Slowmo!”, spin1 is paused at some position, and spin2 starts at exactly the same position. We simply cannot predict that position beforehand … or can we?

A Working Solution

We can! By using a custom property, we can capture the angle in the first animation, then pass it to the second animation:

div {
  transform: rotate(var(--angle1));
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  transform: rotate(var(--angle2));
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

@keyframes spin1 {
  to {
    --angle1: 360deg;
  }
}

@keyframes spin2 {
  from {
    --angle2: var(--angle1);
  }
  to {
    --angle2: calc(var(--angle1) + 360deg);
  }
}

Note: @property is used in this example, which is not supported by all browsers.

The “Perfect” Solution

There is a caveat to the previous solution: “exiting slowmo” does not work well.

Here is a better solution:

In this version, slow motion can be entered or exited seamlessly. No experimental feature is used either. So is it the perfect solution? Yes and no.

This solution works like “shifting” “gears”:

  • Gears: there are two <div>s. One is the parent of the other. Both have the spin animation but with different animation-duration. The final state of the element is the accumulation of both animations.
  • Shifting: At the beginning, only one <div> has its animation running. The other is paused. When the checkbox is toggled, both animations swap their states.

While I really like the result, there is one problem: it is a nice exploit of the spin animation, which does not work for other types of animations in general.

A Practical Solution (with JS)

For general animations, it is possible to achieve the slow motion function with a bit of JavaScript:

A quick explanation:

  • A custom property is used to track the animation progress.
  • The animation is “restarted” when the checkbox is toggled.
  • The JS code computes the correct animation-delay to ensure a seamless transition. I recommend this article if you are not familiar with negative values of animation-delay.

You can view this solution as a hybrid of “restarting animation” and the “gear-shifting” approach.

Here it is important to track the animation progress correctly. Workarounds are possible if @property is not available. As an example, this version uses z-index to track the progress:

Side-note: originally, I also tried to create a CSS-only version but did not succeed. While not 100% sure, I think it is because animation-delay is not animatable.

Here is a version with minimal JavaScript. Only “entering slowmo” works.

Please let me know if you manage to create a working CSS-only version!

Slow-mo Any Animation (with JS)

Lastly, I’d like to share a solution that works for (almost) any animation, even with multiple complicated @keyframes:

Basically, you need to add an animation progress tracker, then carefully compute animation-delay for the new animation. However, sometimes it could be tricky (but possible) to get the correct values.

For example:

  • animation-timing-function is not linear.
  • animation-direction is not normal.
  • multiple values in animation-name with different animation-duration’s and animation-delay’s.

This method is also described here for the Web Animations API.

Acknowledgments

I started down this path after encountering CSS-only projects. Some were delicate artwork, and some were complex contraptions. My favorites are those involving 3D objects, for example, this bouncing ball and this packing cube.

In the beginning, I had no clue how these were made. Later I read and learned a lot from this nice tutorial by Ana Tudor.

As it turned out, building and animating 3D objects with CSS is not much different from doing it with Blender, just with a bit different flavor.

Conclusion

In this article we examined the behavior of CSS animations when an animate-* property is altered. Especially we worked out solutions for “replaying an animation” and “animation slow-mo”.

I hope you find this article interesting. Please let me know your thoughts!


Hacking CSS Animation State and Playback Time originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Monday, 5 September 2022

Flutter For Front-End Web Developers

I started as a front-end web developer and then became a Flutter developer. I think there were some concepts that helped me adopt Flutter easier. There were also some new concepts that were different.

In this article, I want to share my experience and inspire anyone feeling paralyzed with choosing one ecosystem over the other by showing how concepts transfer over and any new concepts are learnable.

Concepts That Transferred Over

This section shows places where front-end web development and Flutter resemble. It explains skills that you already have that are an advantage to you if you start Flutter.

1. Implementing User Interfaces (UIs)

To implement a given UI in front-end web, you compose HTML elements and style them with CSS. To implement UIs in Flutter, you compose widgets and style them with properties.

Like CSS, the Color class in Dart works with “rgba” and “hex”. Also like CSS, Flutter uses pixels for space and size units.

In Flutter, we have Dart classes and enums for almost all CSS properties and their values. For example:

Flutter also has Column and Row widgets. These are the Flutter equivalent for display: flex in CSS. To configure justify-content and align-items styles, you use MainAxisAlignment and CrossAxisAlignment properties. To adjust the flex-grow style, wrap the affected child(ren) widget(s) of the Column/Row, in an Expanded or Flexible.

For the advanced UIs, Flutter has the CustomPaint class – it is to Flutter what the Canvas API is to web development. CustomPaint gives you a painter to draw any UI as you wish. You will usually use CustomPaint when you want something that is really complex. Also, CustomPaint is the go-to way when a combination of widgets doesn’t work.

2. Developing For Multiple Screen Resolutions

Websites run on browsers and mobile apps run on devices. As such, while developing for either platform, you have to keep the platform in mind. Each platform implements the same features (camera, location, notifications, etc.) in different ways.

As a web developer, you think about your website’s responsiveness. You use media queries to handle what your website looks like in smaller and wider screens.

Coming over from mobile web development to Flutter, you have the MediaQuery helper class. The MediaQuery class gives you the current device orientation (landscape or portrait). It also gives you the current viewport size, the devicePixelRatio, among other device info. Together, these values give you insights about the mobile device’s configuration. You can use them to change what your mobile app looks like at various screen sizes.

3. Working with Debuggers, Editors, and Command Line Tools

Desktop browsers have developer tools. These tools include an inspector, a console, a network monitor, etc. These tools improve the web development process. Flutter too has its own DevTools. It has its widget inspector, debugger, network monitor, among other features.

IDE support is also similar. Visual Studio Code is one of the most popular IDE for web development. There are many web-related extensions for VS Code. Flutter too supports VS Code. So while transitioning, you don’t need to change IDE. There are Dart and Flutter extensions for VS Code. Flutter also works well with Android Studio. Both Android Studio and VS Code support Flutter DevTools. These IDE integrations make Flutter tooling complete.

Most front-end JavaScript frameworks come with their command-line interface (CLI). For example: Angular CLI, Create React App, Vue CLI, etc. Flutter also comes with an exclusive CLI. The Flutter CLI permits you to build, create, and develop Angular projects. It has commands for analyzing and testing Flutter projects.

Concepts That Were New

This section talks about Flutter-specific concepts that are easier or non-existent in web development. It explains ideas you should keep in mind as you enter Flutter.

How To Handle Scrolling

When developing for the web, default scrolling behavior is handled by web browsers. Yet, you are free to customize scrolling with CSS (using overflow).

This is not the case in Flutter. Widget groups don’t scroll by default. When you sense that widget groups might overflow, you have to proactively configure scrolling.

In Flutter, you configure scrolling by using peculiar widgets that permit scrolling. For example: ListView, SingleChildScrollView, CustomScrollView, etc. These scrollable widgets give you great control over scrolling. With CustomScrollView, you can configure expert and complex scroll mechanisms within the application.

On Flutter’s side, using ScrollViews is inevitable. Android and iOS have ScrollView and UIScrollView to handle scrolling. Flutter needs a way to unify the rendering and developer experience by using its ScrollViews, too.

It may help to stop thinking about the flow of document structure and instead consider the application as an open canvas for a device’s native painting mechanisms.

2. Setting Up Your Development Environment

To create the simplest website, you can create a file with a .html extension and open it in a browser. Flutter is not that simple. To use Flutter, you need to have installed the Flutter SDK and have configured Flutter for a test device. So if you want to code Flutter for Android, you need to set up the Android SDK. You will also need to configure at least one Android device (an Android Emulator or a physical device).

This is the same case for Apple devices (iOS and macOS). After installing Flutter on a Mac, you still need to set up Xcode before going further. You will also need at least an iOS simulator or an iPhone to test Flutter on iOS. Flutter for desktop is also a considerable setup. On Windows, you need to set up the Windows Development SDK with Visual Studio (not VS Code). On Linux, you will install more packages.

Without extra setup, Flutter works on browsers. As a result, you could overlook the extra setup for target devices. In most cases, you would use Flutter for mobile app development. Hence, you would want to setup at least Android or iOS. Flutter comes with the flutter doctor command. This command reports the status of your development setup. That way, you know what to work on, in the setup, if need be.

This doesn’t mean that development in Flutter is slow. Flutter comes with a powerful engine. The flutter run command permits hot-reloading to the test device while coding. But then you will need to press R to actually hot-reload. This is not an issue. Flutter’s VS Code extension permits auto-hot-reload on file changes.

3. Packaging and Deployment

Deploying websites is cheaper and easier compared to deploying mobile applications. When you deploy websites, you access them through domain names. These domain names are usually renewed annually. However, they are optional.

Today, many platforms offer free hosting.

For example: DigitalOcean gives you a free subdomain on .ondigitalocean.com.

You can use these domains if you are building a documentation website. You can also use them when you are not worried about branding.

In Flutter’s world with mobile applications, you usually in most cases deploy your app to two places.

You have to register a developer account on each of these platforms. Registering a developer account requires a fee or subscription and identity verification.

For App Store, you need to enroll for the Apple Developer program. You need to maintain an annual subscription of $99. For Google Play, you need to make a one-time $25 payment for the account.

These stores review every app reviewed before it goes live.

Also bear in mind that users don’t easily consume app updates. Users must explicitly update installed applications. This is in contrast to the web where everyone just gets to see the latest deployed version of a website.

Managing deployed applications is relatively more demanding than managing deployed websites. However, this shouldn’t scare you. After all, there are millions of apps deployed on either stores so you can add yours, too.

Additional Thoughts On Flutter

Flutter is a cross-platform tool to build desktop, mobile, or web applications. Flutter apps are pixel-perfect. Flutter paints the same UI on each app irrespective of the target platform. This is because each Flutter app contains the Flutter engine. This engine renders the Flutter UI code. Flutter provides a canvas for each device and allows you to paint as you want. The engine communicates with the target platform to handle events and interactions.

Flutter is efficient. It has high-performance levels. This is because it is built with Dart and it leverages Dart’s features.

With these many benefits, Flutter is a good choice for many applications. Cross-platform apps save money and time during production and maintenance. However, Flutter (and cross-platform solutions) might not be an optimum choice in some cases.

Don’t use Flutter if you want users to use platform developer tools with your application. Platform developer tools here mean device-specific tools like Android developer options. It also includes browser developer tools.

Don’t use Flutter for web if you expect browser extensions to interact with the website.

Also, don’t use Flutter for content-heavy websites.

Conclusion

This was a review of skills that carry over from front-end web development to working with Flutter. We also discussed app development concepts that you have to learn as a web developer.

Flutter is simpler for web developers because they both involve implementing UIs. If you start Flutter, you will find out that it gives you a good developer experience. Give Flutter a try! Use it to build mobile apps and of course, showcase what you build.

Cheers!


Flutter For Front-End Web Developers originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Thursday, 1 September 2022

Behind the CSScenes, September 2022

Those of you who have been reading CSS-Tricks for a while may remember that we used to publish a little thing we called CSS-Tricks Chronicles. Our friend Chris Coyier would write up a reflection from the past couple of months or so, and it was a great way to get a pulse on what’s happening around CSS-Tricks, the site, and what the team is doing.

We like that and want to keep it going. It’s a new era, though! So what we’re going to do is welcome you back to what we’re now calling Behind the CSScenes. You’re going to meet some new and familiar faces in these updates, starting with Haley Mills, who is kicking off the very first issue.

How’s the transition going?

[Haley Mills:] Before we dive in, let me start by introducing myself! My name is Haley, and I’m the manager of Content Integration here at DigitalOcean. I’ve been at DigitalOcean for 5 years and previously worked on our editorial team, helping authors publish all sorts of topics through our Write For DOnations program. 

Many folks here at DigitalOcean (including myself) are avid readers of CSS-Tricks, and we still have to pinch ourselves for how lucky we are to be entrusted with this community. We recognize that CSS-Tricks is a critical free resource for devs across the world, and my goal is to keep it that way. 

  • Since the acquisition, we have published 95 pieces of new content and look forward to growing that number.
  • In the month of August, we performed maintenance on 6 existing pieces of content.

That said, change is to be expected when passing a torch.

I think we all know that no one can replace Chris’ voice — it’s a big reason why CSS-Tricks is, well, CSS-Tricks. His ability to have you laughing while learning something new is a skill that few can compete with. I know many of you miss his writing because you told us so in a survey (which we’ll get to in a bit), but it also opens up a huge opportunity for us all to take the torch and continue doing what CSS-Tricks does best:

Find creative solutions to problems and share them with the world. Chris brought people together this way on CSS-Tricks — and you can give back, too.

Your blossoming idea could turn out to be what the Flexbox Guide is for me and so many other people, so I humbly encourage you to reach out in our Guest Writing Form and talk to us about your topic ideas. We have two awesome editors, Geoff and Brad, to help you shape and bring your ideas to life to share with the CSS-Tricks community. In addition to paying you for your contribution, we will now also make a matching donation to a tech-focused charity of your choice.

Next up, we have Product Manager Karen Degi with some survey result highlights.

The results are in…

[Karen Degi:] In June, we shared a survey to collect feedback to help shape the future of CSS-Tricks. We received almost 900 responses, including some great written responses that helped us understand what CSS-Tricks means to the larger community. 

Many of you also volunteered to talk to us directly, which has us thinking about the best way to gather those thoughts. If you’re one of those folks, know that we haven’t forgotten about you and still want to hear from you. We just want to make sure we approach this in the most effective way!

The survey confirmed some things we already suspected and brought new things to our attention. The top few things that grabbed our attention are:

  • Engaging, high-quality content is at the heart of CSS-Tricks. We’re working to make sure that we continue investing in in-depth guides on front-end topics, as well as providing short articles about quick tricks and tutorials with embedded demos.
  • You love RSS! As we continue investing in CSS-Tricks and bringing new functionality, we’ll make sure we keep an eye on how our changes affect the RSS feed.
  • You come to CSS-Tricks to learn, to be entertained, and to do your jobs better. You do not come to CSS-Tricks because you’re excited about being sold…well, anything, really. Although we think DigitalOcean is pretty great, and we’ll probably continue to talk about ourselves where it makes sense, we understand that we need to do so in a way that is honest, trustworthy, and connected to your needs as a front-end enthusiast.

Next up is Logan Liffick, Senior Digital Experience Designer, with redesign updates.

A redesign is in the works!

[Logan Liffick:] If you’ve worked on the front end — or really anywhere on the web, you’re bound to know CSS-Tricks. It’s where I, and many others, started the journey. So, when I was asked to spearhead a redesign for the site, it was nothing short of an honor. Without a doubt, undertaking a brand update for something so familiar to so many is a challenge of incredible magnitude

If I were to do justice to this project, I’d need to pay tribute to the original. That mentality became the underlying theme of my work, and any effort to rejuvenate took inspiration from existing patterns and styles from the site.

  • Slideshow of Redesign Preview

Upon first glance, you’ll notice the fresh coat of paint. Past that, you’ll recognize the site reads more “editorial” than before. This was a purposeful decision to accentuate existing type stylings and, more importantly, to pay homage to the essence of CSS-Tricks as an informational resource. 

Preserving the element of “fun” was also top of mind. Sprinkled throughout the site are various snippets from the actual CSS “tricks” shared on this site — for example, there’s going to be a little Easter egg tucked inside a sticky footer using Preethi’s slide-out effect that’s my personal favorite, a fantastic suggestion from Geoff himself. Gradients are now a core color-way in the system, and border-radii have been rounded out. 

We wanted to give ourselves permission and space to explore an open-ended and malleable system far into the future, which lines up nicely with the overall mission and goal of CSS-Tricks: to explore what’s possible with CSS. This is just the beginning, there’s so much more to see, do, and learn with CSS-Tricks living in our (digital) ocean.

Next is Geoff with author highlights!

New authors!

[Geoff:] We’ve added a few new faces to our growing list of guest authors who have contributed to CSS-Tricks:

You may have also seen our editor Bradley Kouchi’s name pop up a couple of times, and you can expect to continue seeing him on a semi-regular basis.

That’s 16 new authors! You can be one, too, by filling out our guest writing form.

On a related note, I’m pleased as punch that we still get regular contributions from a large band of familiar faces from before the DigitalOcean acquisition. Just look at all the fine folks who’ve continued to share their great ideas with us:

Big shake-ups like the one we’re going through today can be scary. Seeing these familiar names in article bylines has helped me a ton as far as continuity and consistency go. CSS-Tricks still seems very CSS-Tricks-y to me, and that’s a big deal.

Until next time…

We hope you’ve enjoyed this little peek behind the CSScenes! We’ll do it again… and again and again. As you can tell, there’s a lot of activity happening around here, which means we’ll have lots to share in the next edition.

Oh, and if you’re one of the many who’ve told us just how much you miss the newsletter, it’s still here! We’re sending it just once a month while we get back in the swing of things, and you may very well need to re-subscribe to get it (we had to do a lot of scrubbing after the keys to the site were handed over).

Thanks for reading!


Behind the CSScenes, September 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Comparing JAWS, NVDA, and VoiceOver

A screen reader is an important accessibility tool for people with no or limited vision. People who are blind or those with low vision can use a screen reader to navigate the computer. Screen readers will read contents on the screen and explain to the user what is on the page. Screen readers allow people to use the computer for daily tasks.

There are many screen reader software available for people through their operating system or through open source projects.

A 2021 research by WebAim found that from 1568 responders, more than 53.7 percent of people surveyed used JAWS on Windows, more than 30.7 percent of people used NVDA on Windows and little over 6.5 percent of people used VoiceOver on macOS.

JAWS and NVDA for Windows and VoiceOver for macOS are the most popular screen readers people use.

First, I should clarify that this article will be written from my point of view. To give background, I have been a front-end developer at a non-profit for people with learning differences for over three years. I, along with my colleagues, seek to make our projects more accessible every day. I am not visually impaired and do not use these tools on a regular basis. For work, I have a Mac machine and test accessibility using VoiceOver.

Here is my planned testing methodology:

  1. Navigate the page by heading, until “Accessibility APIs” section.
  2. In the “Accessibility APIs” section, read the content and the unordered list inside.
  3. TAB to hear focusable items in the unordered list.
  4. Jump to the Search field.
  5. TAB to hear a few items in the navigation section

To find similarities and differences between them, I decided to test a set of steps with each screen reader on a Wikipedia page about screen readers. I will browse the web with Chrome for my tests. Testing all screen readers on the same page and browser will reduce the amount of variables and keep the tests consistent.

JAWS

JAWS is an acronym for Job Access With Speech and is the most widely used screen reader in the world. It is only available on Windows. Depending on the plan and features, JAWS can be purchased anywhere from $90 yearly license all the way to $1605 for perpetual license.

JAWS has predefined keyboard commands to navigate the web. Full list of keyboard commands can be found on their website.

Demonstration

JAWS Demo

In the beginning of the demo, I am clicking on H key on my keyboard to go to the next heading. JAWS is moving down the page, reading me the headings along with their level.

Later in the video, I am clicking on number 2 and number 3 on my keyboard to have JAWS read Heading Levels 2s then later Heading Levels 3s. This is a great feature because we can move down the page and sections by heading level and get a better sense of the page layout.

When I reach the “Accessible APIs” section, I press the DOWN ARROW key until the third item in the unordered list.

Later in the demo, I am clicking on the TAB key for JAWS to read to me the next focusable item on the page, which is inside this list. I click TAB until I reach a focusable element in another section.

Then I press F key to focus on the search field, which JAWS reads to me.

Then I click on TAB and JAWS focuses on the navigation elements that are on the side of the page.

Pros & Cons

Pros:

  • JAWS is more customizable than other screen readers.
  • There are more options to navigate through the page.
  • JAWS is industry standard.
  • Widely used, which means there are lots of user to user support.

Cons:

  • JAWS is more complicated to use than NVDA or VoiceOver.
  • Some commands are not intuitive.
  • There are a lot more commands for the user to learn.
  • More learning curve for users.
  • JAWS is also not available on the Mac, which limits its users.
  • Costs anywhere between $90 – $1605 for the user.
  • JAWS has different key commands for desktop and laptop which may make it harder for users to transfer knowledge and may cause confusion.

NVDA

NVDA, or NonVisual Digital Access, is available on Windows only. Users need to download the software from NVDA’s website, NVAccess. This software is free to download but does not come already installed on Windows machines. NVDA is the second most popular screen reader in the world according to WebAim’s 2021 survey.

Like other screen readers, NVDA has defined keyboard commands to navigate the web. NVDA’s full keyboard commands can be found on their website.

Demonstration

NVDA Demo

In the demo I am clicking on H key on the keyboard to go to the next heading. First, NVDA reads me Heading Level 1, which is “Screen reader”. Then NVDA goes to read Heading Level 2s and 3s.

When I reach “References” I begin to click on TAB on my keyboard for NVDA to focus on next focusable items.

After focusing on a few items on the list, I click ENTER and go to the New York Times page.

Pros & Cons

Pros:

  • Overall, I found NVDA was able to provide me with information on the screen.
  • The out-of-the-box keyboard commands were easy to use and easy to learn.
  • NVDA is open source, which means the community can update and fix.
  • NVDA is free, which makes it an affordable option to Windows users.

Cons:

  • NVDA is not available on the Mac, which limits its users.

VoiceOver

VoiceOver is the screen reader used in Mac. VoiceOver is only available on Mac not available in Windows. VoiceOver is free and is already installed on the computer, which removes barriers because this is part of the computer setup and the user does not have to download or purchase any additional software.

VoiceOver has defined keyboard commands to navigate the web. VoiceOver’s full keyboard commands can be found on their website.

Demonstration

VoiceOver Demo

In the demo, I am on a Wikipedia page and I am clicking on the VoiceOver Command (which is Control+Option) along with Command+H to navigate through the headings. VoiceOver reads the headings in order, starting from Heading Level 1, “Screen Reader”, to Heading Level 2, “Contents”, to Heading Level 3, and so on.

When I reach the “Accessibility APIs” section, I click on VoiceOver Command plus the RIGHT ARROW, to tell VoiceOver that I want it to read this section. Later I am clicking on the VoiceOver Command plus the RIGHT ARROW on my keyboard, to navigate the section.

When I get on to the third item on the unordered list, I press TAB on my keyboard to focus on the next focusable element.

I press TAB a few times, then I press VoiceOver Command plus U, to open the Form Control Menu. In the menu, I press DOWN ARROW until I hear the “Search Wikipedia” option. When I hear it, I click ENTER and the screen reader focuses on the form field. In the form field, I press TAB to navigate to the navigation section.

Pros & Cons

Pros:

  • VoiceOver is easy to use and learn.
  • VoiceOver’s commands are intuitive.
  • Free tool that comes installed in every macOS device.

Cons:

  • VoiceOver is also not available on Windows, which limits its users.
  • VoiceOver is not an app and can only be updated when Apple releases macOS update.

Key Takeaways

A screen reader is an important accessibility tool for people with no or limited vision. Screen readers allow people to use the computer for daily tasks.

There are many screen reader softwares available. In this article I compared JAWS, NVDA, and VoiceOver.

Here is a comparison chart overview of the three screen readers:

JAWS NVDA VoiceOver
Operating System Windows Windows macOS
Price $90 – $1695 Free Free
# of users 30% 50% 6%
Ease of Use Hard Easy Easy

I found that for basic screen reader testing, most screen readers follow a similar keystroke pattern and knowledge from one screen reader can be used for others.

All screen readers have their pros and cons. Ultimately, it’s up to user preference and also the operating system they use to determine which screen reader software is best for them.

Previously: “Small Tweaks That Can Make a Huge Impact on Your Website’s Accessibility” (2018), and “Why, How, and When to Use Semantic HTML and ARIA” (2019), “15 Things to Improve Your Website Accessibility” (2020), “5 Accessibility Quick Wins You Can Implement Today” (2022).


Comparing JAWS, NVDA, and VoiceOver originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

iShadeed’s Container Queries Lab

Ahmad Shadeed got an early jump on container queries and has a growing collection of examples based on everyday patterns.

And, if you missed it, his latest post on container queries does a wonderful job covering how they work since landing in Chrome 105 this month (we’ll see them in Safari 16 soon). Some choice highlights and takeaways:

  • Containers are defined with the container-type property. Previous demos and proposals had been using contain instead.
  • Container queries are very much like the media queries we’ve been writing all along to target the viewport size. So, rather than something like @media (min-width: 600px) {}, we have @container (min-width: 600px) {}. That should make converting many of those media queries to container queries fairly straightfoward, minus the work of figuring out the new breakpoint values.
  • We can name containers to help distinguish them in our code (e.g. container-name: blockquote).

Great job, Ahmad! And thanks for sharing!

To Shared LinkPermalink on CSS-Tricks


iShadeed’s Container Queries Lab originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



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

Passkeys: What the Heck and Why?

These things called  passkeys  sure are making the rounds these days. They were a main attraction at  W3C TPAC 2022 , gained support in  Saf...