4 Triangle Square

How would I make this 4 triangle square:

Width: 640
Height: 360

https://jsfiddle.net/f0pahn8r/

div {
  width: 0px;
  height: 0px;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;

}

.red {
  border-top: 100px solid red;
}

.blue {
  border-top: 100px solid blue;
  -webkit-transform: rotate(180deg);
}

.green {
  border-top: 100px solid green;
  -webkit-transform: rotate(270deg);
  position: absolute;
  left: -42px;
  top: 58px;
}

.yellow {
  border-top: 100px solid yellow;
  -webkit-transform: rotate(90deg);
  position: absolute;
  top: 58px;
  left: 58px;
}
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
<div class="yellow"></div>

Next I would want to add it to here: https://jsfiddle.net/m941Lgeu/

After that, would I be able to have all 4 triangles slide open?

My guess:

.curtain.slide .panel-left {
  transform: translateX(calc(-100% - 1px));
}

.curtain.slide .panel-right {
  transform: translateX(calc(100% + 1px));
}

.curtain.slide .panel-up {
  transform: translateY(calc(-100% - 1px));
}

.curtain.slide .panel-down {
  transform: translateY(calc(100% + 1px));
}
      <div class="panel-left"></div>
      <div class="panel-right"></div>
      <div class="panel-up"></div>
      <div class="panel-down"></div>

How can it be square if its 640 x 360? That’s an oblong.
Please clarify the question.

You can make the square in one div.

Slide open in which directions?

Are you talking about a 4 way slide as in these other demos you asked for?

Or do you mean that the coloured block is split down the center like the curtain?

Is it always 640x360 or does it scale smaller like your other demos?

Whatever this one is set as.

I was only adding it to this one.

https://jsfiddle.net/m941Lgeu/

You can just add this to the css and use the existing panel assuming you don’t have extra images there.


.panel-left::before,
.panel-right:before {
  width: 0px;
  height: 0px;
  border-top: 100px solid red;
  border-bottom: 100px solid blue;
  border-left: 100px solid green;
  border-right: 100px solid yellow;
  border-width: 180px 320px;
}

What did I do wrong? https://jsfiddle.net/turah28q/1/

It should scale when it gets bigger and smaller.

.panel-left::before,
.panel-right::before {
  content: "";
  position: absolute;
  height: 100%;
  width: 200%;
  top: 0;
  left: 0;
  
  width: 0px;
  height: 0px;
  border-top: 100px solid red;
  border-bottom: 100px solid blue;
  border-left: 100px solid green;
  border-right: 100px solid yellow;
  border-width: 180px 320px;
 
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  pointer-events: none;
}

Percentages would be given to these?

I’m stuck.

  width: 0px;
  height: 0px;
  border-top: 100px solid red;
  border-bottom: 100px solid blue;
  border-left: 100px solid green;
  border-right: 100px solid yellow;
  border-width: 180px 320px;

You asked for thisi:

Width: 640
Height: 360

Which is what you got.

I asked you this:

If you answer the questions properly then you will get better answers :slight_smile:

Does it need to scale bigger than 640 x 320 also

640 x 320

no, only when it gets smaller.

Yes, like in my other demos.

Also, am I able to do this?

Top Triangle should slide up
border-top: 100px solid red;

Bottom Triangle should slide down
border-bottom: 100px solid blue;

Left Triangle should slide Left
border-left: 100px solid green;

Right Triangle should side right
border-right: 100px solid yellow;

Like this?

.curtain.slide .panel-left {
  border-left: 100px solid green;
  transform: translateX(calc(-100% - 1px));
}

.curtain.slide .panel-right {
  border-right: 100px solid yellow;
  transform: translateX(calc(100% + 1px));
}

.curtain.slide .panel-up {
  border-top: 100px solid red;
  transform: translateY(calc(-100% - 1px));
}

.curtain.slide .panel-down {
  border-bottom: 100px solid blue;
  transform: translateY(calc(100% + 1px));
}

To make it scale smaller you would need to replace the rules with the foolowing.

