In a medium saucepan, whisk together the sugar, flour, and salt. Slowly whisk in the cold milk until completely smooth with no lumps.
Set the pan over medium heat and cook, whisking constantly, until the mixture thickens to a glossy pudding consistency and small bubbles pop at the surface, about 5 to 7 minutes.
Remove from heat and scrape the mixture into a shallow bowl. Press plastic wrap directly onto the surface to prevent a skin. Let cool to room temperature; do not use while warm.
In a stand mixer with the paddle or a hand mixer, beat the butter on medium-high until very light and fluffy, about 3 minutes.
With the mixer on medium, add the cooled milk mixture a tablespoon at a time, allowing each addition to incorporate before adding the next. Scrape the bowl as needed.
Beat in the lemon zest, lemon juice, and vanilla. If desired, add a couple drops of yellow food coloring for a pale lemon hue. Continue beating until the frosting is silky and holds soft peaks.
Use immediately to frost cooled cakes or cupcakes. If the frosting looks loose, chill for 10 minutes and re-whip briefly.
Notes
For the smoothest texture, ensure the cooked milk mixture is fully cooled before beating into the butter. If the frosting appears curdled at any point, keep mixing—it will come together. Store leftovers covered in the refrigerator for up to 3 days; bring to room temperature and re-whip before using.