[css] draw diagonal lines in div background with CSS

I have a div for a preview box:

HTML:

<div class="preview-content">PREVIEW</div>

CSS:

.preview-content {
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAGklEQVQIW2NkYGD4D8SMQAwGcAY2AbBKDBUAVuYCBQPd34sAAAAASUVORK5CYII=) repeat;
    width: 100%;
    min-height: 300px;
    max-height: 300px;
    line-height: 300px;
    text-align: center;
    vertical-align: middle;
     font-size: 2em;
}

Question: how to add diagonal lines to div background like in the picture?

note: with CSS only if possible

preview

Thank you in advance.

This question is related to css background line css-shapes diagonal

The answer is


_x000D_
_x000D_
.borders {_x000D_
    width: 200px;_x000D_
    height: 100px;_x000D_
    background-color: black;_x000D_
    border-width: 40px;_x000D_
    border-style: solid;_x000D_
    border-color: red blue green yellow;_x000D_
}
_x000D_
<div class='borders'></div>
_x000D_
_x000D_
_x000D_


I needed to draw arbitrary diagonal lines inside any div. My issue with the other answers posted is that none of them allowed to draw an arbitrary line from point A to point B without doing the trigonometry yourself for the angles. With javascript & CSS you can do this. Hope it's helpful, just specify a pair of points and you're golden.

_x000D_
_x000D_
const objToStyleString = (obj) => {_x000D_
  const reducer = (acc, curr) => acc += curr + ": " + obj[curr] + ";"; _x000D_
  return Object.keys(obj).reduce(reducer, "")_x000D_
};_x000D_
_x000D_
const lineStyle = (xy1, xy2, borderStyle) => {_x000D_
  const p1 = {x: xy1[0], y: xy1[1]};_x000D_
  const p2 = {x: xy2[0], y: xy2[1]};_x000D_
  _x000D_
  const a = p2.x - p1.x;_x000D_
  const xOffset = p1.x;_x000D_
  const b = p2.y - p1.y;_x000D_
  const yOffset = p1.y;_x000D_
  _x000D_
  const c = Math.sqrt(a*a + b*b);_x000D_
  _x000D_
  const ang = Math.acos(a/c);_x000D_
  _x000D_
  const tX1 = `translateX(${-c/2 + xOffset}px) `;_x000D_
  const tY1 = `translateY(${yOffset}px) `;_x000D_
  const rot = `rotate(${ang}rad) `;_x000D_
  const tX2 = `translateX(${c/2}px) `;_x000D_
  const tY2 = `translateY(${0}px) `;_x000D_
  _x000D_
  return {_x000D_
    "width": Math.floor(c) + "px",_x000D_
    "height": "0px",_x000D_
    "border-top": borderStyle,_x000D_
    "-webkit-transform": tX1+tY1+rot+tX2+tY2,_x000D_
    "position": "relative",_x000D_
    "top": "0px",_x000D_
    "left": "0px",_x000D_
    "box-sizing": "border-box",_x000D_
  };_x000D_
};_x000D_
_x000D_
function drawLine(parent, p1, p2, borderStyle) {_x000D_
  const style = lineStyle(p1, p2, borderStyle);_x000D_
  const line = document.createElement("div");_x000D_
  line.style = objToStyleString(style);_x000D_
  parent.appendChild(line);_x000D_
}_x000D_
_x000D_
drawLine(container, [100,5], [25,195], "1px dashed purple");_x000D_
drawLine(container, [100,100], [190,190], "1px solid blue");_x000D_
drawLine(container, [25,150], [175,150], "2px solid red");_x000D_
drawLine(container, [25,10], [175,20], "5px dotted green");
_x000D_
#container {_x000D_
  background-color: #BCBCBC;_x000D_
  width: 200px;_x000D_
  height: 200px;_x000D_
  padding: 0; _x000D_
  margin: 0;_x000D_
}
_x000D_
<div id="container">_x000D_
</div>
_x000D_
_x000D_
_x000D_


Please check the following.

<canvas id="myCanvas" width="200" height="100"></canvas>
<div id="mydiv"></div>

