Border based triangles not rendering as expected

2019-06-25 14:13发布

I am trying to make a full square out of 4 rotated triangles, but when I position them, there is a thin space between. Even weirder, when I rotate the entire thing, the lines disappear in chrome, but appear in the middle of the triangle (forming an X again) in firefox.

enter image description here

jsFiddle

How can I remove this line without adding background and without losing any of the size? I tried using translate3d, but in every way I tried, it either didn't remove all lines, or reduced the size of the square, which shouldn't happen. All this must feel really weird, so here's a fiddle with the final product to explain why I am doing this (just remove the overflow:hidden attribute at the top of the css to see the logic behind it):

jsFiddle

1条回答
\"骚年 ilove
2楼-- · 2019-06-25 14:53

Why is there a white line?

When you create a div it has borders there all just set to the default property.
So there are borders there but not quite?
Creating triangles in CSS is really a hack. So we use borders in a way there where not intended.
By setting the properties of the borders so they create a triangle you will create a tiny gap that looks like a pixel wide, but its really 0.5px.
Haha your joking right?

nope setting the width to 0.5px solves your problem:

.wrapper {
  width: 200px;
  height: 200px;
  margin: 50px;
  position: relative;
  border: 1px solid #f00;
}
.rotate {
  transform: rotate(45deg);
}
.triangle {
  width: 0.5px;
  height: 0;
  position: absolute;
  left: 0;
  right: ;
  top: 0;
  margin: auto;
  border: 100px solid rgba(0, 0, 0, 0);
  border-bottom-width: 0px;
  border-top-color: #333;
  transform-origin: center bottom;
}
.triangle:nth-child(2) {
  transform: rotate(90deg);
}
.triangle:nth-child(3) {
  transform: rotate(180deg);
}
.triangle:nth-child(4) {
  transform: rotate(270deg);
}
<div class="wrapper">
  <div class="triangle"></div>
  <div class="triangle"></div>
  <div class="triangle"></div>
  <div class="triangle"></div>
</div>
<div class="wrapper rotate">
  <div class="triangle"></div>
  <div class="triangle"></div>
  <div class="triangle"></div>
  <div class="triangle"></div>
</div>

What the?

If you rotate a straight line 45 deg will it be 1px wide?
It will actually be 0.5px wide. Or atleast thats how it will be displayed. So by setting the width to 0.5px there wil be a 1px line?
...nope there will be a 0.25px wide gap.
And since browsers don't render at that size it will be displayed as 0px wide gap :D

To avoid tiny gaps use:

SVG

Seems like your trying to create shapes.
SVG is a good solution for this.

So what i do is i set the style properties with javascript. I took a look at your fiddles and i saw you posted them with rotation as well as progress. Found out that you simple can set element.style.transfrom = "rotate("+amount+"deg)" to rotate it.

What the hell is this stroke-array?
See how there are two circles in the svg code?
The second one has a stroke but not a fill. This creates the shape.
Now we cant to cut that shape into pieces.
Stroke-dasharray : 500; Now its cut into 500 pieces.
Setting it to 500, 500 is a full circle setting 250, 500 would be a half circle.
Still following?
And we want to animate it so we set its the elements style attribute:
path.setAttribute("style", "stroke-dasharray:" + i / 2 + "px ," + length + ";");
Animate its style. What property stroke-dasharray and then set its length to how far we have come i/2 +pxand ofcource the second parameter is its full circle length. and that's 500.

var path = document.querySelector('.progress');
var text = document.querySelector('.progress-text');
var style = window.getComputedStyle(path);
var length = parseInt(style.getPropertyValue('stroke-dasharray'));
var i = 0;
var count = 0;
var ticks = 100;

setInterval(function() {
  if (i < length) {
    path.setAttribute("style", "stroke-dasharray:" + i / 2 + "px ," + length + ";");
    i += length / ticks;
    var turn = parseFloat(i / length * (360 * 8));
    path.style.transform = 'rotate(' + turn + 'deg)';
    //setting the text
    count++;
    text.innerHTML = Math.round((count / ticks) * 100);
  }

}, 100);
.progress {
  fill: none;
  stroke: rgba(146, 245, 200, 05);
  stroke-width: 5;
  stroke-dasharray: 500;
  stroke-linecap: round;
  transform-origin: center center;
}
.back-cirlce {
  fill: #222;
}
.progress-text {
  font-size: 20px;
  fill: rgba(146, 245, 200, 0.5);
}
<span>Classic</span>
<svg width="100px" viewBox="0 0 100 100">
  <circle class="back-circle" cx="50" cy="50" r="50" />
  <circle class="progress" cx="50" cy="50" r="40" />
  <text class="progress-text" text-anchor="middle" x="50" y="50">percentage</text>
</svg>
<span></span>

查看更多
登录 后发表回答