24

Goal:

Responsive CSS circles that:

  1. Scale with equal radius.
  2. Radius can be calculated by percent.
  3. Radius can be controlled by media queries.

If solution is javascript, I still need to emulate media query triggers. I dont 'need' media queries but I do want the ability to control the radius by percentage at certain widths:

@media (max-width : 320px) 
{
    .x2{padding: 50%;}
}

@media (min-width : 321px) and (max-width : 800px)
{
    .x2{padding: 25%;}
}

@media (min-width: 801px)
{
    .x2{padding: 12.5%;}
}

Here is what I have so far:

http://jsfiddle.net/QmPhb/

<div class="x1">
    <div class="x2">
        lol dude      
    </div>
    <div class="x2"></div>
    <div class="x2"></div>
    <div class="x2"></div>
</div>

.x1
{
    float:left;
    width:100%;
}

.x2
{
    display:block;
    float:left;
    padding: 12.5%;          //Currently being used to control radius.
    width:auto;
    height:auto;
    border-radius:50%;
    -moz-border-radius:50%;
    -webkit-border-radius:50%;
    -khtml-border-radius: 50%;
    background:#eee;
    text-align:center;
}

Problems:

In this solution, when content is added to a circle:

  • The shape contorts when scaled past it's available padding.
  • Increases the size of the radius.

Update:

I've built a working solution for this here: Responsive CSS Circles

Community
  • 1
  • 1
Dan Kanze
  • 18,097
  • 28
  • 77
  • 133

4 Answers4

14

You don't need @media queries for this. This is my try, pure CSS:

.x1 {
    overflow:hidden;
}
.x1 .x2 {
    display:block;
    float:left;
    padding: 12.5%;
    width:auto;
    height:auto;
    border-radius:50%;
    -moz-border-radius:50%;
    -webkit-border-radius:50%;
    -khtml-border-radius: 50%;
    background:#eee;
    text-align:center;
    position: relative;
}
.x1 .x2 span {
    position: absolute;
    width: 100%;
    left: 0;
    top: 48%;
    line-height: 1em;
    height: 1em;
    font-size: 100%;
    overflow: hidden;
}​

Fiddle

Full Screen

Praveen Kumar Purushothaman
  • 154,660
  • 22
  • 177
  • 226
  • This certainly addresses the overflow problem. I guess I would expect the Circles to stack @ 25% padding (2 rows) and 50% padding (4 rows) though. Is that possible with this solution? – Dan Kanze Oct 18 '12 at 02:18
  • Yeah, for that to be possible, we need to use media queries then! :) – Praveen Kumar Purushothaman Oct 18 '12 at 02:26
  • Hopefully this gives better context for the kind of flexibility I need. http://jsfiddle.net/tgXKK/ – Dan Kanze Oct 18 '12 at 02:57
  • @DanKanze Nothing gets rendered inside! `:O` Gimme a few mins will finish it soon. `:)` – Praveen Kumar Purushothaman Oct 18 '12 at 03:13
  • I'm curious have you come up with anything yet? – Dan Kanze Oct 18 '12 at 20:52
  • ohhh very cool you should add to that code / link to your post ;) – Dan Kanze Oct 19 '12 at 04:47
  • The un-prefixed CSS should *follow* the vendor-prefixed versions (so the 'final' version is used to override the vendor-prefixed 'draft' versions). Also you left out `o-border-radius` (which is okay since, I think, Opera -as well as Webkit and Mozilla- can just use the regular `border-radius` property). – David says reinstate Monica Oct 21 '12 at 03:45
  • 2
    I made several revisions to this code and minified it the best I could. There were a couple properties I added to allow for more flexibility in child content container elements. See edits above. – Dan Kanze Oct 21 '12 at 04:31
  • You keep getting thumbed up but I dont think they realize I need improvments to the exhisting solution lol... Want to work for the bounty =) ? – Dan Kanze Oct 22 '12 at 18:18
  • @DanKanze Just saw that got those upvotes. Am not well (fever for 3 days), okay, deal... Will work. Gimme time till tomorrow evening (say 20 hours from now) may be? Will get some good solution! – Praveen Kumar Purushothaman Oct 22 '12 at 18:20
  • also chrome seems to hate full width blocks and doesn thide overflow. http://jsfiddle.net/QmPhb/17/ – Dan Kanze Oct 25 '12 at 20:54
  • Actually I tested with Chrome only! – Praveen Kumar Purushothaman Oct 26 '12 at 07:16
  • Chrome doesn't seem to hide overflow. – Dan Kanze Oct 29 '12 at 13:46
  • @DanKanze What's with the bounty? What happened to you? – Praveen Kumar Purushothaman Nov 01 '12 at 04:31
  • 1
    Your solution really only solved half the problem. even though it received a lot of attention does not mean when people try to use this outside the jsfiddle it will actually be portable. I asked you several times to revise your answer to accommodate the bounty and you never modified. – Dan Kanze Nov 01 '12 at 04:41
  • Fine okay. :) No issues. As I said you, I wasn't well. – Praveen Kumar Purushothaman Nov 01 '12 at 04:51
  • The part you solved was very helpful and did overcame a difficult piece. This was the ability to fix content within circle divs without affecting the radius. When this question becomes unlocked we are still looking for a way to solve chrome overflow problem and a way (if possible) to eliminate helper class that encapsulates circle divs. – Dan Kanze Nov 01 '12 at 05:30
  • Why was it **locked** at the first place? Sorry, I was not active for a few days and saw that the question had issues this way. That's why asking you. You lost your **50** bounty points na!!! I was concerned with that issue! – Praveen Kumar Purushothaman Nov 01 '12 at 06:53