JS:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle="red";
ctx.moveTo(0,100);
ctx.lineTo(200,0);
ctx.stroke();
ctx.moveTo(0,0);
ctx.lineTo(200,100);
ctx.stroke();

CSS:

html, body { 
  margin: 0;
  padding: 0;
}

#myCanvas {
  padding: 0;
  margin: 0;
  width: 200px;
  height: 100px;
}

#mydiv {
  position: absolute;
  left: 0px;
  right: 0;
  height: 102px;
  width: 202px;
  background: rgba(255,255,255,0);
  padding: 0;
  margin: 0;
}

jsfiddle


intrepidis' answer on this page using a background SVG in CSS has the advantage of scaling nicely to any size or aspect ratio, though the SVG uses <path>s with a fill that doesn't scale so well.

I've just updated the SVG code to use <line> instead of <path> and added non-scaling-stroke vector-effect to prevent the strokes scaling with the container:

<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'>
  <line x1='0' y1='0' x2='100' y2='100' stroke='black' vector-effect='non-scaling-stroke'/>
  <line x1='0' y1='100' x2='100' y2='0' stroke='black' vector-effect='non-scaling-stroke'/>
</svg>

Here's that dropped into the CSS from the original answer (with HTML made resizable):

_x000D_
_x000D_
.diag {_x000D_
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><line x1='0' y1='0' x2='100' y2='100' stroke='black' vector-effect='non-scaling-stroke'/><line x1='0' y1='100' x2='100' y2='0' stroke='black' vector-effect='non-scaling-stroke'/></svg>");_x000D_
  background-repeat: no-repeat;_x000D_
  background-position: center center;_x000D_
  background-size: 100% 100%, auto;_x000D_
}
_x000D_
<div class="diag" style="width: 200px; height: 150px; border: 1px solid; resize: both; overflow: auto"></div>
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
.crossed {
    width: 200px;
    height: 200px;
    border:solid 1px;
    background-color: rgb(210, 137, 226);
    background-image: repeating-linear-gradient(
      45deg,
      transparent,
      transparent 15px,
      #ccc 10px,
      #ccc 20px
        ),
      repeating-linear-gradient(
        135deg,
        transparent,
        transparent 15px,
        #ccc 10px,
        #ccc 20px
      );
}
_x000D_
<div class='crossed'>Hello world</div>
_x000D_
_x000D_
_x000D_


Here is how I did this using the css clip-path property alongside relative and absolute positioning to create a more fancy cross.

_x000D_
_x000D_
.cross {_x000D_
  width:150px;_x000D_
  height: 150px;_x000D_
  border: 2px solid #555;_x000D_
  border-radius: 5px;_x000D_
  position: relative;_x000D_
  background: #efefef;_x000D_
}_x000D_
_x000D_
.cross .diag1{_x000D_
  position: absolute;_x000D_
  width:100%; height:100%;_x000D_
  clip-path: polygon(90% 0, 100% 0%, 10% 100%, 0% 100%);_x000D_
  background: #311B92;_x000D_
}_x000D_
_x000D_
.cross .diag2{_x000D_
  position: absolute;_x000D_
  width:100%; height:100%;_x000D_
  clip-path: polygon(0 0, 10% 0, 100% 100%, 90% 100%);_x000D_
  background: #1B5E20;_x000D_
}
_x000D_
<div class="cross">_x000D_
  <div class="diag1"></div>_x000D_
  <div class="diag2"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Here is a link to the code on codepen if you'd like to tweak it.


You can use SVG to draw the lines.

_x000D_
_x000D_
.diag {_x000D_
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M1 0 L0 1 L99 100 L100 99' fill='black' /><path d='M0 99 L99 0 L100 1 L1 100' fill='black' /></svg>");_x000D_
    background-repeat:no-repeat;_x000D_
    background-position:center center;_x000D_
    background-size: 100% 100%, auto;_x000D_
}
_x000D_
<div class="diag" style="width: 300px; height: 100px;"></div>
_x000D_
_x000D_
_x000D_

Have a play here: http://jsfiddle.net/tyw7vkvm


All other answers to this 3-year old question require CSS3 (or SVG). However, it can also be done with nothing but lame old CSS2:

