Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to make the smallest possible nested circles with css

Im working on a Vue component, where the user can add circles in to other circles, with support for unlimited levels of nesting, but im having some problems with the CSS.

Here is a simplified version of the problem:

Im trying to achieve something like this.goal of the html and css

I thought flexbox would be a great choice for that job, but cant make it work how i want it to, it always ends up way too big and not breaking up into separate lines or breaking out of the circles.

I have tried this approach, im open for a new structure if there is an easer way to do this. As long as the circle have a title and content, thought about using before and after for the title and content to simplify the structure, but haven't explored that option yet.

document.querySelectorAll(".circle").forEach( el => el.style.height = window.getComputedStyle(el).width);
* {
  margin: 0;
  padding: 0;
}
.flex {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;

  flex-flow: row wrap;
  justify-content: space-around;
}
.circle {
  border-radius: 50%;
  padding: 40px;
  box-shadow: 7px 7px 5px 0px rgba(50, 50, 50, 0.75);
}
.head {
  color: #fff;
  text-align: center;
  margin-bottom: 10px;
  height: 20px;
}
.body {
  align-items: center;
}
.red {
  background-color: rgba(255, 17, 0, 0.76);
}
.blue {
  background-color: rgba(8, 0, 255, 0.76);
}
.green {
  background-color: rgba(0, 157, 11, 0.76);
}
<div id="circle_test">
    <div id="master" class="red circle flex">
    
        <div class="head">
            Parent
        </div>
        <div class="body flex">
            <div class="blue circle">
                <div class="head">
                    child-0
                </div>
                <div class="body flex">
                    <div class="green circle">
                        <div class="head">sub-child-0</div>
                        <div class="body">content here</div>
                    </div>
                    <div class="green circle">
                        <div class="head">sub-child-1</div>
                        <div class="body">content here</div>
                    </div>
                    <div class="green circle">
                        <div class="head">sub-child-2</div>
                        <div class="body">content here</div>
                    </div>
                </div>
            </div>
            <div class="blue circle">
                <div class="head">
                    child-1
                </div>
                <div class="body flex">
                    <div class="green circle">
                        <div class="head flex">sub-child-0</div>
                        <div class="body">content here</div>
                    </div>
                </div>
            </div>
        </div>

    </div>
</div>

or as a jsfiddle.net link

Any inputs are appreciated, thanks :)

like image 825
keja Avatar asked Jan 17 '18 14:01

keja


People also ask

How do you make a small circle in CSS?

To create a circle we can set the border-radius on the element. This will create curved corners on the element. If we set it to 50% it will create a circle. If you set a different width and height we will get an oval instead.

How do I make a circle div in CSS?

The method that we used in the example above is the simplest one and has good browser support. Now, let's see an example, where we use <span> elements within a <div>. Here, we also specify the display as “inline-block” and add the text-align property set to “center” to the <div> to align the circles to the center.


1 Answers

I think you could achieve something visually similar with d3.js:

var svg = d3.select("svg"),
  diameter = +svg.attr("width"),
  g = svg.append("g").attr("transform", "translate(2,2)"),
  format = d3.format(",d");

  var pack = d3.pack()
  .size([diameter - 4, diameter - 4]);

  var circles = '{ "name": "Parent", "children": [ { "name": "child-0", "children": [ {"name": "sub-child-0", "size": 100}, {"name": "sub-child-1", "size": 100}, {"name": "sub-child-2", "size": 100} ] }, { "name": "child-1", "children": [ {"name": "sub-child-0", "size": 100} ] } ]}';

  var circlesParse = JSON.parse(circles);

  circlesParse = d3.hierarchy(circlesParse)
  .sum(function(d) { return d.size; })
  .sort(function(a, b) { return b.value - a.value; });

  var node = g.selectAll(".node")
  .data(pack(circlesParse).descendants())
  .enter().append("g")
  .attr("class", function(d) { return d.children ? "node" : "leaf node"; })
  .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

  node.append("title")
  .text(function(d) { return d.data.name + "\n" + format(d.value); });

  node.append("circle")
  .attr("r", function(d) { return d.r; });

  node.filter(function(d) { return !d.children; }).append("text")
  .attr("dy", "0.3em")
  .text(function(d) { return d.data.name.substring(0, d.r / 3); });
circle {
    fill: rgb(31, 119, 180);
    fill-opacity: .25;
    stroke: rgb(31, 119, 180);
    stroke-width: 1px;
  }

  .leaf circle {
    fill: #ff7f0e;
    fill-opacity: 1;
  }

  text {
    font: 10px sans-serif;
    text-anchor: middle;
  }
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="250" height="250"></svg>

Inspired by https://bl.ocks.org/mbostock/4063530

like image 182
Valentin Avatar answered Oct 12 '22 23:10

Valentin