7

Shorter Code

This solution reduces your code size but keeps the functionality in place. I've kept the original .x#, eliminating the .x0, .x3, and .x6 that were not needed. So in a final solution, you would probably renumber (but I wanted you to see what was eliminated).

Any of your pieces "splitting" the circle that require a different top or left setting will need to have a selector that meets or exceeds the .x2 > div selector to override, hence why I have .x2 > .x7 etc. for some of my selectors.

(As noted in the comments below, Chrome has bug issues with the original technique the OP had posted at the time of the bounty starting. This does not solve those, so view the following in another browser.)

Here's the modified fiddle.

HTML

<div class="x1">
        <div class="x2">
                <!-- BEG Content -->
                <div class="x4">
                    dude
                </div>
                <div class="x7">
                    dude
                </div>
                <div class="x8">
                    dude
                </div>
                <div class="x5">
                    dude
                </div>
                <!-- END Content -->
        </div>
        <div class="x2"></div>
        <div class="x2"></div>
        <div class="x2"></div>
    </div>

CSS

.x1 {
    margin:0px auto;
}
.x2 {
    overflow:hidden;
    display:block;
    float:left;
    width:auto;
    height:auto;
    position: relative;
    border-radius:50%;
    -moz-border-radius:50%;
    -webkit-border-radius:50%;
    -khtml-border-radius: 50%;
    background:#eee;
}

/* BEG Content */
.x2 > div {
    position: absolute;
    text-align: center;
    top: 0;
    left: 0;
}
.x4,.x5 {
    width:100%;
    height: 20%;
}
.x2 > .x7, .x2 > .x8 {
    width:50%;
    height: 60%;
    top: 20%;
}
.x4 {
    background-color:blue;
}
.x2 > .x5 {
    background-color:yellow;
    top: 80%;
}

