The reason this doesn’t work is actually quite simple: The ::before and ::after pseudo-elements render inside its parent element. You could have found this via a fairly simple Google search, which would lead you to this StackOverflow answer.
 
Basically, if you try to render a ::before pseudo-element inside a self-closing input element, then it won’t work, since you can’t nest any elements inside an input. It won’t work for select because everything nested inside those would have to render as an option, which is not what the ::before pseudo-element is.
 
See this JSFiddle for a simple demonstration of the ::before pseudo-element’s position in the DOM. If you inspect the DOM via Chrome’s developer tools, you’ll also see how it renders: Inside the div