4

Given a div of unknown dimensions how can I draw a solid line from one corner to the diagonally opposite corner without using JavaScript?

I thought the CSS3 calc() function might help me here but it seems you can't pull values from the height and width into another property (e.g. transform or background-image) I was hoping I could do something like:

transform: rotate ( calc(atan(height / width)) rad);

(The calculation is probably wrong but more important is that the syntax is totally invented.)

I am targeting Firefox for this project but would prefer something that will work in any modern browser.

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
DJL
  • 2,060
  • 3
  • 20
  • 39

4 Answers4

12

You can use an SVG:

<svg style='width: 200px; height: 200px;'>
    <line x1="0" y1="200" x2="200" y2="0"
        style="stroke:rgb(255,0,0);stroke-width:2"/>
</svg>

With percentage coordinates, if needs be:

<svg style='width: 100%; height: 100%;'>
    <line x1="0" y1="100%" x2="100%" y2="0"
        style="stroke:rgb(255,0,0);stroke-width:2"/>
</svg>

http://jsfiddle.net/qXKfN/2/

(Should work in FF, Chrome, Safari, and IE >= 9)


At various sizes in various browsers, the SVG might be pushed out of its container. One solution is to set line-height: 0px;. Another solution, and probably the preferred solution, is to set position: relative; on the container and position: absolute; on the SVG.

http://jsfiddle.net/qXKfN/3/

svidgen
  • 13,744
  • 4
  • 33
  • 58
2

Or you can use plugin: https://bitbucket.org/stopsopa/jquery.line I couldn't find tools to draw such lines on top of divs in way that don't block clicks beneath, then idea of creating this plugin was born.

Plugin is based on transform-rotate (css3) and one div element.

Using:

$.line(0, 0, 500, 1000);

or

$('selector').line(0, 0, 500, 1000);

you can also change color or width of line:

$('selector').line(0, 0, 500, 1000, {
   css : {
       borderTop: '5px solid red'
   }
});

and you have also callback function:

$('selector').line(0, 0, 500, 1000, {
   css : {
       borderTop: '5px solid red'
   }
}, function (linediv, opt) {
    linediv.css({
        borderBottom : '1px solid black'
    });
});
  • 1
    Hey don't ban this plugin, this is good work, well documented and i really did research to develop this plugin. – monstersmart Jul 07 '14 at 12:36
  • @user1338731 Sorry for the ban. I contacted a moderator and he lifted it. However, if you wrote the plugin yourself you should add something like «**Disclaimer:** I am the developer of the plugin.» to avoid misflagging as spam. – nalply Aug 05 '14 at 17:52
  • And also explain a bit what your plugin does: rotate-transform a border-top. – nalply Aug 05 '14 at 18:04
  • Ok, i'm new here so i will remember that for the future. – monstersmart Aug 06 '14 at 21:55
-1

Sometimes you don't want to use SVG as suggested. Here is an example of pure HTML + vanilla JS code to draw a line from any X1,Y1 to any X2,Y2 in any color & width.

function drawLine(X1, Y1, X2, Y2, color, width) {
  let x1 = X1, y1 = Y1, x2 = X2, y2 = Y2;
  if (X1 > X2) { x1 = X2; y1 = Y2; x2 = X1; y2 = Y1 }
  const dx = x1 - x2
  const dy = y1 - y2
  const d = Math.sqrt(dx * dx + dy * dy)
  const a = Math.atan(dy / dx)
  
  const element = document.createElement('span')
  element.style = `border-top:solid ${color} ${width}px;position:absolute;top: ${y1}px;left:${x1}px;width:${d}px;height:0;transform:translate(-${d/2}px,0) rotate(${a}rad) translate(${d/2}px,0)`
    document.getElementById('root').appendChild(element)
}

drawLine(10, 10, 100, 200, 'red', 5)
drawLine(15, 150, 300, 30, 'green', 15)
<div id="root" style="position:relative">
</div>
Oleg Imanilov
  • 2,591
  • 1
  • 13
  • 26
-1

Here is my line. It's SVG and it's as simple as possible. Easily sizable by their parent element.

    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 100 100"
      preserveAspectRatio="none"
    >
      <line
        x1="0"
        y1="100"
        x2="100"
        y2="0"
        stroke="black"
      />
    </svg>
ThaJay
  • 1,758
  • 1
  • 19
  • 30