使用CSS在div背景中绘制对角线

Posted

技术标签:

【中文标题】使用CSS在div背景中绘制对角线【英文标题】:draw diagonal lines in div background with CSS 【发布时间】:2013-08-03 11:02:30 【问题描述】:

我有一个用于预览框的 div:

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;

问题:如何像图中那样在div背景中添加对角线?

注意:仅在可能的情况下使用 CSS

提前谢谢你。

【问题讨论】:

你只想添加两行吗? 是的,只有 2 个和图片一样 【参考方案1】:

自动缩放到元素尺寸的解决方案是使用与 calc() 连接的 CSS3 线性渐变,如下所示。 (在这个答案最初描述的 v30+ 版本中,Chrome 存在一些问题,但看起来它们在此期间得到了解决,并且在 v90+ 中它按预期工作)。

.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%);
&lt;textarea class="crossed"&gt;&lt;/textarea&gt;

【讨论】:

这里有一个 jsfiddle,如果你想玩这个解决方案:jsfiddle.net/zaxy6pmn 在 Chrome 39 中看起来基本没问题,但右下角的“手臂”有一个额外的像素。根据周围的情况,这可能不明显,除非尺寸非常小,例如5x5 像素。 不错的解决方案。将其更新为背景重复:jsfiddle.net/6q4m4ww8我现在的问题是如何在 x-es 之间添加距离 你的意思是http://jsfiddle.net/8f5rgn8t/? ;)(尽管可能需要对较粗的线条进行更多调整,因为每条线的一端剪裁到边界框的垂直侧,另一端剪裁到水平) 如果我想将背景颜色改为灰色而不是白色怎么办?【参考方案2】:

你可以这样做:

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

这是jsfiddle。

为您的目的改进了answer 版本。

【讨论】:

使用-webkit-transform 仅适用于基于 WebKit 的浏览器。我建议首先指定标准 W3C transform 规则,然后指定其他浏览器特定规则,例如 -webkit-transform-moz-transform-ms-transform-o-transform【参考方案3】:

您可以使用 SVG 来绘制线条。

.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;
&lt;div class="diag" style="width: 300px; height: 100px;"&gt;&lt;/div&gt;

在这里玩一玩:http://jsfiddle.net/tyw7vkvm

【讨论】:

不错!正在寻找一种模拟“划掉”价格的解决方案,并且通过一些小的改动效果很好jsfiddle.net/tyw7vkvm/636? @intrepidis 如何增加线条的粗细? 类似于&lt;path stroke-width='2' d='...'&gt; @TonyMathew 这里是 4 像素厚:&lt;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' /&gt;&lt;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' /&gt; 只需将 4's 和 96's 更改为您需要的任何厚度。 (例如 2 和 98、5 和 95)【参考方案4】:

这个 3 年前的问题的所有其他答案都需要 CSS3(或 SVG)。但是,也可以只用蹩脚的旧 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;
&lt;div class='crossed'&gt;&lt;/div&gt;

按要求解释:

而不是实际绘制对角线,我想到我们可以在我们想要看到这些线的位置附近为所谓的 负空间 三角形着色。我想出的实现这一点的技巧是利用多色 CSS 边框对角倾斜的事实:

.borders 
    width: 200px;
    height: 100px;
    background-color: black;
    border-width: 40px;
    border-style: solid;
    border-color: red blue green yellow;
&lt;div class='borders'&gt;&lt;/div&gt;

为了使事情符合我们想要的方式,我们选择一个尺寸为 0 和 LINE_THICKNESS 像素的内部矩形,以及另一个尺寸相反的矩形:

.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; 
&lt;div class='r1'&gt;&lt;/div&gt;&lt;div class='r2'&gt;&lt;/div&gt;

最后,使用 :before:after 伪选择器和定位 relative/absolute 作为一种巧妙的方法,将上述两个矩形的边框相互重叠插入到您选择的 HTML 元素中,以生成一个对角线十字架。请注意,使用细 LINE_THICKNESS 值(例如 1px)时结果可能看起来最好。

【讨论】:

是的,不错的技巧,但忽略了原始问题的一个假设:width: 100%div 被交叉;)虽然,公平地说,从接受的答案猜测,看起来不是硬要求。【参考方案5】:

此页面上的intrepidis' answer 在 CSS 中使用背景 SVG 的优点是可以很好地缩放到任何大小或纵横比,尽管 SVG 使用的填充不是很好地缩放的 &lt;path&gt;s。

我刚刚更新了 SVG 代码以使用 &lt;line&gt; 而不是 &lt;path&gt; 并添加了 non-scaling-stroke vector-effect 以防止笔划随容器缩放:

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

这是从原始答案中放入 CSS 的(HTML 可调整大小):

.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;
&lt;div class="diag" style="width: 200px; height: 150px; border: 1px solid; resize: both; overflow: auto"&gt;&lt;/div&gt;

【讨论】:

与其他形状/结构相比,这非常适合绘制线条。谢谢。【参考方案6】:

请检查以下内容。

<canvas id="myCanvas"  ></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

【讨论】:

注意宽度是100%,width: 100%;所以盒子会浮动,所以我不能将坐标永久写入js【参考方案7】:

.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
      );
&lt;div class='crossed'&gt;Hello world&lt;/div&gt;