_x000D_
_x000D_
.crossed {_x000D_
    position: relative;_x000D_
    width: 300px;_x000D_
    height: 300px;_x000D_
}_x000D_
_x000D_
.crossed:before {_x000D_
    content: '';_x000D_
    position: absolute;_x000D_
    left: 0;_x000D_
    right: 0;_x000D_
    top: 1px;_x000D_
    bottom: 1px;_x000D_
    border-width: 149px;_x000D_
    border-style: solid;_x000D_
    border-color: black white;_x000D_
}_x000D_
_x000D_
.crossed:after {_x000D_
    content: '';_x000D_
    position: absolute;_x000D_
    left: 1px;_x000D_
    right: 1px;_x000D_
    top: 0;_x000D_
    bottom: 0;_x000D_
    border-width: 149px;_x000D_
    border-style: solid;_x000D_
    border-color: white transparent;_x000D_
}
_x000D_
<div class='crossed'></div>
_x000D_
_x000D_
_x000D_

Explanation, as requested:

Rather than actually drawing diagonal lines, it occurred to me we can instead color the so-called negative space triangles adjacent to where we want to see these lines. The trick I came up with to accomplish this exploits the fact that multi-colored CSS borders are bevelled diagonally:

_x000D_
_x000D_
.borders {_x000D_
    width: 200px;_x000D_
    height: 100px;_x000D_
    background-color: black;_x000D_
    border-width: 40px;_x000D_
    border-style: solid;_x000D_
    border-color: red blue green yellow;_x000D_
}
_x000D_
<div class='borders'></div>
_x000D_
_x000D_
_x000D_

To make things fit the way we want, we choose an inner rectangle with dimensions 0 and LINE_THICKNESS pixels, and another one with those dimensions reversed:

_x000D_
_x000D_
.r1 { width: 10px;_x000D_
      height: 0;_x000D_
      border-width: 40px;_x000D_
      border-style: solid;_x000D_
      border-color: red blue;_x000D_
      margin-bottom: 10px; }_x000D_
.r2 { width: 0;_x000D_
      height: 10px;_x000D_
      border-width: 40px;_x000D_
      border-style: solid;_x000D_
      border-color: blue transparent; }
_x000D_
<div class='r1'></div><div class='r2'></div>
_x000D_
_x000D_
_x000D_

Finally, use the :before and :after pseudo-selectors and position relative/absolute as a neat way to insert the borders of both of the above rectangles on top of each other into your HTML element of choice, to produce a diagonal cross. Note that results probably look best with a thin LINE_THICKNESS value, such as 1px.


