如何应用圆角边框突出显示/选择

时间:2014-07-27 20:48:37

标签: html css html5 visual-studio selection

我已经为项目使用了Visual Studio Online一段时间,并且他们在其在线代码查看器中将圆形边框应用于选择的方式非常有趣:

http://i.imgur.com/V9dlwSr.png

我已经尝试检查元素并寻找某种自定义CSS,但没有运气。

我有一种感觉,这需要一些复杂的“黑客”来使它工作,但它似乎非常有趣,因为我以前从未见过它。

他们如何将圆形边框应用于选区?

注意:正常选择在选择时完全隐藏,圆角选择跟随光标,就像常规选择一样。不是在你选择了什么之后。

编辑:我有@ {Coma的答案的created a fork应该可以在Firefox中使用并在鼠标移动时选择使用:

$(document).on('mousemove', function () {

(在某些情况下,边界仍然可以使用工作。)

5 个答案:

答案 0 :(得分:7)

我可以向你保证,这与html,css边框半径或突出显示无关。证明?

  1. 整个选择显示为具有多个边和格的单个块,并且不对称。在没有使用SVG或Canvas的情况下,无法直接在html中使用多边形状。 (好吧,这是一个可以讨论的可能性)
  2. 如果它不是单个块,但实际上多个行突出显示或用某种HTML或CSS或JS标记,那么就不能有这样一个外向曲线:
    enter image description here
    (总有可能。例如,您可以使用带有边框半径的白色矩形来覆盖选区,但这似乎非常低效且不太可能......所以...)
  3. 总结一下,他们必须使用Canvas属性和大量代码来支持'互动选择程序。编辑器中出现了许多不同类型的突出显示,例如“相同的单词突出显示'”,“选择突出显示”,“焦点突出显示'”等...为了使所有这些有效地发生,我找不到比画布更好的选择。

    不要因为张贴这个而生我的气。但我并不想把我4小时的研究视为浪费。至少我得到了一个观察,那就是。

    更新:

    虽然我认为在末尾使用带有边框半径的白色矩形来覆盖选区,但这是一种相当低效且不必要的方式。微软并不这么认为。

    他们使用弯曲的边缘矩形来掩盖高光的末端以产生这种效果。他们使用绝对定位的圆边<div>来产生突出效果。在<div>的末尾,它们覆盖了圆角矩形的图像。

    对他们赞不绝口,他们做得很好。

答案 1 :(得分:7)

不完美,但它正在发挥作用:

http://jsfiddle.net/coma/9p2CT/

删除真实选择

::selection {
   background-color: transparent;
}

添加一些样式

span.highlight {
    background: #ADD6FF;
}

span.begin {
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
}

span.end {
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
}

pre.merge-end > span:last-child {
    border-bottom-right-radius: 0;
}

pre.merge-end + pre > span:last-child {
    border-top-right-radius: 0;
}

pre.merge-begin > span:first-child {
    border-bottom-left-radius: 0;
}

pre.merge-begin + pre > span:first-child {
    border-top-left-radius: 0;
}

包装节点元素中的每个字符

var format = function () {

    var before = -1;
    var html = $.trim(editor.text())
    .split("\n")
    .reverse()
    .map(function (line) {

        var a = line.length === before ? 'merge-end' : '';
        before = line.length;

        return '<pre class="' + a + '"><span>' + line.split('').join('</span><span>') + '</span></pre>';
    })
    .reverse()
    .join('');

    editor.html(html);
};

获取所选节点并突出显示它们,照顾他们的父母

var getSelectedNodes = function () {

    var i;
    var nodes = [];
    var selection = rangy.getSelection();

    for (i = 0; i < selection.rangeCount; ++i) {

        selection
        .getRangeAt(i)
        .getNodes()
        .forEach(function (node) {

            if ($(node).is('span')) {

                nodes.push(node);
            }
        });
    }

    return nodes;
};

var highlight = function (nodes, beforeNode) {

    var currentNode = $(nodes.shift()).addClass('highlight');
    var currentParent = currentNode.parent();

    if (beforeNode) {

        var beforeParent = beforeNode.parent();

        if (currentParent.get(0) !== beforeParent.get(0)) {

            currentNode.addClass('begin');
            beforeNode.addClass('end');
            beforeParent.addClass('merge-begin');
        }

    } else {

        currentNode.addClass('begin');
    }

    if (nodes.length) {

        highlight(nodes, currentNode);

    } else {

        currentNode.addClass('end');
    }
};

format();

$(document).on('mouseup', function () {

    $('.highlight').removeClass('highlight begin end');
    highlight(getSelectedNodes());
});

感谢Tim DownRangy

答案 2 :(得分:2)

CSS&#39; ::selection仅支持声明颜色,背景,光标和轮廓(See W3C)。因此,无法使用纯CSS为选择定义border-radius

所以我相信他们就像Niklas在评论中提到的那样:

  1. 等到用户选择某些内容(selectstart,mousedown和mouseup的组合)
  2. 获取所选文字
  3. 获取所选文本的位置(从头开始的字符数),因为如果只是双击一个单词,则无法从中创建规则
  4. 用div或span
  5. 包装选区
  6. 将样式应用于包装器
  7. 聆听用户点击其他内容等(取消选择文字) - &gt;删除包装器
  8. 我开始尝试自己创建解决方案,但由于花费了太多时间,我失去了动力。 也许有人可能需要我的建议(我使用jQuery):

    对于第2点:

    var selection = (window.getSelection() // > IE 9 
                     || document.selection.createRange() //< IE 9
                    ).toString();
    

    对于第4点,请使用replace()

    第6点:

    $(".selection").replaceWith($(".selection")[0].childNodes);
    

    Fiddle

答案 3 :(得分:2)

它们实际上使用圆形边缘来覆盖小于前一行或后一行的句子中的高光结尾(正如我在第2点中所述)。自己检查一下:

  1. 您无法直接从iframe检查元素。所以点击其他地方并导航到iframe。我是用chromes&#39;内置源代码检查器。
  2. 然后使用此图像查找图像中突出显示的行的位置。
  3. <div>包含所有&#34;选择&#34;强调。他们只是在文本下方使用圆形的背景色矩形 绝对,顶部和左边!!! **
  4. 下一个<div>拥有类似背景色的<div>,只是用于突出显示重点词,类似词语等...
  5. enter image description here

    这实际上是iframe的内容。请参阅顶部的#document

    请参阅展开的视图。上面带有代码的小空间实际上是突出显示的部分。

    enter image description here

    这对于一个简单的网站来说不是一个好主意。他们真的需要解析和填充单词和字母,因为它应该是一个高端的代码编辑器,所以不能责怪他们花费相对较少的时间来绕过边缘一点点

答案 4 :(得分:0)

我也喜欢您可能想要的解决方案。它基本上可以处理每个单词周围的跨度,然后可以应用边界半径。但是我不知道如何存档上方的角落-因此它只是水平连接。

Row
p.introduction {
  width: 150px;
}

p.introduction span {
  background-color: #f48024;
  color: #1d1d1e;
  border-radius: 25px;
  float: left;
  padding: 0 15px 0 10px;
  margin: 4px -15px 4px 0px;
}