draw diagonal lines in div background with CSS

213,405

Solution 1

You can do it something like this:

<style>
    .background {
        background-color: #BCBCBC;
        width: 100px;
        height: 50px;
        padding: 0; 
        margin: 0
    }
    .line1 {
        width: 112px;
        height: 47px;
        border-bottom: 1px solid red;
        -webkit-transform:
            translateY(-20px)
            translateX(5px)
            rotate(27deg); 
        position: absolute;
        /* top: -20px; */
    }
    .line2 {
        width: 112px;
        height: 47px;
        border-bottom: 1px solid green;
        -webkit-transform:
            translateY(20px)
            translateX(5px)
            rotate(-26deg);
        position: absolute;
        top: -33px;
        left: -13px;
    }
</style>
<div class="background">
    <div class="line1"></div>
    <div class="line2"></div>
</div>

Here is a jsfiddle.

Improved version of answer for your purpose.

Solution 2

Solution that automatically scales to dimensions of an element would be usage of CSS3 linear-gradient connected with calc() as shown below. (There were some issues with Chrome in times of v30+ versions that this answer originally described but looks like they got resolved in the meantime and in v90+ it works as expected).

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

Solution 3

You can use SVG to draw the lines.

.diag {
    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>");
    background-repeat:no-repeat;
    background-position:center center;
    background-size: 100% 100%, auto;
}
<div class="diag" style="width: 300px; height: 100px;"></div>

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

Solution 4

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:

.crossed {
    position: relative;
    width: 300px;
    height: 300px;
}

.crossed:before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 1px;
    bottom: 1px;
    border-width: 149px;
    border-style: solid;
    border-color: black white;
}

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

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:

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

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:

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

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.

Solution 5

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):

.diag {
  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>");
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 100% 100%, auto;
}
<div class="diag" style="width: 200px; height: 150px; border: 1px solid; resize: both; overflow: auto"></div>
Share:
213,405
Ing. Michal Hudak
Author by

Ing. Michal Hudak

Updated on July 05, 2022

Comments

  • Ing. Michal Hudak
    Ing. Michal Hudak almost 2 years

    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.

  • Ing. Michal Hudak
    Ing. Michal Hudak almost 11 years
    notice that width is 100%, width: 100%; so box will be floating, so I can't write coordinates permanent into js
  • T-moty
    T-moty over 9 years
    With -webkit-transform will work only on WebKit based browsers. I suggest to specify the standard W3C transform rule as first step, then specify other browser-specific rule, such -webkit-transform, -moz-transform, -ms-transform, -o-transform.
  • danvk
    danvk over 9 years
    Here's a jsfiddle in case you want to play with this solution: jsfiddle.net/zaxy6pmn
  • mrec
    mrec over 9 years
    Looks mostly OK in Chrome 39, but the lower-right "arm" has an extra pixel. Depending on what's around it this may not be noticeable except at very small sizes, e.g. 5x5 pixels.
  • Daniel Ursu
    Daniel Ursu about 7 years
    Nice solution. Updated it to background repeat: jsfiddle.net/6q4m4ww8 My issue now is how to add a distance between x-es
  • RobertT
    RobertT about 7 years
    You mean something like http://jsfiddle.net/8f5rgn8t/? ;) (though probably need a little bit more of tweaking for thicker lines, as each line has one end clipped to vertical side of bounding box and second one to horizontal)
  • RobertT
    RobertT about 7 years
    Yeah, nice trick, but ignores one assumption of original question: width: 100% of div to be crossed ;) Though, to be fair, guessing from accepted answer, looks like it wasn't hard requirement.
  • Mavelo
    Mavelo almost 6 years
    Nice! Was looking for a solution to emulate a "crossed out" price and this worked great with a few minor alterations jsfiddle.net/tyw7vkvm/636 👍
  • Bargain23
    Bargain23 almost 5 years
    What if I wanted to change the background color to grey instead of white?
  • TylerH
    TylerH over 4 years
    @Bargain23 Change the rgba values to be grey values.
  • Tony Mathew
    Tony Mathew over 4 years
    @intrepidis How to increase the thickness of the lines?
  • intrepidis
    intrepidis over 4 years
    It's something like <path stroke-width='2' d='...'>
  • Sam Eaton
    Sam Eaton about 4 years
    @TonyMathew here is 4 pixel thick: <path d='M 4 0 L 4 0 L 0 0 L 0 4 L 96 100 L 100 100 L 100 96' fill='black' /><path d='M 96 0 L 96 0 L 100 0 L 100 4 L 4 100 L 0 100 L 0 96' fill='black' /> just change the 4's and 96's to whatever thickness you need. (e.g. 2 and 98, 5 and 95)
  • Tsurule Vol
    Tsurule Vol over 3 years
    Best :) As for me
  • jis0324
    jis0324 almost 3 years
    Perfect reusable solution
  • tyrex
    tyrex over 2 years
    This is great for drawing lines, in contrast to other shapes/structures. Thanks.
  • Patrick Szalapski
    Patrick Szalapski over 2 years
    When my containing div is just 2px tall (i.e. the line is nearly horizontal), both Firefox and Chrome seem to fade out the beginning and end of the lines. I'm guessing this is antialiasing? Any way to turn it off?
  • Elmatou
    Elmatou about 2 years
    Nice proposal for more advance needs. why do you translate the div before and after the rotate ? It seems to work fine with a single translate by offset values with "transform-origin: top left;".