Skip to content Skip to sidebar Skip to footer

Make Text "more" Selectable

I have text in a

tag:

Hello world... and goodbye mind A B!

How do I increase the area in which the text is selectable? I know I can increase the font-

Solution 1:

From my test it works on the iphone as well as ff and chrome - if someone can test on android I'll appreciate feedback!

The border obviously can be removed.

This code uses code from this answer (part of the SelectText() function): Selecting text in an element (akin to highlighting with your mouse)

Fiddle

Code:

function extendSelection() {
    var extendBy = arguments.length <= 0 || arguments[0] === undefined ? 15 : arguments[0];

    var extended = document.getElementsByClassName('extendedSelection');
    [].slice.call(extended).forEach(function (v) {
        var bounds = v.getBoundingClientRect();
        var x = bounds.left;
        var r = textWidth(v.innerHTML, ''+ css(v, 'font-weight') +' ' + css(v, 'font-size') + ' ' + css(v, 'font-family') );
        var y = bounds.top;
        var w = bounds.width;
        var h = bounds.height;
        var element = document.createElement('div');
        element.style.position = 'absolute';
        element.style.height = h + extendBy + 'px';
        element.style.width = r + extendBy + 'px';
        element.style.left = x - extendBy / 2 + 'px';
        element.style.top = y - extendBy / 2 + 'px';
        element.style.border = '1px dotted black';
        document.body.appendChild(element);
        element.addEventListener('click', function (e) {
            SelectText(v);
        });
        element.addEventListener('touchend', function (e) {
            SelectText(v);
        });
    });
}

function css(element, property) {
    return window.getComputedStyle(element, null).getPropertyValue(property);
}

function textWidth(text, font) {
    var el = textWidth.canvas || (textWidth.canvas = document.createElement("canvas"));
    var draw = el.getContext("2d");
    draw.font = font;
    var m = draw.measureText(text);
    return m.width;
};

function SelectText(element) {
    var doc = document,
        text = element,
        range,
        selection;
    if (doc.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if (window.getSelection) {
        selection = window.getSelection();
        range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
        selection.setSelectionRange(0, element.value.length)
    }
}

extendSelection();

Solution 2:

You could add padding around paragraphs as someone already suggested but also use negative margin of the same value to prevent it from affecting layout.

Here is DEMO (double-clicking or long-tapping anywhere inside gray area should select text)

Relevant code:

HTML:

<p>normal paragraph</p>
<hr />
<p class="fat-fingers">fat fingers paragraph</p>

CSS:

p {
    //resetting default browser styles for brevity
    //otherwise adjust negative margin value so it's == default margin - padding
    margin: 0;
}

.fat-fingers {
    padding: 10px;
    margin: -10px;
}

note: I didn't test case of two areas overlapping but I assume that the one with higher stacking order wins.


Solution 3:

I'm assuming the scenario where you have a body of text, and inside that body of text is a fairly important or relevant piece of information to an end user and you would like them to be able to easily highlight and copy the information.

This would be considered as a last option if no other solution was found,

<p class="surroundingText"> BLAH BLAH BLAH  <span class="importantText"> This is the information you would like users to be able to highlight </span> BLAH BLAH BLAH BLAH ETC ETC ETC </p>

If you wrap the text around it in separate paragraph tags and give them a class then set the following in CSS:

.surroundingText {

  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  user-select: none;         
}

.importantText {

        -webkit-user-select: all;  /* Chrome all / Safari all */
      -moz-user-select: all;     /* Firefox all */
      -ms-user-select: all;      /* IE 10+ */
      user-select: all;
    }

So the end result is only the text between the span tag is able to be selected.


Solution 4:

Exaggerated for effect but what about:

<head>
    <style>   
    p {
        letter-spacing: 2px;
        line-height: 3em;
        word-spacing: 1.5em;
        vertical-align: middle;
    }
    </style>
</head>
<body >

    <p>this is a line.</p>
    <p>this is a line.</p>
    <p>this is a line.</p>
    <p>this is a line.</p>
    <p>this is a line.</p>
    <p>this is a line.</p>
    <p>this is a line.</p>
</body>

Solution 5:

One approach is to increase the line-height of the <p> element. On a mobile device, you can better select a text fragment, because of the larger spacing between the lines. If you define the values in em, the spacing is always relative to the font-size.

A second approach is to increase the word-spacing of the text element to a level which is still acceptable. I would recommend a maximal value of of 0.2em.

HTML:

<p class="extendedSelection">Extended Selection</p>

CSS:

p.extendedSelection {
   line-height: 2em;
   word-spacing: 0.2em;
}

JSFiddle here

If those two approaches are not good enough, you could of course create an absolute positioned element for each word, which overlays the text element, but has an opacity of 0. The text inside of this element should be equal to the text behind but with a larger font-size. This approach has several drawbacks: You need to calculate the positions of every word and duplicate the text content. It is a rather large calculation for just a little effect.


Post a Comment for "Make Text "more" Selectable"