Как сделать «заголовок» (всплывающую подсказку, всплывающее окно, альтернативный текст) в CSS для использования с SVG, без JavaScript - PullRequest
11 голосов
/ 28 июля 2011

Довольно просто создать всплывающее окно с атрибутом title в SVG.Но как добиться того же эффекта с помощью CSS.

Это для иллюстрации, которую я делаю для Викимедиа, и я стараюсь, чтобы большинство вещей, которые другие википедисты хотели бы исправить во встроенной таблице стилей, сгруппировав свойства стиляпо реальной теме.Большинство редакторов Википедии - компьютерные неграмотные, вы не можете ожидать, что они будут искать большую часть кода, чтобы внести свои изменения, и если им придется изменить что-либо, кроме простых CSS-значений в коде, то вы, вероятно, получите неприятный беспорядок,Если я сделаю это тяжело для их слабых мозгов, то рано или поздно кто-нибудь сделает файл неуправляемым, используя Inkscape, Illustrator или какой-нибудь другой столь же ужасный векторный редактор.

Я мог бы использовать Javascript, но это сделало быиллюстрации менее доступны и делают код еще более запутанным для людей, которым нужно его редактировать.Кроме того, некоторые SVG-файлы, использующие Javascript, были удалены из Викимедиа из-за этого, но я не уверен, является ли это абсолютным правилом.


Я только что обнаружил, когда проверял свой файл, что заголовокАтрибут в SVG не разрешен там, где я его использую, но он работает с большинством браузеров.В соответствии со стандартом вы должны использовать title-элемент, но это не работает ни с одним браузером.Кроме того, в соответствии со стандартом, я мог бы дать атрибут title элементу style, но это, похоже, не работает ни с одним браузером, и мне потребовалось бы использовать 180 элементов style вместо одного (кодсгенерированный скриптом, поэтому для меня не проблема создать их, просто это сделает код намного больше и сложнее для понимания).


Два «ответа» IДо сих пор я не отвечал на вопрос, который я задал, и даже отдаленно бесполезен.

I Не волнует, можно ли редактировать изображение в Inkscape .Inkscape - это хороший инструмент для создания растровых изображений (даже если вам нужно запустить их через какую-то другую программу, чтобы впоследствии получить лучшее сжатие). Inkscape отстой при создании SVG-файлов (или любые векторные файлы изображений, предназначенные для аудитории, векторные файлы изображений, которые создает Inkscape, действительно полезны только с Inkscape), Inkscape - действительно очень плохой инструмент длявыбрать для создания SVG-изображений, предназначенных как конечный продукт;Sodipodi был хорошим инструментом для этого, но Inkscape - это не Sodipodi, он основан только на Sodipodi (к сожалению, старая C-версия Sodipodi плохо работает на современных компьютерных системах, а версия C ++ никогда не была закончена). Я хочу упростить редактирование своего изображения с помощью текстового редактора , чтобы ни у одного из Википедистов не возникало соблазна использовать Inkscape и сделать файл не подлежащим обработке (и при этом увеличить размер с чуть менее 2 МБ до более).затем 60 МБ, если вы сохраните его в Inkscape как «стандартное» изображение SVG (которое не всегда дает стандартный совместимый файл), собственный формат Inkscapes, основанный на SVG, делает файлы еще больше).

Я неЯ думаю, что википедия допускает использование javascript в SVG-изображениях, поэтому о о Javascript не может быть и речи .

Я уже знаю, как создавать всплывающие подсказки с помощью javascript и двух разных способов их создания в SVG (ноне в CSS, встроенном в SVG).Причина того, что я не хочу использовать SVG-код для всплывающих подсказок, в дополнение к тому, что уже упоминалось в исходном вопросе, заключается в том, что ни один веб-браузер не поддерживает стандарт, но SVG-средства просмотра поддерживают (но не нестандартные).всплывающие подсказки, которые работают с браузерами), поэтому тот, кто будет вручную вносить исправления в всплывающую подсказку в файле (с помощью текстового редактора), должен будет изменить текст в двух разных местах, скорее всего, со временем, что приведет к появлению разных подсказок при просмотрев разных браузерах / зрителях.

Ответы [ 3 ]

4 голосов
/ 11 августа 2011

Я часто прибегаю к использованию (недопустимого) атрибута title = "" в элементах SVG, поскольку он настолько прост и, кажется, работает в большинстве браузеров.Я понимаю, что ваше требование заключается в том, чтобы оно соответствовало стандартам, и чтобы люди могли редактировать графику в InkScape прозрачно и без нарушения подсказок - для этого вам придется использовать некоторый JavaScript.Вот быстрый пример, который, я надеюсь, вы найдете полезным, он прикрепит событие mouseover к непосредственному родителю каждого элемента и загрузит текстовое содержимое во всплывающей подсказке, отображаемой рядом с курсором.Это при сохранении совместимости с InkScape и возможности использовать диалоговое окно «Свойства объекта» InkScape для установки текста всплывающей подсказки.

С учетом следующего примера SVG:

<svg xmlns="http://www.w3.org/2000/svg">
  <title>Main Title</title>
  <g id="group1">
    <title>Title One</title>
    <circle cx="120" cy="60" r="40" fill="#993333" />
  </g>
  <g id="group2">
    <title>Title Two</title>
    <circle cx="60" cy="60" r="40" fill="#339933" />
    <g id="group3">
      <circle cx="180" cy="60" r="40" fill="#333399" />
      <title>Title Three</title>
    </g>
  </g>
</svg>

