JSFiddle - React, Tailwind, and code Playground

by caub

HTML

<div id="editor" contenteditable>


  <p>
    some text outside table, selection is yellow here 
  </p>
  <table id="test">
    <tr>
      <td ><a> ok </a>test</td>
      <td colspan="3" rowspan="2">test</td>
      <td>test</td>
    </tr>
    <tr>
      <td >test</td>
      <td >test</td>
    </tr>
    <tr>
      <td >test</td>
      <td colspan="2">test</td>
      <td >test</td>
      <td >test</td>
    </tr>
    <tr>
      <td >test</td>
      <td >test</td>
      <td >test</td>
      <td >test</td>
      <td >test</td>
    </tr>
  </table>
  <p>
    some text outside table
  </p>

</div>

CSS

body ::selection { all: inherit; background-color: yellow;}
table ::selection { all: inherit; background-color: lightblue;}
td::selection, td ::selection { all: inherit; background-color: red;}

body ::-moz-selection { all: inherit; background-color: yellow;}
table ::-moz-selection { all: inherit; background-color: lightblue;}
td::-moz-selection, td ::-moz-selection { all: inherit; background-color: red;}

.noselection, .noselection table td {
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

table {
  border: none;
  border-collapse: collapse;
  empty-cells: show;
  max-width: 100%;
  z-index: 3;
  position: relative; 
}
td {
  border: 1px solid #dddddd;
  vertical-align: middle;
  height: 24px;
  padding: 5px;
}

[contenteditable] {
  border: 1px solid blue;
  padding: 0 2em;
}

JavaScript

var r=getRange();
r.selectNode(test);

setRange(r);
editor.contentEditable='false';
setTimeout(_=>{
editor.classList.add('noselection');
},100)

/*
var start;
test.addEventListener('mousedown', function(e){
	start = e.target;
});
test.addEventListener('mouseenter', function(e){
	if (start){
  	if (start===e.target) {editor.classList.remove('noselection');editor.contentEditable='true';}
    else {editor.classList.add('noselection');editor.contentEditable='false';}
  }
}, true)
document.body.addEventListener('mouseup', function(e){
	start=null;
  editor.classList.remove('noselection');
  editor.contentEditable='true';
});
*/

function getRange(){ return document.getSelection().rangeCount?document.getSelection().getRangeAt(0):document.createRange(); }
function setRange(range){document.getSelection().removeAllRanges(); document.getSelection().addRange(range);}

document.execCommand('insertBrOnReturn',null, false);
document.execCommand('enableInlineTableEditing',null, false);
document.execCommand('enableObjectResizing',null, false);