Assuming the browsers run a lexer to take the HTML and convert it into an AST of some kind they would walk the text per-character (or UTF code-point potentially). If the rules were enforced loosely but in a purely forward looking way then `<div class=pants shirts id=small>` would parse as Div token with a class value of `pants shirts id=small`. However I doubt that they're parsed purely forward looking since it's not possible to know from the character position at the `i` in `id` that `id` is a keyword for an argument rather than part of the class value.
So how does the browser know that the class value ends at `id`? Because there are additional heuristics over and above the quote requirement. What probably happens is that it looks forward until it finds some value that's not allowed in the `class` attribute (spaces are allowed for multiple class names), I'd guess in this case the assignment operator after `id`. Once it finds this it says to itself "Hey, `id` is an attribute." So it ends the Div token before `id`, probably stripping the trailing white-space since it's inside an HTML tag, and then starts parsing the `id` attribute.
This behavior of accepting non-compliant HTML is additional complexity over and above strictly parsing the standard. Having to take the "slow" path of waiting until it gets to another attribute doesn't take much, maybe a few dozen actual instructions, the data is probably still in the same cache line. But repeat that 100,000 times for each attribute in a real-world HTML document and it adds up.
Your example is equivalent to <div class="pants" shirts="" id="small">. This may show your error in expecting that it look backwards: no attribute names are considered special, an attribute value is concluded by its closing quote or by characters like space, and attributes don’t have to have values (there are plenty of boolean attributes, which are the most common cases where people omit the ="").
The HTML grammar really isn’t conducive to lexing.
If you’re interested in how it all actually works, I find how the HTML spec defines its parser very approachable.