css-loader reads in a css file as a string. You could replace it with raw-loader and get the same effect in a lot of situations. Since it just reads the file contents and nothing else, it's basically useless unless you chain it with another loader.
style-loader takes those styles and creates a <style> tag in the page's <head> element containing those styles.
If you look at the javascript inside bundle.js after using style-loader you'll see a comment in the generated code that says
  // style-loader: Adds some css to the DOM by adding a  tag
For example,
<html>
    <head>
        <!-- this tag was created by style-loader -->
        <style type="text/css">
            body {
                background: yellow;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
    </body>
</html>
That example comes from this tutorial. If you remove the style-loader from the pipeline by changing the line
require("!style-loader!css-loader!./style.css");
to
require("css-loader!./style.css");
you will see that the <style> goes away.