Before I get to the problem, let me just say: You don't have to define the same element for screen and print if the style is the same for both (i.e. the html & body where you set the same properties for both). In this case I assume all styles are to be the same for screen & print except for the "noprint" style to be used on items that, well, shouldn't print.
So, for the default styles don't declare a media value.
I have never used different STYLE blocks for different media types. I have always used the @media property within a single STYLE block to define different media styles. I don't know which method is right or wrong, but a little testing showed me why you are experiencing this problem. And, it is an interesting difference.
When using different STYLE blocks for different media types, if you declare a class in one media style block and not another, the browser is applying that class to all media types. So, in your code above you did not define the noprint class in the print media style block. I guess the browser then defaulted to the properties for that class in the print media style block.
The method I typically used didn't have this behavior. Example:
<html>
<head>
<style type="text/css">
/* media neutral styles go here */
@media print {
.noprint { display: none; }
}
</style>
</head>
<body>
<div>This will print</div>
<div class="noprint">This will NOT print</div>
</body>
</html>