This looks like a bug in several shells, it works as expected with ksh93 and zsh.
Most shells seem to run the while loop inside the main shell and
Bourne Shell suspends the whole shell if you type ^Z with a non-login shell
bash suspends only the
sleep and then leaves the while loop in favor of printing a new shell prompt
dash makes this command unsuspendable
With ksh93, things work very different:
ksh93 does the same, while the command is started the first time, but as
sleep is a buitin in ksh93, ksh93 has a handler that causes the while loop to fork off the main shell and then suspend at the time when you type ^Z.
If you in ksh93 later type
fg, the forked off child that still runs the loop is continued.
You see the main difference when comparing the jobcontrol messages from bash and ksh93:
+ Stopped sleep 1
but ksh93 reports:
^Z + Stopped while true; do echo .; sleep 1; done
zsh behaves similar to ksh93
With both shells, you have a single process (the main shell) as long as you don't type ^Z, and two shell processes after you typed ^Z.