salut,
1ere chose les if(isset($_POST['cb'])) sont inutiles dans les foreach. Simplement parce que si tu est dans le foreach c'est que $_POST['cb'] existe sinon il y aune erreur sur la ligne du foreach
2nd : pourquoi ré indexer ?
La perte des index est du à array_values, regarde bine l'exemple de la doc :
http://php.net/manual/fr/function.array-values.php
3ème : je pense que ton système est bancale.
$tab_art me dit que c'est un tableau qui contient des articles ?
si c'est le cas les index doivent être les références article (ou pk de la table qui les contient). C'est la seule référence utile.
ensuite tu met en valeur des checkbox ces références et les utilisent pour la suppression. La réindexation est totalement inutile (anti performante et l'on se fou de savoir s'il y a des "trous" dans les index ou pas

).
au final ton code se restreint à
if(!empty($_POST['cb']) && is_array($_POST['cb'])) {
foreach ($_POST['cb'] as $key => $value) {
unset($tab_art[$value]);
}
}
exemple avec test
<?php
$_POST['cb'] = ['art-1','art-2','art-3'];
$tab_art = ['art-1' => 'fdfdfd', 'art-3' => 'ffjkhjkghf','art-4'=>'gardé'];
if(!empty($_POST['cb']) && is_array($_POST['cb'])) {
foreach ($_POST['cb'] as $key => $value) {
unset($tab_art[$value]);
}
}
xdebug_var_dump($tab_art);
résultat
@+