Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change inactive selection color in Firefox

Tags:

css

firefox

When i select some text in Firefox and then the window or Iframe loses focus (selecting address bar for Example), then the selection becomes grey, even when a different color is specified in css.

How do i change the color for a disabled selection in Firefox?

What I've tried:

<style>::selection { background-color: green; }</style>
<p>lorem ipsum</p>

Screenshot of the Behavior

Edit:

What i want to use here seem to be ::inactive-selection, but it's not yet implemented in firefox. See https://drafts.csswg.org/css-pseudo-4/#selectordef-inactive-selection

Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=706209

Does anyone know a workaround? At this point, im considering using some javascript hacks. Any ideas how to do this?

like image 543
Zotta Avatar asked Jun 09 '19 12:06

Zotta


2 Answers

No, you can't

Not on Firefox at least.

Reason I'm answering with a no, is to save both of your time and others who might try to find some solutions / hacks.

Since you already know about the css specification. I might want to add that,

Remember Firefox has it's own version of ::selection, ::-moz-selection. It also has it's own version of :window-inactive, :-moz-window-inactive. Unfortunately using these things together doesn't work.

Source: CSS Tricks

/* Does work */
::-moz-selection {
  background: rgba(255,0,0,0.9);
  color: white;
}
/* Doesn't work */
::-moz-selection:-moz-window-inactive {
  background: rgba(255,0,0,0.3);
}
/* Nor this */
:-moz-window-inactive::-moz-selection {
  background: rgba(255,0,0,0.3);
}

Also, Bugzilla has years old bugs requesting this feature and talking about it's inability to handle inactive selections but no responses on those. Here is a list. Some of them are even 11 years old. I am planning to talk to someone about this and report a new bug myself with some more details, might add their response or the bug number here so that you can get updates.

So, for now I think you shouldn't be looking for some hacks, it'll only waste your time.

Thanks

Update: here is the bug to keep an eye on bugzilla, lets see what the dev team has to say.

like image 150
Towkir Avatar answered Sep 22 '22 01:09

Towkir


For text-selection inside a single node/element, a possible workaround can be achieved with javascript.

  • You can listen for the focus and blur events of the window.
  • In the event-handler for the blur-event you can check if anything is selected, wrap a span-element around the selected text and clear the selection.
  • In the event-handler for the focus-event, you can restore the content and selection to its previous states.

Demo:

let range = null;
let span = null;

// browser-window looses focus (blur)
window.addEventListener('blur', function(event){
  let selection = window.getSelection();
  // abort if selection involves text from multiple nodes
  if (selection.anchorNode != selection.focusNode) {
    console.log('Selection over multiple nodes is not supported!');
    return;
  }
  // get range from current selection and wrap content in span with custom style
  range = selection.getRangeAt(0);
  span = document.createElement("span");
  span.classList.add("selection-custom-highlight");
  span.appendChild(range.extractContents());
  range.insertNode(span);
  // clear current selection in document
  selection.removeAllRanges();
});

// browser-window gets focus
window.addEventListener('focus', function(event){
  if (span) {
    let selection = window.getSelection();
    // replace span with text-node
    let node = document.createTextNode(span.textContent)
    span.remove();
    range.insertNode(node);
    span = null;
    // clear current selection in document
    selection.removeAllRanges();
    // add saved range to selection
    selection.addRange(range);
  }
});
::selection,
.selection-custom-highlight {
  background-color: green;
}
<div id="content-1">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
<hr>
<div id="content-2">
  Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

It is also possible to extend this workaround to handle text-selection over multiple rows:

  • For that you will have to wrap spans around the selection in anchorNode and focusNode utilizing the values of anchorOffset and focusOffset.
  • You also have to find all the text-nodes between anchorNode and focusNode (See this answer). And wrap each content in a span-node.
  • And when the window regains the focus, you would have to undo all the modifications.

Note: This can result in a lot of manipulations to the document and probably lead to some unwanted behavior when using any javascript libraries that interact or attach to these nodes.

like image 36
Jan Avatar answered Sep 21 '22 01:09

Jan