Almost perfect solution, that automatically scales to dimensions of an element would be usage of CSS3 linear-gradient connected with calc() as shown below. Main drawback is of course compatibility. Code below works in Firefox 25 and Explorer 10 and 11, but in Chrome (I've tested v30 and v32 dev) there are some subtle problems with lines disappearing if they are too narrow. Moreover disappearing depends on the box dimensions – style below works for div { width: 100px; height: 100px}, but fails for div { width: 200px; height: 200px} for which in my tests 0.8px in calculations needs to be replaced with at least 1.1048507095px for diagonals to be shown and even then line rendering quality is quite poor. Let's hope this Chrome bug will be solved soon.

_x000D_
_x000D_
.crossed {_x000D_
     background: _x000D_
         linear-gradient(to top left,_x000D_
             rgba(0,0,0,0) 0%,_x000D_
             rgba(0,0,0,0) calc(50% - 0.8px),_x000D_
             rgba(0,0,0,1) 50%,_x000D_
             rgba(0,0,0,0) calc(50% + 0.8px),_x000D_
             rgba(0,0,0,0) 100%),_x000D_
         linear-gradient(to top right,_x000D_
             rgba(0,0,0,0) 0%,_x000D_
             rgba(0,0,0,0) calc(50% - 0.8px),_x000D_
             rgba(0,0,0,1) 50%,_x000D_
             rgba(0,0,0,0) calc(50% + 0.8px),_x000D_
             rgba(0,0,0,0) 100%);_x000D_
}
_x000D_
<textarea class="crossed"></textarea>
_x000D_
_x000D_
_x000D_


An svg dynamic solution for any screen is the following:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" stroke-width="1" stroke="#000">
  <line x1="0" y1="0" x2="100%" y2="100%"/>
  <line x1="100%" y1="0" x2="0" y2="100%"/>
</svg>

And if you want to keep it in background use the position: absolute with top and left 0.


If you'd like the cross to be partially transparent, the naive approach would be to make linear-gradient colors semi-transparent. But that doesn't work out good due to the alpha blending at the intersection, producing a differently colored diamond. The solution to this is to leave the colors solid but add transparency to the gradient container instead:

_x000D_
_x000D_
.cross {_x000D_
  position: relative;_x000D_
}_x000D_
.cross::after {_x000D_
  pointer-events: none;_x000D_
  content: "";_x000D_
  position: absolute;_x000D_
  top: 0; bottom: 0; left: 0; right: 0;_x000D_
}_x000D_
_x000D_
.cross1::after {_x000D_
  background:_x000D_
    linear-gradient(to top left, transparent 45%, rgba(255,0,0,0.35) 46%, rgba(255,0,0,0.35) 54%, transparent 55%),_x000D_
    linear-gradient(to top right, transparent 45%, rgba(255,0,0,0.35) 46%, rgba(255,0,0,0.35) 54%, transparent 55%);_x000D_
}_x000D_
_x000D_
.cross2::after {_x000D_
  background:_x000D_
    linear-gradient(to top left, transparent 45%, rgb(255,0,0) 46%, rgb(255,0,0) 54%, transparent 55%),_x000D_
    linear-gradient(to top right, transparent 45%, rgb(255,0,0) 46%, rgb(255,0,0) 54%, transparent 55%);_x000D_
  opacity: 0.35;_x000D_
}_x000D_
_x000D_
div { width: 180px; text-align: justify; display: inline-block; margin: 20px; }
_x000D_
<div class="cross cross1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et dui imperdiet, dapibus augue quis, molestie libero. Cras nisi leo, sollicitudin nec eros vel, finibus laoreet nulla. Ut sit amet leo dui. Praesent rutrum rhoncus mauris ac ornare. Donec in accumsan turpis, pharetra eleifend lorem. Ut vitae aliquet mi, id cursus purus.</div>_x000D_
_x000D_
<div class="cross cross2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et dui imperdiet, dapibus augue quis, molestie libero. Cras nisi leo, sollicitudin nec eros vel, finibus laoreet nulla. Ut sit amet leo dui. Praesent rutrum rhoncus mauris ac ornare. Donec in accumsan turpis, pharetra eleifend lorem. Ut vitae aliquet mi, id cursus purus.</div>
_x000D_
_x000D_
_x000D_


you can use a CSS3 transform Property:

div
{
transform:rotate(Xdeg);
-ms-transform:rotate(Xdeg); /* IE 9 */
-webkit-transform:rotate(Xdeg); /* Safari and Chrome */
}

Xdeg = your value

For example...

You can make more div and use a z-index property. So,make a div with line, and rotate it.


Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to background

SwiftUI - How do I change the background color of a View? Changing background color of selected item in recyclerview Android Studio Image Asset Launcher Icon Background Color Android: keep Service running when app is killed How to set a background image in Xcode using swift? CSS Background image not loading css transition opacity fade background how to set the background image fit to browser using html background:none vs background:transparent what is the difference? How to scale images to screen size in Pygame

Examples related to line

How do I compute the intersection point of two lines? Java Replace Line In Text File draw diagonal lines in div background with CSS How to make a new line or tab in <string> XML (eclipse/android)? How do you run a command for each line of a file? How can I format a list to print each element on a separate line in python? Remove lines that contain certain string How to paste text to end of every line? Sublime 2 Making PHP var_dump() values display one line per value How to do multiple line editing?

Examples related to css-shapes

How to create a inner border for a box in html? CSS Circle with border How to Make A Chevron Arrow Using CSS? How to make a div with a circular shape? How to make rectangular image appear circular with CSS Half circle with CSS (border, outline only) How to draw a checkmark / tick using CSS? how to draw a rectangle in HTML or CSS? CSS3 Transform Skew One Side Center Triangle at Bottom of Div

Examples related to diagonal

draw diagonal lines in div background with CSS