Center triangle at bottom of div full width respon

2020-07-18 02:52发布

问题:

After hours of trying in CSS (sorry, I'm still a CSS noob) I am asking you for help:
I want a triangle to be the "bottom" of a div while filling the whole screen width, no matter what size the screen is (100%).
When the window resizes I just want the triangle to change it's width so that it still fills the whole screen width (100%) but not it's height.
At the moment the whole thing looks like this (triangle colored black only for demonstration purposes) which judging by the looks is what I want to achieve:

My code looks like this:

.top {
  background-color: green;
  height: 100px;
  width: 100%;
}
.bottom {
  background-color: red;
  height: 200px;
  width: 100%;
}
.triangle {
  border-top: 40px solid black;
  border-left: 950px solid transparent;
  border-right: 950px solid transparent;
  width: 0;
  height: 0;
  top: 107px;
  content: "";
  display: block;
  position: absolute;
  overflow: hidden;
  left: 0;
  right: 0;
  margin: auto;
}
<div class="top">
  <div class="triangle"></div>
</div>
<div class="bottom"></div>

Code on JSFiddle: http://jsfiddle.net/L8372wcs/

My problems:

  • I can't figure out how to make the triangle take 100% of the screen size (I'm using a width in pixels at the moment).
  • I can't figure out how to make the triangle stick to the exact bottom of the div (here I'm also using a pixel value at the moment).
  • I can neither figure out how to resize the triangle responsively nor how to maintain it's height while doing so (I tried serveral tutorials).

Thanks a lot in advance for the help.

回答1:

See http://jsfiddle.net/L8372wcs/1/


CSS (Relevant changes)

.top {
    ...
    position: relative;
}

.triangle {

    border-top: 40px solid black;
    border-left: 50vw solid transparent;
    border-right: 50vw solid transparent;
    ...
    bottom: -40px;
}
  1. The left and right borders are defined with viewport units (since your div is 100% wide). The triangle is responsive (try to resize the viewport)

  2. The triangle position is defined with bottom: -40px; (instead of top) and its parent has position: relative; This will ensure that the triangle will be positioned always just below the green element (until the top border of the triangle is 40px tall)


Result



回答2:

Another approach would be to use an inline svg with the polygon element.

This way, it's width can be set to 100% and it's height can be controled independently with CSS thx to the preserveAspectRatio svg attribute.

In the following example, the height of the triangle is fixed to 40px but you can make the height rezise according the width by removing the CSS height property and the preserveAspectRatio attribute.

.top {
    position:relative;
    background-color: green;
    height: 100px;
    width: 100%;
}
.bottom {
    background-color: red;
    height: 200px;
    width: 100%;
}
.triangle {
    position:absolute;
    top:100%;
    width:100%;
    height:40px;
}
<div class="top">
    <svg viewbox="0 0 100 10" preserveAspectRatio="none" class="triangle" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <polygon points="0 0 100 0 50 10"/>
    </svg>
</div>
<div class="bottom"></div>

You can also style the triangle (fill colors, border, opacity...) as derired either with CSS or with attributes in the SVG element. Here is an example with CSS :

.top {
  position: relative;
  background-color: green;
  height: 100px;
  width: 100%;
}
.bottom {
  background-color: red;
  height: 200px;
  width: 100%;
}
.triangle {
  position: absolute;
  top: 100%;
  width: 100%;
  height: 40px;
  fill: gold;
}
<div class="top">
  <svg class="triangle" viewbox="0 0 100 10" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <polygon points="0 0 100 0 50 10" />
  </svg>
</div>
<div class="bottom"></div>



回答3:

You can use vw unit (viewport width).

Working example.



回答4:

I can't figure out how to make the triangle take 100% of the screen size (I'm using a width in pixels at the moment).

This can be done by using vw as the units for the borders creating the triangle. As the body has a margin (8px in Chrome) use calc(50vw - 8px) to accommodate for it.

I can't figure out how to make the triangle stick to the exact bottom of the div (here I'm also using a pixel value at the moment).

Position .triangle relative to .top by adding position: relative; to .top then add top: 100% to .triangle to always place it at the bottom of .top.

I can neither figure out how to resize the triangle responsively nor how to maintain it's height while doing so (I tried serveral tutorials).

The vw unit will make the triangle responsive.

.top {
  background-color: green;
  height: 100px;
  position: relative;
  width: 100%;
}
.bottom {
  background-color: red;
  height: 200px;
  width: 100%;
}
.triangle {
  border-left: calc(50vw - 8px) solid transparent;
  border-right: calc(50vw - 8px) solid transparent;
  border-top: 40px solid black;
  content: "";
  display: block;
  height: 0;
  left: 0;
  margin: auto;
  overflow: hidden;
  position: absolute;
  right: 0;
  top: 100%;
  width: 0;
}
<div class="top">
  <div class="triangle"></div>
</div>
<div class="bottom"></div>



回答5:

Triangle can also be created with linear-gradient:

.top {
  background-color: green;
  height: 100px;
  position: relative;
}
.triangle {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 40px;
  background:
    linear-gradient(to bottom left, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 50%) no-repeat left top / 50% 100%,
    linear-gradient(to bottom right, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 50%) no-repeat right top / 50% 100%;
}
.bottom {
  background-color: red;
  height: 200px;
}
<div class="top">
  <div class="triangle"></div>
</div>
<div class="bottom"></div>

Chrome does not produce smooth results but expect this to be fixed in the future.



回答6:

Does this fit?

*{
    padding: 0;
    margin: 0;
}
.top {
    background-color: green;
    height: 100px;
    width: 100%;
    position: relative;
}
.bottom {
    background-color: red;
    height: 200px;
    width: 100%;
}
.triangle {
    box-sizing: border-box;
    width: 0; 
    height: 0; 
    border-left: 50vw solid transparent;
    border-right: 50vw solid transparent;
    position: absolute;
    top: 100px;
    border-top: 30px solid black;
}