.panel-left::before,
.panel-right:before {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 50%;
  right: 0;
  left: auto;
  content: "";
  width: 0px;
  height: 0px;
  border-top: 180px solid red;
  border-bottom: 180px solid blue;
  transform:translateY(-50%);
  pointer-events: none;
}
.panel-left:before {
  border-left: 320px solid green;
}
.panel-right:before {
  left: 0;
  right: auto;
  border-right: 320px solid yellow;
}

/*
.panel-right::before {
  left: -100%;
}
*/

That assumes that it will scale smaller but get no larger. (Note you cannot specify border-widths in percentages.)

Assuming you want the top and bottom to travel vertically then you will need the panel-up and panel down divs and make them transition up and down as per the left and right.

If that’s all you are going to do then it may be possible to simplify the structure and just use four divs as you are no actually splitting anything anymore as they are all different. You’d put one coloured border and three transparent borders to get the triangle and then overlay them on top and move them as required.

Let me think about it.

Here’s the 4 elements splitting but I haven’t made them scale smaller yet as it’s dinner time.:slight_smile:

.panel-left,
.panel-right,
.panel-up,
.panel-down{
  position: absolute;
  transition: all 8s ease;
  transition-delay: 0s;
  overflow: hidden;
  width:0;
  height:0;
}
.panel-up {
  left: 0;
  bottom:50%;
  border-top: 180px solid red;
  border-left:320px solid transparent;
  border-right:320px solid transparent;
  }
  .panel-down {
  left: 0;
  top:50%;
  border-bottom: 180px solid blue;
  border-left:320px solid transparent;
  border-right:320px solid transparent;
  }
  .panel-left {
  top:-50%;
  bottom:-50%;
  margin:auto 0;
  border-left: 320px solid green;
  border-top:180px solid transparent;
  border-bottom:180px solid transparent;
  }
  .panel-right {
  top:-50%;
  bottom:-50%;
  right:0;
  margin:auto 0;
  border-right: 320px solid yellow;
  border-top:180px solid transparent;
  border-bottom:180px solid transparent;
  }


/*
.panel-left::before,
.panel-right:before {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 50%;
  right: 0;
  left: auto;
  content: "";
  width: 0px;
  height: 0px;
  border-top: 180px solid red;
  border-bottom: 180px solid blue;
  transform:translateY(-50%);
  pointer-events: none;
}
.panel-left:before {
  border-left: 320px solid green;
}
.panel-right:before {
  left: 0;
  right: auto;
  border-right: 320px solid yellow;
}
*/

/*
.panel-right::before {
  left: -100%;
}
*/
.curtain.slide .panel-left {
  transform: translateX(calc(-100% - 1px));
}
.curtain.slide .panel-right {
  transform: translateX(calc(100% + 1px));
}

.curtain.slide .panel-up {
  transform: translateY(calc(-100% - 1px));
}

.curtain.slide .panel-down {
  transform: translateY(calc(100% + 1px));
}


      <div class="panel-left"></div>
      <div class="panel-right"></div>
      <div class="panel-up"></div>
      <div class="panel-down"></div>
1 Like

I got up to that. https://jsfiddle.net/1ntbrz93/

Only thing left is to scale.

Here it is with the scale.

.panel-left,
.panel-right,
.panel-up,
.panel-down {
  position: absolute;
  transition: all 8s ease;
  transition-delay: 0s;
  overflow: hidden;
  width: 0;
  height: 0;
}
.panel-up {
  left: -100%;
  right: -100%;
  margin: 0 auto;
  bottom: 50%;
  border-top: 180px solid red;
  border-left: 320px solid transparent;
  border-right: 320px solid transparent;
}
.panel-down {
  left: -100%;
  right: -100%;
  margin: 0 auto;
  top: 50%;
  border-bottom: 180px solid blue;
  border-left: 320px solid transparent;
  border-right: 320px solid transparent;
}
.panel-left {
  top: -100%;
  bottom: -100%;
  right: 50%;
  margin: auto 0;
  border-left: 320px solid green;
  border-top: 180px solid transparent;
  border-bottom: 180px solid transparent;
}
.panel-right {
  top: -100%;
  bottom: -100%;
  left: 50%;
  margin: auto 0;
  border-right: 320px solid yellow;
  border-top: 180px solid transparent;
  border-bottom: 180px solid transparent;
}