Сначала добавьте фиктивный элемент всплывающей подсказки:

<g id="toolTip" transform="translate(0,0)">
  <rect width="150" height="25" />
  <text x="5" y="18"> </text>
</g>

Придайте ему стиль:

<style>
g#toolTip {
visibility: hidden;
}
  g#toolTip rect {
  fill: #FFCC00;
  }
  g#toolTip text {
  font-size: 16px;
  }
</style>

Затем вставьте разбрызгивание JS:

<script>
  <![CDATA[
  var toolTip = document.getElementById('toolTip');
  var titles = document.getElementsByTagName('title');
  for (var i = 0; i < titles.length; i++) {
    titles.item(i).parentNode.addEventListener('mouseover', function(e) {
      showTip(this,xy(e));
    }, true);
    titles.item(i).parentNode.addEventListener('mouseout', function() {
      hideTip();
    }, true);
  }
  function showTip(element,pos) {
    var text = element.getElementsByTagName('title')[0].childNodes[0].nodeValue;
    toolTip.getElementsByTagName('text')[0].childNodes[0].nodeValue = text;
    toolTip.setAttribute('transform', 'translate(' + pos + ')');
    toolTip.style.visibility = 'visible';
  }
  function hideTip() {
    toolTip.style.visibility = 'hidden';
  }
  function xy(e) {
    if (!e) var e = window.event;
    if (e.pageX || e.pageY) {
      return [e.pageX,e.pageY]
    } else if (e.clientX || e.clientY) {
      return [e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,e.clientY + document.body.scrollTop + document.documentElement.scrollTop];
    }
    return [0,0]
  }
  ]]>
</script>

Предостережения: блок JS должен идти внизу файла SVG - и если вы используете редактор XML в InkScape (редко), он испортитсценарий (это можно решить, перейдя во внешний файл JS и добавив обнаружение готовности DOM).

Подход также предполагает, что a) все элементы должны отображаться как всплывающие подсказки, и b) что существует только один элемент на одного родителя(как ни странно, спецификация SVG допускает множественное число) - здесь я жестко запрограммировал его, чтобы он просто использовал первый встреченный дочерний элемент, игнорируя любые последующие.

Примечание: функция xy (e) необходима только для того, чтобы обойти несоответствия браузера, когда дело доходит до сообщения о позиции курсора - вам это может не понадобиться, или вы можете предпочесть прокрутить свою собственную.

Бонус: это может быть легко расширено для использования элемента , если вам нужны более сложные всплывающие подсказки с более длинными битами текста.

1 голос
/ 08 августа 2011

Насколько я могу сказать, вы не можете.Элемент SVG, кажется, ведет себя странно.

Я думал, что вы могли бы применить подобную концепцию, как это, используя CSS3:

<style type="text/css">
acronym{
    position:relative
}
acronym:after {
    content:attr(title);
    position:absolute;
    position:absolute;
    left:100%;
    margin-left:-10px;
    top:-0.5em;
    z-index:2;
    padding:0.25em;
    width:200px;
    background-color:#f1f1f1;
    text-align:center;
    display:none;   
}
acronym:hover:after{
    display:block;
}
</style>

<acronym title="Keep It Simple Stupid"><a href="/">KISS</a></acronym>

Но селектор :after, похоже, не работает наЭлемент SVG

Я думаю, что ваша лучшая ставка - это скрипт jQuery, который работает на $(document).ready() и выполняет всю тяжелую работу за вас.

0 голосов
/ 05 августа 2015

Эта статья: http://codepen.io/recursiev/pen/zpJxs демонстрирует несколько типов всплывающих подсказок с SVG.

Включая то, что вы просили: SVG + CSS.

В основном:

<g class="tooltip css" transform="translate(200,50)">
    <rect x="-3em" y="-45" width="6em" height="1.25em"/>
    <text y="-45" dy="1em" text-anchor="middle" fill="LightSeaGreen">
        SVG/CSS Tip</text>
</g>

Также с некоторыми соответствующими CSS:

.tooltip {
    pointer-events:none; /*let mouse events pass through*/
    opacity:0;
    transition: opacity 0.3s;
    text-shadow:1px 1px 0px gray;
}
g.tooltip:not(.css) {
    fill:currentColor;
}
g.tooltip rect {
    fill: lightblue;
    stroke: gray;
}

В этой статье: http://www.scientificpsychic.com/etc/css-mouseover.html показаны подсказки только для CSS.

в основном:

<span class="dropt" title="Title for the pop-up">Hot Zone Text
    <span style="width:500px;">Pop-up text</span>
</span>

с этим CSS:

span.dropt {border-bottom: thin dotted; background: #ffeedd;}
span.dropt:hover {text-decoration: none; background: #ffffff; z-index: 6; }
span.dropt span {position: absolute; left: -9999px;
  margin: 20px 0 0 0px; padding: 3px 3px 3px 3px;
  border-style:solid; border-color:black; border-width:1px; z-index: 6;}
span.dropt:hover span {left: 2%; background: #ffffff;} 
span.dropt span {position: absolute; left: -9999px;
  margin: 4px 0 0 0px; padding: 3px 3px 3px 3px; 
  border-style:solid; border-color:black; border-width:1px;}
span.dropt:hover span {margin: 20px 0 0 170px; background: #ffffff; z-index:6;}

Между ними вы сможете получить именно то, что вы хотите.

ОБНОВЛЕНИЕ: Это прекрасно работает для меня в Chrome v44, но не в Internet Explorer v9,IE просто дает мне название всплывающего окна, а не само всплывающее окно.

...