14-day Cloud trial
Start today. For free.

One editor. 50+ features. Zero constraints. After your trial, retain the advanced features.

Try Professional Plan for FREE
PricingContact Us
Log InGet Started Free

How HTML focus works in rich text editors

March 2nd, 2022

8 min read

How HTML focus works in rich text editors.

Written by

Keanan Koppenhaver

Category

Developer Insights

Rich text editors are a commonly requested feature among the users of data-driven applications. In many cases, what would be considered ‘simple text’ input can be made more powerful by using a rich text editor – especially when users want (or need) that level of control.

With a rich text editor, users can easily add basic text formatting and sometimes more complicated things like tables, embedded images, or links – depending on the capability of the editor itself.

Rich text editors offer more features and functionality compared to only the textarea element.

It’s this level of functionality that’s being increasingly expected by end users, and leaves developers with a choice: buy an off-the-shelf library or tool,try to build their own rich text editor from scratch, or buy third-party components (like a rich text editor) and customize/code additional requirements in house.

HTML focus and rich text editor complexity

An important  thing to consider is  how difficult even the most basic features of a rich text editor are to implement. 

HTML focus, in particular, is a feature that can be difficult to get right. There are a ton of edge cases, such as textarea focus, to account for and workarounds you’ll need to implement to provide the level of functionality that many users consider as ‘essential’ in a rich text editor. 

Need more information on the complexities of building rich text editors?

Read our white paper – ‘The Great Debate: Buy or Build Rich Text Editors’ – for a complete breakdown of the requirements needed to build a basic rich text editor

On top of that, you’ll want to make sure your editor is accessible for those people who are using assistive devices, or working in non-traditional computing environments.

In this article, we'll take a look at how HTML focus functionality works in text editors, why it can be a complex challenge to solve if you're building an editor yourself, and how some prebuilt editors handle this complex functionality.

What is HTML ‘focus’ in a rich text editor?

Focus, in a web context, is used to determine which element the user is currently trying to interact with. It’s the element that receives keyboard events (and other similar ones) by default

For example, when a user types on their keyboard, the input that’s currently ‘in focus’ is where the text will display. If they press the tab key,click another element, or even when JavaScript is triggered, the event can cause the focus to change. The complication occurs when a user writes in a rich text editor, and they expect the focus to stay on that element – even if they take an action that would otherwise change the focus on a traditional browser element, such as textarea focus.

Focus and accessibility

In addition to being a large factor in the overall user experience of an application, managing focus is an important concern for the accessibility of your application. 

Many screen readers and other assistive devices use focus to determine which information needs to be presented to the user, in addition to where to place their input. Applications that use non-traditional methods of focus, or that create their user interfaces through CSS tricks or other methods, can throw a wrench into this process. However, just as there are CSS tricks to build an interface that is not as accessible as possible, there are several CSS tricks that can improve accessibility.

Rich text editors can also provide accessibility checking, if they are sufficiently advanced, and control over focus.

Complex rich text editor focus cases

On the surface, maintaining HTML focus on an element is relatively straightforward. However, as the interface for your application starts to get more complex, edge cases start to pop up, since the behavior isn’t normalized across different browsers. 

For example, most rich text editors have a toolbar with controls that allow the user to manipulate the text they're entering. Normally, a click on the toolbar would be an event that takes focus away from the text input and places it instead on the clicked toolbar. In some browsers, this can cause a problem where the formatting that the user selected won’t be applied, because the focus is no longer on the content area.

On the other hand, some browsers might leave the focus on the toolbar element after the user has clicked a formatting button, which requires the user to click the textbox before they can start typing again. Neither of these are great or intuitive user experiences, since most actions in the formatting toolbar are performed quickly, and the user immediately continues entering more text. And, different browser behavior makes it difficult to correct.

Browser edge cases make focus more difficult to control

The following example may make this clearer. Take a look at the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="toolbar">
        <button id="boldButton">Bold</button>
      </div>
      <div id="editor" contenteditable="true" role="textbox" style="margin-top: 10px; border: 1px solid gray; padding: 10px; border-radius: 5px;">
          Start Editing...
      </div>
    <script>
        const editor = document.getElementById('editor')
        const boldButton = document.getElementById('boldButton');

        boldButton.addEventListener('click', function () {
            document.execCommand('bold', false, null);
        });

    </script>
</body>
</html>

You have a simple contenteditable div along with a bold button that uses execCommand to make the selected text bold.

If you test this in Firefox, you’ll notice that after making the selection bold, you need to re-click the text field, because Firefox leaves the focus on the bold button. On the other hand, in Safari and Chromium-based browsers, the focus automatically shifts back to the text field.

