Creating a 3 circle Venn diagram with pure css/html

后端 未结 5 1862
猫巷女王i
猫巷女王i 2020-12-14 22:36

Maybe there\'s not a way, but I\'m looking to create 3 circles that would appear to overlap, yet would be actually individual objects with pure css. I can easily create a c

相关标签:
5条回答
  • 2020-12-14 22:49

    Making the shapes really concaves in CSS is really hard, in this case your best bet would be SVG.

    But, if you want a pure CSS solution, may be you don't need really those shapes. If you set your z-index ok, then you can get your topmost div to hide the others, and then you don't care about the concave side ...

    In this demo, the hover works ok. It would be the same for other events.

    div {
      width: 240px;
      height: 240px;
      position: absolute;
      border-radius: 50%;
    }
    
    .innerw {
      left: 0px;
      top: 0px;
      overflow: hidden;
    }
    
    .innerw2 {
      left: 170px;
      top: 0px;
      overflow: hidden;
    }
    
    .inner {
      left: -85px;
      top: 130px;
      background-color: palegreen;
      z-index: 20;
    }
    
    .inner:hover {
      background-color: green;
    }
    
    #midw1 {
      left: 0px;
      top: 0px;
      overflow: hidden;
    }
    #mid1 {
      left: 170px;
      top: 0px;
    }
    #midw2 {
      left: 0px;
      top: 0px;
      overflow: hidden;
    }
    #mid2 {
      left: 85px;
      top: 130px;
    }
    #midw3 {
      left: 170px;
      top: 0px;
      overflow: hidden;
    }
    #mid3 {
      left: -85px;
      top: 130px;
    }
    .mid {
      background-color: lightblue;
      z-index: 15;
    }
    .mid:hover {
      background-color: blue;
    }
    
    
    #outer1 {
      left: 0px;
      top: 0px;
    }
    
    #outer2 {
      left: 170px;
      top: 0px;
    }
    #outer3 {
      left: 85px;
      top: 130px;
    }
    .outer {
      background-color: lightcoral;
      z-index: 10;
    }
    .outer:hover {
      background-color: red;
    }
    <div id="outer1" class="outer">
    </div>
    <div id="outer2" class="outer">
    </div>
    <div id="outer3" class="outer">
    </div>
    <div id="midw1">
    <div id="mid1" class="mid"></div>
    </div>
    <div id="midw2">
    <div id="mid2" class="mid"></div>
    </div>
    <div id="midw3">
    <div id="mid3" class="mid"></div>
    </div>
    <div class="innerw">
    <div class="innerw2">
    <div class="inner">
    </div>
    </div>
    </div>

    A more complex layout, bug-free in Chrome and IE

    div {
      width: 240px;
      height: 240px;
      border-radius: 50%;
      pointer-events: none;
      position: absolute;
    }
    
    .innerw {
      left: 0px;
      top: 0px;
      overflow: hidden;
      position: absolute;
      /* border: solid; */
      z-index: 20;
      /* transform: translateZ(10px); */
      pointer-events: none;
    }
    
    .innerw2 {
      margin-left: 0px;
      top: 0px;
      overflow: hidden;
      position: static;
      /* border: solid; */
      /* z-index: 20; */
      pointer-events: none;
    }
    
    .innerw3 {
      margin-left: 170px;
      top: 0px;
      overflow: hidden;
      position: static;
      /* border: solid; */
      /* z-index: 20; */
      pointer-events: none;
    }
    
    .inner {
      margin-left: -85px;
      margin-top: 130px;
      background-color: palegreen;
      z-index: 20;
      position: static;
      pointer-events: auto;
    }
    
    .inner:hover {
      background-color: green;
    }
    
    .mwrap {
      position: absolute;
      overflow: hidden;
      pointer-events: none;
      z-index: 10;
    }
    .mwrap2 {
      position: static;
      margin-left: 0px;
      margin-top: 0px;
      overflow: hidden;
      pointer-events: none;
    }
    .mid {
      position: static;
      pointer-events: auto;
    }
    #midaw1 {
      left: 0px;
      top: 0px;
    }
    #mida {
      margin-left: 170px;
      margin-top: 0px;
    }
    #midbw1 {
      left: 170px;
      top: 0px;
    }
    #midb {
      margin-left: -85px;
      margin-top: 130px;
    }
    #midcw1 {
      left: 85px;
      top: 130px;
    }
    #midc {
      margin-left: -85px;
      margin-top: -130px;
    }
    .mid {
      background-color: lightblue;
      z-index: 15;
    }
    .mid:hover {
      background-color: blue;
    }
    
    
    #outer1 {
      left: 0px;
      top: 0px;
    }
    
    #outer2 {
      left: 170px;
      top: 0px;
    }
    #outer3 {
      left: 85px;
      top: 130px;
    }
    .outer {
      background-color: lightcoral;
      z-index: 1;
      pointer-events: auto;
    }
    .outer:hover {
      background-color: red;
    }
    <div id="outer1" class="outer">
    </div>
    <div id="outer2" class="outer">
    </div>
    <div id="outer3" class="outer">
    </div>
    <div id="midaw1" class="mwrap">
    <div id="midaw2" class="mwrap2">
    <div id="mida" class="content mid"></div>
    </div>
    </div>
    <div id="midbw1" class="mwrap">
    <div id="midbw2" class="mwrap2">
    <div id="midb" class="content mid"></div>
    </div>
    </div>
    <div id="midcw1" class="mwrap">
    <div id="midcw2" class="mwrap2">
    <div id="midc" class="content mid"></div>
    </div>
    </div>
    <div class="innerw">
    <div class="innerw2">
    <div class="innerw3">
    <div class="inner">
    </div>
    </div>
    </div>
    </div>

    Thanks to theleggett for his help on this

    0 讨论(0)
  • 2020-12-14 22:53

    I have SVG solution for your question:

    DEMO: http://jsfiddle.net/kboksc04/

    The code recreates the circles and intersections with polygons.

    var r = 200,              // radius of the circles
    
    // colors of the circles
    // you can create functions for colors or load them from array etc.
        colors = {            
            a: "#ADD8E6",     
            b: "#FFFACD",     
            c: "#FA8072",
            ab: "#008000",
            bc: "#FF0000",
            ca: "#0000FF",
            abc: "#000000"
        };
    
    // the body of the picture
    var board = d3.select("body").append("svg:svg").attr({
        width: 3 * r,
        height: 3 * r
    });
    
    // function creates array of x,y pairs for dots
    // uses parametric function of circle
    // @param {float} x_0, y_0 - center of the circle
    // @param {float} r - radius
    // @param {integer} n - number of sections  
    // @returns {Array} - array of coordinates for "n" dots of polygon
    function dots(x_0, y_0, r, n) {
        var a = [],
            d_alpha = 2 * Math.PI / n;
        for (var alpha = 0; alpha < 2 * Math.PI; alpha += d_alpha) {
            a.push([
            x_0 + r * Math.cos(alpha),
            y_0 + r * Math.sin(alpha)]);
        }
        return (a);
    }
    
    // the coordinates for points of three basic circles
    var shape_a = d3.geom.polygon(dots(r, r, r, 80));
    var shape_b = d3.geom.polygon(dots(2 * r, r, r, 80));
    var shape_c = d3.geom.polygon(dots(1.5 * r, 2 * r, r, 80));
    
    // intersections of circles in pairs
    var shape_a_x_b = shape_a.slice();
    shape_b.reverse().clip(shape_a_x_b);
    
    var shape_b_x_c = shape_c.slice();
    shape_b.clip(shape_b_x_c);
    
    var shape_c_x_a = shape_c.slice();
    shape_a.reverse().clip(shape_c_x_a);
    
    // central intersection for all the circles
    // actually it is intersection of pair previous calculated intersections
    var shape_abc = shape_c_x_a.slice();
    d3.geom.polygon(shape_b_x_c.reverse()).clip(shape_abc);
    
    // drawing
    board.append("svg:polygon")
        .attr({
        points: shape_a,
        fill: colors.a
    });
    board.append("svg:polygon")
        .attr({
        points: shape_b,
        fill: colors.b
    });
    board.append("svg:polygon")
        .attr({
        points: shape_c,
        fill: colors.c
    });
    board.append("svg:polygon")
        .attr({
        points: shape_a_x_b,
        fill: colors.ab
    });
    board.append("svg:polygon")
        .attr({
        points: shape_b_x_c,
        fill: colors.bc
    });
    board.append("svg:polygon")
        .attr({
        points: shape_c_x_a,
        fill: colors.ca
    });
    board.append("svg:polygon")
        .attr({
        points: shape_abc,
        fill: colors.abc
    });
    

    Finally, there you can see a version with clickable-responsible pieces:

    http://jsfiddle.net/kboksc04/2/

    You can click on a green or black pieces.

    0 讨论(0)
  • 2020-12-14 22:58

    The best tool to use is SVG. Vals answer with CSS is great! but its not working in my GC.

    With SVG, you can use path elements with arcs. EG, my shape is divided into 7 arc paths.

    svg {
      overflow: visible;
    }
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="40%" width="40%" viewBox="0 0 100 100" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <style type="text/css">
          path {
            fill: transparent;
            stroke: red;
            stroke-width: 0.5;
          }
          path:hover {
            fill: red;
          }
        </style>
      </defs>
      <path d="M 50 8 A 30 30 0 1 0 21 59 30 30 0 0 1 41 36 30 30 0 0 1 50 8" />
      <path d="M 50 8 A 30 30 0 0 0 41 36 30 30 0 0 1 59 36 30 30 0 0 0 50 8" />
      <path d="M 50 8 A 30 30 0 1 1 79 59 30 30 0 0 0 59 36 30 30 0 0 0 50 8" />
      <path d="M 50 52 A 30 30 0 0 1 21 59 30 30 0 0 1 41 36 30 30 0 0 0 50 52" />
      <path d="M 50 52 A 30 30 0 0 1 41 36 30 30 0 0 1 59 36 30 30 0 0 1 50 52" />
      <path d="M 50 52 A 30 30 0 0 0 79 59 30 30 0 0 0 59 36 30 30 0 0 1 50 52" />
      <path d="M 21 59 A 30 30 0 1 0 79 59 30 30 0 0 1 50 52 30 30 0 0 1 21 59" />
    </svg>

    If you want image inside separate arc shapes (for some reason. don't ask)

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="40%" width="40%" viewBox="0 0 100 100" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <style type="text/css">
          path {
            fill: transparent;
            stroke: red;
            stroke-width: 0.5;
          }
          path:hover {
            fill: url(#img);
          }
        </style>
        <pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
          <image xlink:href="http://www.placecage.com/g/200/300" x="0" y="-25" width="100" height="200" />
        </pattern>
      </defs>
      <path d="M 50 8 A 30 30 0 1 0 21 59 30 30 0 0 1 41 36 30 30 0 0 1 50 8" />
      <path d="M 50 8 A 30 30 0 0 0 41 36 30 30 0 0 1 59 36 30 30 0 0 0 50 8" />
      <path d="M 50 8 A 30 30 0 1 1 79 59 30 30 0 0 0 59 36 30 30 0 0 0 50 8" />
      <path d="M 50 52 A 30 30 0 0 1 21 59 30 30 0 0 1 41 36 30 30 0 0 0 50 52" />
      <path d="M 50 52 A 30 30 0 0 1 41 36 30 30 0 0 1 59 36 30 30 0 0 1 50 52" />
      <path d="M 50 52 A 30 30 0 0 0 79 59 30 30 0 0 0 59 36 30 30 0 0 1 50 52" />
      <path d="M 21 59 A 30 30 0 1 0 79 59 30 30 0 0 1 50 52 30 30 0 0 1 21 59" />
    </svg>

    0 讨论(0)
  • 2020-12-14 22:58

    DEMO: http://jsfiddle.net/u5e5mhgx/

    I believe the final mix is depends of the color and transparence of the circles, like:

    background-color: rgba(0, 0, 255, 0.4);
    
    0 讨论(0)
  • 2020-12-14 23:04

    Using the border-radius property, you can create pure css Venn diagram like this:

    Here's my pen http://jsfiddle.net/sLzUG/195/

     .circle{
        position:absolute;
        width:150px;
        height: 150px;
    
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
        filter: alpha(opacity=30);
        -moz-opacity: 0.3;
        -khtml-opacity: 0.3;
        opacity:0.3;
        -webkit-border-radius: 50%;
        -moz-border-radius: 50%;
        border-radius: 50%;
        border: 2px solid black;
    }
    
    
    #second{position:relative; left:92px; top:4px;
     background: yellow;
    
    }
    
    #first {
        background: blue;
    }
    
    
    
    
    #third {
        position: relative; 
        top: -70px;
        left: 40px;
        background: red;
    }
    
    #problem{
        font-size: 8pt;
        color:white;
        position: absolute;
        width: 75px;
        height: 75px;
        border-left:2px solid red;
        border-top:2px solid red;
        top : 41px;
        left:71px;
        z-index:-4;
        background:red;
    }
    #problem:after{
        position:absolute;
        content:" ";
        background:white;
        width:150px;
        height:150px;
        top:-2px;
        left: -2px;
        -webkit-border-radius: 50%;
        -moz-border-radius: 50%;
        border-radius: 50%;
        z-index:-3;
    }
    
    
    
    <div id="first" class="circle"></div>
    <div id="second" class="circle"></div>
    <div id="third" class="circle"></div>
    
    0 讨论(0)
提交回复
热议问题