.x7 {
    background-color:green;
}
.x2 > .x8 {
    background-color:orange;
    left: 50%;
}
/* END Content */
@media (max-width: 320px)
{
    .x2 {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .x2 {padding: 25%;}
}

@media (min-width: 801px)
{
    .x1 {width:800px}
    .x2 {padding: 12.5%;}
}

EDIT: Based on comments, it appears the OP desired something more like the control this fiddle offers (not functional in Chrome; the OP has not at the time of this edit replied for me to know if that is the type of functionality desired or not).

Community
  • 1
  • 1
ScottS
  • 68,932
  • 12
  • 117
  • 139
  • Ahh yea I didnt say that correctly. `.x2` divs are stacking fine. You have also eliminated `.x3`...which is great. What I meant is that using overrides to apply styles in `.x2` child elements is undesirable. – Dan Kanze Oct 23 '12 at 20:17
  • @DanKanze--how much flexibility versus standardization do you want in the "layouts" inside these circles? Are they all the same? Each one different? Your goal is "improved" and "smaller". Well, I got the code smaller, but what is "improved"? That depends a lot on what functionality you want. – ScottS Oct 23 '12 at 23:27
  • From a developer point of view an **ideal** solution would be one that easy to build (rolling out styles inside of `.x2` blocks without overrides) and optimizes arbitrary code (trim fat like `.x3` only used as a helper class to accomadate the build flexibility in `.x2`). An **ideal** solution would be a single class that enabled a developer too use `.x2` like a `block` as well as contain them. – Dan Kanze Oct 23 '12 at 23:55
  • @DanKanze--have you looked at your original fiddle solution in Chrome? It fails to hide the overflow because of the bug noted in [this question](http://stackoverflow.com/questions/5736503/how-to-make-css3-rounded-corners-hide-overflow-in-chrome-opera). – ScottS Oct 24 '12 at 02:49
  • @DanKanze--[Here is a fiddle](http://jsfiddle.net/WTWrB/23/) (look at in Firefox or IE9+, see comment above) that controls things by a `layout` class on the content wrapper. Is that more what you are talking about? It is certainly not necessarily "smaller" in size, but the layout class can be coded by the developer and the class applied by the user. – ScottS Oct 24 '12 at 02:55
5

Solution:

http://jsfiddle.net/WTWrB/

The DIV structure:

We use overflow:hidden in .x2 for spill off background colors in .x3 of child elements.

Notice the content starts inside of .x3

<div class="x0">
    <div class="x1">
        <div class="x2">
            <div class="x3">
                <!-- BEG Content -->
                <div class="x4">
                    dude
                </div>
                <div class="x6">
                    <div class="x7">
                        dude
                    </div>
                    <div class="x8">
                        dude
                    </div>
                </div>                
                <div class="x5">
                    dude
                </div>
                <!-- END Content -->
            </div>
        </div>
        <div class="x2"></div>
        <div class="x2"></div>
        <div class="x2"></div>
    </div>
</div>

The CSS:

@media (max-width: 320px)
{
    .x2 {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .x2 {padding: 25%;}
}

@media (min-width: 801px)
{
    .x1 {width:800px}
    .x2 {padding: 12.5%;}
}
.x0 {
    float:left;
    width:100%;
}
.x1 {
    margin:0px auto;
}
.x2 {
    overflow:hidden;
    display:block;
    float:left;
    width:auto;
    height:auto;
    position: relative;
    border-radius:50%;
    -moz-border-radius:50%;
    -webkit-border-radius:50%;
    -khtml-border-radius: 50%;
    background:#eee;
}
.x3 {
    position: absolute;
    width: 100%;
    left: 0;
    top:0;
    font-size: 100%;
    float:left;
    height:100%;
    background-color:red;
}
/* BEG Content */
.x3 div{float:left;}
.x4,.x5,.x6 {
    width:100%;
}
.x7,.x8 {
    width:50%;
    float:left;
    height:100%;
}
.x4,.x5,.x7,.x8 {
    text-align:center;
}
.x4 {
    background-color:blue;
    height:20%;
}
.x5 {
    background-color:yellow;
    height:20%;
}
.x6 {
    height:60%;
}
.x7 {
    background-color:green;
}
.x8 {
    background-color:orange;
}
/* END Content */

Responsive CSS Circles

Dan Kanze
  • 18,097
  • 28
  • 77
  • 133
0

I know this solution differs quite a bit from what has been suggested here but I still thought it would be worth putting it up.

I used an image as a mask to create the circle and took advantage of the fact that when padding is specified as a percentage it is calculated based on the width of its parent element rather than the height. This enabled me to create a perfect square.

Demonstration of circles proportionally resizing here

HTML code

<div class="container">
    <img class="circle" src="circleImage.png">
</div>

CSS code

.container {
    position: relative;
    float: left;
    width: 50%;
    height: 0;
    padding-bottom: 50%;
    background-color: #bbb;

}

.circle { 
    position: absolute;
    width: 100%;
    left: 0;
    top: 0;
    height: auto;
    z-index: 1;
}

@media (max-width: 320px) {
    .container { width: 100%; padding-bottom: 100%; }
}

@media (min-width: 321px) and (max-width: 800px) {
    .container { width: 50%; padding-bottom: 50%; }
}

@media (min-width: 801px) {
    .container { width: 25%; padding-bottom: 25%; }
}

Demonstration of the above circles sub-divided into sections as per your question here

Bruno
  • 5,504
  • 1
  • 22
  • 39