(Note: this was tried in Firefox 95.0.2 and Chromium 97; your mileage may vary if you’re using different versions.)

Further complications with focus

Mobile implementations involve further complications. While Chromium-based desktop browsers automatically shift focus after interaction with the example formatting toolbar, on mobile devices this is only true if there’s text selected during the interaction. Otherwise, the editor loses focus, and the on-screen keyboard closes.

Another case where maintaining the correct focus can get complicated is the use of keyboard navigation. With traditional HTML inputs, when the user presses the tab key, focus is moved to the next input in the document object model, or as specified by the tabindex. However, tab functionality, where the tab key indents the text instead of moving the focus out of the editor, is a feature that many rich text editors need to support.

How to handle complex focus cases

Managing all of these situations while maintaining the accessibility of your application is possible, but can be difficult. Let's take a look at how you might handle some of these situations if you do decide to develop a rich text editor yourself.

  1. Focus and refocus code maintenance

Because these situations require modifying the default behavior of your application, you’ll have to write and maintain focus and refocus code if you want to build your own rich text editor. 

In this context, refocus code is code that returns focus to where the user would expect it to be, after an action has taken the focus away from the expected element due to default behavior.

  1. Tracking previously maintained focus

To continue from the example above, you’ll need to keep track of the previously focused element – when a toolbar button is clicked, you’ll need to shift focus from the toolbar back to the previously focused editor, and perform the action. Keep in mind that since browser behavior isn’t standardized, the solution will likely be quite complicated. For example, the browser might refocus automatically, in which case giving focus back to the previously focused element would return focus to the toolbar button.

To demonstrate, modify the code as follows:

const editor = document.getElementById("editor");
const boldButton = document.getElementById("boldButton");
let previouslyFocused;
boldButton.addEventListener("click", function () {
  document.execCommand("bold", false, null);
  if (previouslyFocused) previouslyFocused.focus();
});
document.addEventListener("focusout", function (e) {
  previouslyFocused = e.target;
});

The added event listener uses the previouslyFocused variable to track when an element loses focus. After the execCommand call, this previouslyFocused element gets the focus back.

You’ll notice this code now works in Firefox, but breaks in Chromium (at least in the versions mentioned previously). Because Chromium automatically refocuses the text box, the toolbar button becomes the previouslyFocused element, which causes focus to shift back to the toolbar rather than the text box.

  1. Testing and retesting

In addition to writing the code itself, you'll also want to either write extensive automated tests for this code or have a plan to manually test for this sort of behavior. This is especially true if the rich text editor that you're building is a core part of your application experience. 

As your codebase grows, so does the complexity of implementing a rich text editor. Above, we looked at one example where focus and refocus code would need to be written, but in addition to the examples previously discussed, your focus and refocus code grows as you discover more scenarios and edge cases that need custom behavior. 

This code needs to be tested, either with automated tests or a more manual QA process, across all the major browsers and devices that your application is used on. These tests, or even your users themselves, will certainly continue to discover new cases where focus and refocus code needs to be implemented.

The alternative to building your own rich text editor

Writing and maintaining this type of code is possible, and could even be desirable, if you want an extremely customized experience or absolute control over how your users experience your application. 

However in most cases, you’d be better served by using an off-the-shelf editor that you can embed in your application.

Using a rich text editor like TinyMCE allows you to focus on writing and maintaining the core logic of your application, while the team at Tiny worries about all the quirks of building and maintaining a text editor – something they have years of experience with and continue to innovate each year. 

TinyMCE is easy to deploy and painless to maintain, and allows anyone to create visually stunning, web-ready content with compliance, tab focus, and collaboration solutions.

Wrapping up

When building an application that includes a rich text editor, it's important for your users to have a seamless experience, and maintaining and managing HTML focus is an important part of that. While building your own solution is possible, it can be difficult to account for all the possible edge cases while still creating a performant, accessible interface.

The time spent maintaining your rich text editor’s code can take up engineering time and resources that could be better spent elsewhere. A solution like TinyMCE allows you to focus your engineering efforts where they’ll count the most – while still ensuring that your rich text editor supports any use case

EngineeringHTMLProduct DevelopmentTinyMCE
byKeanan Koppenhaver

Keanan is the CTO at Alpha Particle where he helps publishers modernize their technology platforms and build their developer teams.

Related Articles

  • Developer InsightsMar 7th, 2024

    Understanding Uncaught TypeErrors in JavaScript

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tiny logo

Stay Connected

SOC2 compliance badge

Products

TinyMCEDriveMoxieManager
© Copyright 2024 Tiny Technologies Inc.

TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.