tamilselvancst
tamilselvancst

Reputation: 488

How to apply a background color to only half of the text on selecting?

When I select text, the background color changes to yellow.

body p::selection {
  background: #fcf113;
  color: #000;
  display: none;
}

body p::-moz-selection {
  background: #fcf113;
}

enter image description here

But, I want it to appear like this.

enter image description here

Is it possible or not?

Upvotes: 18

Views: 16664

Answers (7)

Om Bharti
Om Bharti

Reputation: 47

.half-bg-effect {
  @apply inline text-black/90;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0) 70%,
    rgba(169, 213, 233, 0.5) 70%,
    rgba(180, 215, 233, 0.5) 100%
  );
}

I am using tailwind, just u need to set--> display:inline; and background i gave you for light blue, NOTE: u must need to use rgba format, otherwise it will not work

Upvotes: 0

Penny Liu
Penny Liu

Reputation: 17498

If you want to consider the descenders of letters like g and y, you can modify the CSS code as follows:

p {
  font-family: Georgia, serif;
  font-size: 4rem;
}

.half_bg {
  background: linear-gradient(/* Gradient from yellow to yellow */
  yellow, yellow)
  /* Starting position of the gradient */
  0
  /* Position of the gradient along the y-axis */
  70%
  /* Size of the gradient along the x-axis (full width) */
  / 100%
  /* Size of the gradient along the y-axis (1rem height) */
  1rem
  /* Background will not repeat */
  no-repeat;
}
<p>
  The quick brown fox jumps over the <span class="half_bg">lazy dog</span>.
</p>

Upvotes: 2

Yagnesh Patel
Yagnesh Patel

Reputation: 11

You can do this using box-shadow.

h1 span{
  box-shadow: inset 0px -15px 0px 0px yellow;
}
<h1><span>Here's Your Answer.</span></h1>

Upvotes: 1

Jan Grabowski
Jan Grabowski

Reputation: 61

Yes, with gradients it work's fine.

<h1 class="grad">Design the Future Kitchen</h1>

Here's the css code.

.grad {
    background: rgb(255,255,255);
    background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,0,1) 50%, rgba(255,255,0,1) 100%);
}

h1 must be an inline-element or do it with a span-tag.

h1 { 
  display: inline;
}

Upvotes: 6

roberrrt-s
roberrrt-s

Reputation: 8210

Thank you for ruining at least an hour of my day, but I actually found a CSS-only solution. It's not really solid though, and it involves a lot of faking, but hey: No JavaScript!

We basically use a data-content attribute with the same content as the span holds, and then copy this to a layered :after element which displays it. We then hide the original text and apply a 50% height to the after element, this way the background color can only be applied to the bottom half.

h1 {
    position: relative;
    color: #FFF;
}

h1:after {
    content: attr(data-content);
    position: absolute;
    color: #000;
    top: 0;
    left: 0;
    width: 100%;
    height: 50%;
    background-color: #FFF;
}

h1::selection {
    background: #fcf113;
}
<h1 data-content="Hello world!">Hello world!</span>

Based on above, user @chrona made this really lovely working version:

var paragraph = $('p');
var words     = paragraph.text().split(" ");

paragraph.empty();

$.each(words, function(i, v) {
    paragraph.append('<span data-word="' + v + '"> ' + v + ' </span>');
});
p {
  background: white;
}

body {
  background: white;
}

span {
  position: relative;
  font-size: 1.25rem;
  line-height: 1.4;
}

span::after {
  background: white;
  content: attr(data-word);
  display: block;
  height: 75%;
  left: 0;
  padding-top: 0.14em;
  position: absolute;
  pointer-events: none;
  overflow: hidden;
  top: -0.28em;
  width: 100%;
}

span::selection {
  background: #fcf113;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
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>

Upvotes: 14

chrona
chrona

Reputation: 1911

This is not possible with css alone (without hacks), currently you can only style a small set of properties for ::selection like color, background-color, cursor, outline, text-decoration, and text-shadow.

Other background properties will be ignored so using a gradient isn't possible.


If you really need the color as described you could use javascript to get the selected text, wrap it with a <span> and style that with CSS.

For small sentences or headlines, check out Roberrrts CSS only answer.

Source:
https://developer.mozilla.org/en-US/docs/Web/CSS/::selection
https://drafts.csswg.org/css-pseudo-4/#highlight-styling

Upvotes: 3

Henrique Souza
Henrique Souza

Reputation: 49

I think that you can do it with gradient effect:

#grad1 {
    height: 200px;
    background: -webkit-linear-gradient(rgba(255,255,0,0) 70%, rgba(255,255,0,1)); /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(rgba(255,255,0,0) 70%, rgba(255,255,0,1)); /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(rgba(255,255,0,0) 70%, rgba(255,255,0,1)); /* For Firefox 3.6 to 15 */
    background: linear-gradient(rgba(255,255,0,0) 70%, rgba(255,255,0,1)); /* Standard syntax (must be last) */
}

Upvotes: 2

Related Questions