【讨论】:

【参考方案8】:

您可以使用 CSS3 转换属性:

div

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

Xdeg = 你的价值

例如...

您可以制作更多 div 并使用 z-index 属性。 所以,用线条制作一个 div,然后旋转它。

【讨论】:

【参考方案9】:

任何屏幕的 svg 动态解决方案如下:

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

如果您想将其保留在后台,请使用 position: absolute 顶部和左侧 0。

【讨论】:

【参考方案10】:

如果您希望十字架部分透明,最简单的方法是将linear-gradient 颜色设为半透明。但这并不好,因为交叉处的 alpha 混合会产生不同颜色的钻石。解决这个问题的方法是让颜色保持纯色,但为渐变容器添加透明度:

.cross 
  position: relative;

.cross::after 
  pointer-events: none;
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;


.cross1::after 
  background:
    linear-gradient(to top left, transparent 45%, rgba(255,0,0,0.35) 46%, rgba(255,0,0,0.35) 54%, transparent 55%),
    linear-gradient(to top right, transparent 45%, rgba(255,0,0,0.35) 46%, rgba(255,0,0,0.35) 54%, transparent 55%);


.cross2::after 
  background:
    linear-gradient(to top left, transparent 45%, rgb(255,0,0) 46%, rgb(255,0,0) 54%, transparent 55%),
    linear-gradient(to top right, transparent 45%, rgb(255,0,0) 46%, rgb(255,0,0) 54%, transparent 55%);
  opacity: 0.35;


div  width: 180px; text-align: justify; display: inline-block; margin: 20px; 
<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>

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

【讨论】:

【参考方案11】:

这是我如何使用 css clip-path 属性以及 relativeabsolute 定位来创建一个更花哨的十字架。

.cross 
  width:150px;
  height: 150px;
  border: 2px solid #555;
  border-radius: 5px;
  position: relative;
  background: #efefef;


.cross .diag1
  position: absolute;
  width:100%; height:100%;
  clip-path: polygon(90% 0, 100% 0%, 10% 100%, 0% 100%);
  background: #311B92;


.cross .diag2
  position: absolute;
  width:100%; height:100%;
  clip-path: polygon(0 0, 10% 0, 100% 100%, 90% 100%);
  background: #1B5E20;
<div class="cross">
  <div class="diag1"></div>
  <div class="diag2"></div>
</div>

如果您想调整它,这里是link to the code on codepen。

【讨论】:

【参考方案12】:

我需要在任何 div 内绘制任意对角线。我对发布的其他答案的问题是,如果不对角度进行三角测量,他们都不允许从 A 点到 B 点画一条任意线。使用 javascript & CSS 你可以做到这一点。希望对您有所帮助,只需指定一对点即可。

const objToStyleString = (obj) => 
  const reducer = (acc, curr) => acc += curr + ": " + obj[curr] + ";"; 
  return Object.keys(obj).reduce(reducer, "")
;

const lineStyle = (xy1, xy2, borderStyle) => 
  const p1 = x: xy1[0], y: xy1[1];
  const p2 = x: xy2[0], y: xy2[1];
  
  const a = p2.x - p1.x;
  const xOffset = p1.x;
  const b = p2.y - p1.y;
  const yOffset = p1.y;
  
  const c = Math.sqrt(a*a + b*b);
  
  const ang = Math.acos(a/c);
  
  const tX1 = `translateX($-c/2 + xOffsetpx) `;
  const tY1 = `translateY($yOffsetpx) `;
  const rot = `rotate($angrad) `;
  const tX2 = `translateX($c/2px) `;
  const tY2 = `translateY($0px) `;
  
  return 
    "width": Math.floor(c) + "px",
    "height": "0px",
    "border-top": borderStyle,
    "-webkit-transform": tX1+tY1+rot+tX2+tY2,
    "position": "relative",
    "top": "0px",
    "left": "0px",
    "box-sizing": "border-box",
  ;
;

function drawLine(parent, p1, p2, borderStyle) 
  const style = lineStyle(p1, p2, borderStyle);
  const line = document.createElement("div");
  line.style = objToStyleString(style);
  parent.appendChild(line);


drawLine(container, [100,5], [25,195], "1px dashed purple");
drawLine(container, [100,100], [190,190], "1px solid blue");
drawLine(container, [25,150], [175,150], "2px solid red");
drawLine(container, [25,10], [175,20], "5px dotted green");
#container 
  background-color: #BCBCBC;
  width: 200px;
  height: 200px;
  padding: 0; 
  margin: 0;
<div id="container">
</div>

【讨论】:

【参考方案13】:

.borders 
    width: 200px;
    height: 100px;
    background-color: black;
    border-width: 40px;
    border-style: solid;
    border-color: red blue green yellow;
&lt;div class='borders'&gt;&lt;/div&gt;

【讨论】:

以上是关于使用CSS在div背景中绘制对角线的主要内容,如果未能解决你的问题,请参考以下文章

如何将多个线性渐变添加到 CSS 背景?如果

css 花蜜滑块改变对角线预加载背景

通过 <div> 或 <span> 的对角线

在 Swift 中绘制对角线

如何在表格的某单元格中绘制一条对角线

itextsharp C#:如何在表格单元格内绘制对角线