In your custom theme theme.inc file for example add this code snippet (replace custom_theme with your custom theme name).
use Drupal\node\NodeInterface;
/**
* @file
* Custom theme hooks.
*/
function custom_theme_preprocess_html(&$variables) {
$route = \Drupal::routeMatch();
$node = $route->getParameter('node');
if ($node instanceof NodeInterface) {
$variables['attributes']['class'][] = 'page--node__' . $node->bundle();
}
}
First we get the $route object and then we try to load a node object (if this is in fact a node page and the node object is an instance of a NodeInterface Class). We want check the node is a NodeInterFace class because there are routes where {node} is used but it is not upcasted, for example if the controller does not type hint it as NodeInterface.
So after we make sure that this is a node object then we get the bundle of the node add it as a css class in the body element of the page. The result for a node article page will be something like class="page--node__article".