I saw this selection in VSCode and monaco-editor and it looks really good :
SO I tried to recreate this, here is my effort :
#ta{
font-size : 18px;
}
#ta::selection{
background : rgba(173, 216, 130, 0.9);
border : 1px solid transparent;
border-radius : 15px;
}
<textarea id="ta"></textarea>
I saw this selection in VSCode and monaco-editor and it looks really good :
SO I tried to recreate this, here is my effort :
#ta{
font-size : 18px;
}
#ta::selection{
background : rgba(173, 216, 130, 0.9);
border : 1px solid transparent;
border-radius : 15px;
}
<textarea id="ta"></textarea>
But this doesn't get the round corners effect(I hope you get it) like the one shown in the picture.
Please help me out. Answers appreciated.
Share Improve this question edited Jan 1, 2020 at 15:32 Pranav asked Jan 1, 2020 at 15:10 PranavPranav 6731 gold badge8 silver badges24 bronze badges 4-
1
Looking up
::selection
, there is only a very small subset of CSS rules that can be applied to it,border-radius
not being one of them. In other words, this doesn't seem possible in this way. You might be able to use JS to wrap the current selection in aspan
, then add somedisplay: inline-block
and the desiredborder-radius
to it, although this would probably not work in atextarea
. – domsson Commented Jan 1, 2020 at 15:24 - @domsson could you show me a attempt? – Pranav Commented Jan 1, 2020 at 15:29
- 1 What is the question? Do you want rounded corners only on selecting the text area? – Nagaraj Raveendran Commented Jan 1, 2020 at 15:30
- 3 I need the ::selection to have rounded corners – Pranav Commented Jan 1, 2020 at 15:32
2 Answers
Reset to default 8As some people already mented on your question
::selection is only a very small subset of CSS rules that can be applied to it, border-radius not being one of them...
So, next step is, if you really need it, how could you go around it? One of the options is: You could use the "selected" string and then add some HTML tags. Then when you select text and release the mouse all your CSS styles will be applied.
Keep in mind: this might not work in "normal" text boxes
I hope the following code gives you an example to get started
var selectionElements = document.querySelectorAll('.selection');
selectionElements.forEach(function(element){
element.setAttribute('original-content', element.innerHTML); // this will be needed to reset to original after a selection has been made
element.addEventListener('mouseup', function() {
replaceContentWithSelectionWrapper(this)
});
});
function replaceContentWithSelectionWrapper(element) {
let selection = window.getSelection().toString();
if(selection.length <= 0) { // if selection length is not bigger then 0 we can stop right here
return;
}
// next lines should be self explanatory
// get start of string until selection
// get the end of string after selection
// concatenate all strings back together
let selObj = window.getSelection();
let selRange = selObj.getRangeAt(0);
let originalString = element.innerHTML;
let start = originalString.substr(0, selRange.startOffset);
let end = originalString.substr(selRange.endOffset);
element.innerHTML = start + '<span class="mark-special-selected">' + selection + '</span>' + end;
document.body.classList.add('selections-enabled');
}
function clearSelections() {
var selections = document.querySelectorAll('[original-content]');
selections.forEach(function(selection){
selection.innerHTML = selection.getAttribute('original-content');
});
}
document.body.addEventListener('mousedown', function(){
if(document.body.classList.contains('selections-enabled')) {
document.body.classList.remove('selections-enabled');
clearSelections();
}
});
.selection {
font-size : 18px;
}
.mark-special-selected,
.selection::selection{
background : rgba(173, 216, 130, 0.9);
border : 1px solid transparent;
border-radius : 15px;
outline: 2px;
}
<h1 class="selection">Here is some text, you can select some of it with your mouse</h1>
<p class="selection">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
With this CSS, the effect is more like the text selection of VS Code, it's just not instantly rounded and it doesn't have the effect on each intersection (and has a line of one pixel blank between lines, due to the lack of a border), but the text won't move when selecting it.
I remind that the text selection of Visual Studio Code looks like this:
Other issues with the code snippet below:
- If the click is released outside of the text box, the rounded corners effect may not work;
- If the text is selected from outside the text box, the selection will be the default one;
- In this example, if the cursor selects the header text and releases the click on the text bellow, the upper selected text is written lower, and the effect is only on the lower paragraph;
- In this example, if the cursor selects the lower text and releases the click on the upper text, the lower selected text is written upper, and the effect works only on the selected copied part which is now in the header text;
- If the text is selected too fast (I think this is the cause of it), the rounded corners don't work on the header text.
Anyway, strange things are going on with this text selection, and if someone can handle them, it would be great.
var selectionElements = document.querySelectorAll('.selection');
selectionElements.forEach(function(element){
element.setAttribute('original-content', element.innerHTML); // this will be needed to reset to original after a selection has been made
element.addEventListener('mouseup', function() {
replaceContentWithSelectionWrapper(this)
});
});
function replaceContentWithSelectionWrapper(element) {
let selection = window.getSelection().toString();
if(selection.length <= 0) { // if selection length is not bigger then 0 we can stop right here
return;
}
// next lines should be self explanatory
// get start of string until selection
// get the end of string after selection
// concatenate all strings back together
let selObj = window.getSelection();
let selRange = selObj.getRangeAt(0);
let originalString = element.innerHTML;
let start = originalString.substr(0, selRange.startOffset);
let end = originalString.substr(selRange.endOffset);
element.innerHTML = start + '<span class="mark-special-selected">' + selection + '</span>' + end;
document.body.classList.add('selections-enabled');
}
function clearSelections() {
var selections = document.querySelectorAll('[original-content]');
selections.forEach(function(selection){
selection.innerHTML = selection.getAttribute('original-content');
});
}
document.body.addEventListener('mousedown', function(){
if(document.body.classList.contains('selections-enabled')) {
document.body.classList.remove('selections-enabled');
clearSelections();
}
});
.selection {
font-size: 18px;
}
.mark-special-selected, .selection::selection{
background: #8884;
border-radius: 4px;
}
<h1 class="selection">Here is some text, you can select some of it with your mouse</h1>
<p class="selection">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>