For <img>, the SVG is scaled to fit the image element, and the viewport of the SVG is the CSS dimensions of the <img>. So the first <img> has a viewport width of 50, and the second has a viewport width of 100. This means the second <img> picks up the "blue" media query, but the first does not.
For <iframe>, the viewport of the SVG is the viewport of the iframed document. So in the above example, the viewport width is 50 CSS pixels because that's the width of the iframe.
For inline <svg>, the SVG doesn't have its own viewport, it's part of the parent document. This means the <style> is owned by the parent document - it isn't scoped to the SVG. This caught me out when I first used inline SVG, but it makes sense and is well defined in the spec.