/*
.panel-left::before,
.panel-right:before {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 50%;
  right: 0;
  left: auto;
  content: "";
  width: 0px;
  height: 0px;
  border-top: 180px solid red;
  border-bottom: 180px solid blue;
  transform:translateY(-50%);
  pointer-events: none;
}
.panel-left:before {
  border-left: 320px solid green;
}
.panel-right:before {
  left: 0;
  right: auto;
  border-right: 320px solid yellow;
}
*/

/*
.panel-right::before {
  left: -100%;
}
*/
.curtain.slide .panel-left {
  transform: translateX(calc(-100% - 1px));
}
.curtain.slide .panel-right {
  transform: translateX(calc(100% + 1px));
}

.curtain.slide .panel-up {
  transform: translateY(calc(-100% - 1px));
}

.curtain.slide .panel-down {
  transform: translateY(calc(100% + 1px));
}

Back tomorrow now :slight_smile:

2 Likes

If I wanted to add an image instead of a color, how would I do that?

Image being: 640 x 360

  background: url("");
  background-position: 0 0;
  background-size: cover;
  background-repeat: no-repeat;

Here is the code using only a color: https://jsfiddle.net/j10eurz3/

What image and how is it supposed to split?
You cant have the image split in a triangle shape using current methods.

You could split into 4 little squares as they don’t overlap (and there is a demo of that in one of the posts above).

If you want the image to split in 4 triangle shapes then that would take some consideration as you’d need to rotate the element into a diamond while still trying to match up each part of the image.

This one:

If you want the image to split in 4 triangle shapes then that would take some consideration as you’d need to rotate the element into a diamond while still trying to match up each part of the image.

Here is an image:

You can use clip-path and do this:

.panel-up,
.panel-down,
.panel-left,
.panel-right {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  transition: all 8s ease;
  background: url(https://global.discourse-cdn.com/sitepoint/original/3X/3/e/3e5859c04331f0148c64807ff90d49f573f62b20.jpeg) no-repeat;
  background-size: cover;
}

.curtain.slide  .panel-right {
  transform: translateX(100%);
  clip-path: polygon(100% 0%, 50% 50%, 100% 100%);
}
.curtain.slide  .panel-left {
  transform: translateX(-100%);
  clip-path: polygon(0% 100%, 50% 50%, 0% 0%);
}
.curtain.slide  .panel-up {
  transform: translateY(-100%);
  clip-path: polygon(0% 0%, 100% 0%, 50% 50%);
}
.curtain.slide  .panel-down {
  transform: translateY(100%);
  clip-path: polygon(50% 50%, 100% 100%, 0% 100%);
}

Here’s the proof of concept.

2 Likes

Using clip-path and gradients instead of border, how would this one be done? https://jsfiddle.net/j10eurz3/

clip-path and gradient code:
https://jsfiddle.net/vyfabc1g/

box {
  height: 300px;
  max-width: 600px;
  margin: auto;
  background: linear-gradient(red 50%,blue 0);
  position: relative;
  z-index: 0;
}
.box::before {
  content:"";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: linear-gradient(90deg,green 50%,yellow 0);
  clip-path: polygon(0 0,100% 100%,100% 0,0 100%);
}

body {
  background: #000;
}

@PaulOB That’s brilliant!

If you translate each segment by ±50% then you see the slow end of the ‘ease’ timing function.

1 Like

You can’t do it with one element and one pseudo element. You need four elements (or 2 elements if you use the pseudo elements on those). You need 4 separate things because you drag each element in a separate direction.

Although you can make that shape with one element you can;t then break it into 4 and drag each part in a different direction.

You need 4 things.

As it stands you have no single triangles in that demo you have a solid red at the top and a solid green at the bottom which you hide by putting two joined triangles on top. I’ve pulled one element outside so you can see how the effect is created.

You could nearly do it with one simple gradient but it won’t be much use for splitting.

You’d need to clip path the red and blue as well and then apply that to 4 elements as before and then size them so you don’t see the other part much as we have done for other similar things.

The easiest solution is the last one I just gave you so I’m not going to try and implement that method you showed as it has no real bearing on the problem and will just be going over old ground.:slight_smile: