One of the easiest – non SVG – ways to achieve this is as below, with explanatory comments in the code:
.collage {
/* using grid layout means we can easily
position the elements in the same place
without nesting them: */
display: grid;
/* effectively the same as:
justify-content: center;
align-contents: center;
to place the items in the center along
the block and inline axes: */
place-items: center;
}
.triangle {
/* allows us to set the aspect-ratio, which causes
the browser to compute one axis of the element
based on the value we specify for 'other' axis;
here we specify a height of 300px, so the browser
calculates the other axis to 600px, making the
triangle-shape twice as wide as its height: */
aspect-ratio: 2 / 1;
background-color: #000;
/* using clip-path, with the CSS polygon() function,
to specify a list of coordinates outside of which
the element is clipped, instead of using the
border hack to create a triangle: */
clip-path: polygon(50% 0, 100% 100%, 0 100%);
/* positions the element in the first grid-row
and first grid-column: */
grid-area: 1 / 1;
height: 300px;
z-index: 1;
}
.circle {
/* a shorthand for an aspect-ratio of: 1 / 1,
which causes the browser to calculate the
unknown axis to be same length as the
specified axis (again, the height): */
aspect-ratio: 1;
background-color: #00f;
border-radius: 50%;
grid-area: 1 / 1;
height: 210px;
/* to place the element higher in the visual
stack, 'closer' to the viewer: */
z-index: 10;
}
<div class="collage">
<div class="triangle"></div>
<div class="circle"></div>
</div>
JS Fiddle demo.
Of course, if you're prepared to use SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" xml:space="preserve">
<!-- this element is the background upon which
the triangle and circle appear: -->
<rect id="background"
<!-- we fill the shape with black, the 'fill'
being the 'background-color' -->
style="fill: #fff;"
<!-- these attributes determine the placement of
the element, the x and y coordinates
of the upper-left corner: -->
x="-300" y="-300"
<!-- determines the width and height: -->
width="600" height="600"
<!-- moves the element across the SVG, in the
x and y axes: -->
transform="translate(300 300)" />
<path id="triangle"
style="fill: #000;"
<!-- this is the path of the triangle, the enclosed
space being the filled portion: -->
d="M-37.43 32.41 0-32.41l37.43 64.82z"
transform="matrix(7.36 0 0 4.99 300 300)" />
<circle id="circle"
style="fill: #00f;"
<!-- we specify the radius of the <circle>: -->
r="35"
<!-- and move it within the SVG for positioning: -->
transform="matrix(3.01 0 0 3.01 300 300)" />
</svg>
JS Fiddle demo.
SVG is a little complex to explain, so unfortunately I've largely abdicated from that responsibility and left a link – in the bibliography below – from which you (and others) can learn more about it.
It's also worth stating that my own knowledge of SVG is limited, and I tend to use a program to create them, such as InkScape (other programs are, of course, available) or an online generator, as I did here.
References:
Bibliography: