Okay, backing up. Here’s the problem, as you define it: some developer somewhere adds CSS to your codebase that has unintended consequences. By packaging in a reusable component, you’ve isolated the problem.
But in reality, all you’ve done is moved the API. You still need the developer to use your component. Do you then wrap every native in a component, like links and inputs? If you make a <Button>, what’s to say some dev isn’t going to forget it’s there and use a native <button>? What if they need/want something slightly different, do you keep adding more and more options to the component? These can be answered, but these are all the same decisions you would make in CSS land.
It’s a lot of overhead, and I don’t see the gain. What I do see is permission implicitly granted for devs who don’t understand CSS—and by that I mean things like positioning and layout and margin collapsing—to start writing CSS willy nilly.
I feel like a guy yelling, “don’t drive on the sidewalk because people should be able to walk there” and your response is “nobody walks on the sidewalk because everybody drives there.”
Anyway, the larger point is: driving on the road is better. And I would argue using relative units is better in many cases. Why? Because the code maintenance is easier. True, using px requires less thought up front. But if you use relative units, you can define systems that work together better as a whole.
You can change a few inputs and have the entire system respond. You can define things in terms of your fonts, because your fonts are an integral part of the design. With pixels, small changes in the future can require code changes all over your code to adapt to that change. With units, done right, one small change can update the entire system accordingly.