Note that in terms of semantics and accessibility, there is a difference between a label
and a placeholder
The key is to not assume a placeholder can take the place of a label on a form field.
Where it gets debatable is how to actually implement that. Prior to HTML 5's placeholder attribute, there were two common methods:
Hide the label with CSS, add text into the field itself and delete it on focus with JS
Move the label so that it physically was on top of the field.
I usually preferred the second option as it felt more pure.
Today, though, with HTML 5, we have an actual attribute for this called 'placeholder'. In addition, we can use aria-label
for accessibility:
https://developer.mozilla.org/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
In theory, a field with both of those attributes set to the text you want for a label should work--both from a usability standpoint and an accessibility standpoint.
As for which to use, I'd typically suggest that one should always use a proper label
tag and place it next to or above the form field. This is the clearest option for most users and the most appropriate in terms of markup. In addition, you can still use a placeholder attribute for further clarification if needed.
When to put a label inside the field? I'd say that usually comes down to space and visual design considerations.