How to put items in a Circle in CSS LESS

Through the depths of the internet I have search and found a method to put items on a circle using a CSS preprocessor. However it was in SCSS and I work in LESS, by which I mean the preprocessor not just less things. So I have converted it over to the dark side of LESS and broken down how it works below, I hope this helps.

Let’s start off with the SCSS version of items on a circle by Hugo Giraudel from his site.

/// Mixin to put items on a circle
/// [1] - Allows children to be absolutely positioned
/// [2] - Allows the mixin to be used on a list
/// [3] - In case box-sizing: border-box has been enabled
/// [4] - Allows any type of direct children to be targeted
///
/// @param {Integer} $nb-items - Number or items
/// @param {Length} $circle-size - Container size
/// @param {Length} $item-size - Item size
/// @param {String | false} $class-for-IE - Base class name for old IE
@mixin distribute-on-circle(
$nb-items,
$circle-size,
$item-size,
$class-for-IE: false
) {

$half-item: ($item-size / 2);
$half-parent: ($circle-size / 2);

position: relative; /* 1 */
width: $circle-size;
height: $circle-size;
padding: 0;
border-radius: 50%;
list-style: none; /* 2 */
box-sizing: content-box; /* 3 */

> * { /* 4 */

display: block;
position: absolute;
top: 50%;
left: 50%;
width: $item-size;
height: $item-size;
margin: -$half-item;

}

$angle: (360 / $nb-items);
$rot: 0;

@for $i from 1 through $nb-items {

@if not $class-for-IE {
> :nth-of-type(#{$i}) {
transform: rotate($rot * 1deg) translate($half-parent) rotate($rot * -1deg);
}
} @else {
> .#{$class-for-IE}#{$i} {
// If CSS transforms are not supported
$mt: sin($rot * pi() / 180) * $half-parent - $half-item;
$ml: cos($rot * pi() / 180) * $half-parent - $half-item;
margin: $mt 0 0 $ml;
}

}

$rot: ($rot + $angle);
}

}

So now you have seen the SCSS, let’s go to the LESS CSS.

First lets build the method you will be calling in the CSS, which like most of this we will just be copying the SCSS. Instead of putting an action call before the method name like in SCSS (@mixin), we call it like a class in standard CSS. In LESS we also identify variables with ‘@’ instead of the ‘$’. This means the above method of calling a method turns into the below.

.on-circle(@item-count, @circle-size, @item-size) {

}

There are then some manadatory styles that we need for the container to work. At this point though you could also add in some of your own custom style for the container as well. When we call the method we will be putting it in the containers class. We also use the variable ‘circle-size’ for the width and height. For this I used the Unit function for LESS, so it could be swapped out to be in percentage, em, rem or anything else. Rembering to use the ‘@’ to call the variable and not the ‘$’.

.on-circle(@item-count, @circle-size, @item-size) {

position: relative;
width: unit(@circle-size, px);
height: unit(@circle-size, px);
padding: 0;
margin:auto;
border-radius: 50%;

}

Within the method we now call upon the children, but to make sure we only affect the children of the container and nothing further down we got the direct child symbol added in (‘>’). Also because you could be using div’s, span’s or li elements as the children, it using the any type of element selector (‘*’).

A method to centre items up, which we have used here, is to set the width and height 50%, then move the item back half of its size. We get the children’s item size sent in the method to use for this, plus we got the Unit function used in case your making this responsive.

> * {

display: block;
position: absolute;
top: 50%;
left: 50%;
width: unit(@item-size, px);
height: unit(@item-size, px);
margin: unit(-(@item-size / 2), px);

}

Next is the loop for each child and it gets a bit different here for the conversion so ill break it down a bit more. The loop in SCSS looks more like a general loop you would see in JavaScript or some other languages, but the way to do in LESS is to call it like a method with an exception on the side. You can see from the example below I have called the method ‘cl’ for ‘children loop’, passed in two variables and then put a when clause on the side. This will then run while ‘i’ is greater than zero.

.cl(@i,@r) when (@i > 0) {

}

However this will be an infinite loop at the moment as ‘i’ never changes and if we just change ‘i’ in the loop then the ‘when’ clause won’t know about it. What we can do is call the loop method again inside, but of course minus 1.

Our ‘i’ variable is going to be our item count as we want to loop through each of the items. The second variable is our rotation for the item we are at, so for this reason we need to calculate out how much rotation we need for each item. This will be 360 degree’s divided between how many items we have, which will give us the 1% rotation value for each item on the circle.

You can then see we call the method at the bottom after we create the method, or the LESS won’t know what you are calling. Then in each iteration we iterate the variables by removing 1 from the item count and adding another degree percentage to the previous degree.

@angle: (360 / @item-count);

.cl(@i,@r) when (@i > 0) {

@rot: @r + @angle;
.cl(@i - 1,@rot);

}

.cl(@item-count,0);

We can now convert in the style for each of the children items, which is added in the loop. The simple conversion differences are the variables in the nth-of-type and the degrees. Instead of the ‘$’ symbol we use the ‘@’.  Then compared to the SCSS version, I did the calculation within the translate instead of using a variable. I halfed the circle and again to make it flexible to change I used the Unit function.

&:nth-of-type(@{i}) {

transform: rotate(@r * 1deg)  translate(unit(@circle-size/2,px)) rotate(@r * -1deg);

}

All Together Now

At the end of the road with all the pieces we have the final product. You can then use the following as the base to build your items in a circle. I have done a small demo on my Code Pen here.

/// Mixin to place items on a circle
/// @author Hugo Giraudel
/// @author Ana Tudor
/// @author convert SASS to LESS Christopher Pateman

.on-circle(@item-count, @circle-size, @item-size) {

position: relative;
width: unit(@circle-size, px);
height: unit(@circle-size, px);
padding: 0;
margin:auto;
border-radius: 50%;

> * {

display: block;
position: absolute;
top: 50%;
left: 50%;
width: unit(@item-size, px);
height: unit(@item-size, px);
margin: unit(-(@item-size / 2), px);

@angle: (360 / @item-count);

.cl(@i,@r) when (@i > 0) {

&:nth-of-type(@{i}) {

transform: rotate(@r * 1deg)  translate(unit(@circle-size/2,px)) rotate(@r * -1deg);

}

@rot: @r + @angle;
.cl(@i - 1,@rot);

}

.cl(@item-count,0);

}

}

 

CSS Click Event

So you have click the link to find out, how on earth is there a CSS Click Event that I have not heard of? Well that’s because there is no Click Event directly, but we can replicate that event with CSS. Below will show you with a simple example how to action CSS on a click.

As I have said there is not real Click Event in CSS, but you can use the other tools you have to replicate that event. In CSS you can determine the stat of elements on the screen and so with that you can check the stat of a Checkbox. This is how we are going create the Click Event.

You can use the pseudo attribute ‘:checked’ to determine is the Checkbox is checked or not. If you use the pseudo then all CSS under it will only action when it is checked.

 

input{
    background-color:red;
}
input:checked{
    background-color:green;
}

 

Now that we know we can click on an Checkbox to activate CSS, we will need to expand its reach. If you are to click on a menu item of a button, you don’t want it to be a Checkbox. We get round this with the label element. With this element you can surround your items that will change. You can link the input and the label together so when you click on the label you are also clicking on the input.

 

<label for="chk" >

<input type="checkbox" id="chk" />

<span>

<!-- content -->

</span>

</label>

 

From this you can change the style depending on the checkbox state, but with CSS you can only target the children elements. This means you can’t target the ‘span’ because its not a child on the input that is having its state changed. What we can do is target the next element. We can do this by using the ‘+’. If you put this next to the input element then add the span in CSS the it will target the span. It affects the next element to the one on the left, please see the example below:

 

#chk:checked + span {

/* Checked Style Here */

}

 

Now you can put it all together and create a click event like I have in the Codepen below:

http://codepen.io/purerandom/full/mEyqmR/

Visual Studio Code Cookie Snippet

If you didn’t know, Microsoft release an editor called Visual Studio Code and if you didn’t know, Visual Studio Code can handle Snippets and extensions. These Snippets can be created by Visual Studio and by the coding community. These can be simple modules to help coding or full languages. I have found a use to generate a snippet of code that I always use and so I have made this into a Visual Studio Code Snippet. Read on to find out what and how to use it.

What is it?

The Snippet is called CookieJs and by the title you can guess it is about cookies in JavaScript. This snippet produces 3 methods for running cookies. One is to set a cookie, one is to get a cookie and finally a method to check if an cookie exists. These three methods can be produced separately, plus also it can be produced as a JavaScript object.

How do you get it?

If you download Visual Studio Code first of course and you can do the following

  1. Install Visual Studio Code 0.10.1 or higher
  2. Launch Code
  3. From the command palette Ctrl-Shift-P (Windows, Linux) or Cmd-Shift-P (OSX)
  4. Select Install Extension
  5. Type CookieJs
  6. Choose the extension
  7. Reload Visual Studio Code

 

How do you use it?

So like most snippets, it is easy to use. You simply have to type in one of the 4 keywords and they will produce the respective snippets of code.

 

'cookieobj' for full CookieJs object

'chkcookie' for Check Cookie Function

'getcookie' for Get Cookie Function

'setcookie' for Set Cookie Function

 

CookieJs

 

A little snag that kept getting me is to remember to have the language setting set to JavaScript. To change this you need to click the Language Indicator, which is down in the bottom right hand of the status bar. This will bring up the Command Palette for Select Language Mode. You can read more about the languages here on Visual Studio Code site on Languages.

 

Screen Shot 2016-04-27 at 20.18.15

You can get this snippet and more from this link here to my CookieJs. 

 

ARIA Control JavaScript Library

This is a library to automatically inject the standard for screen readers mark-up ARIA. ARIA is Accessible Rich Internet Applications which is a way to make websites and applications more accessible to people with disabilities.

This libraries purpose is to automatically inject the necessary tags and commands to the users mark-up, so that it meets the standards as much as possible. There are also commands for the users to inject the methods on to specific parts if the library does not get them automatically. Also the automatic functionality can be turned off if only partly needed.

Download the library on GitHub 

View the examples on CodePen

Here are some helpful links about ARIA to help understand the tags and their values.

 

ARIA Control Library V1 Method Breakdown

Hidden (has auto)

This detects all the elements that are ‘display:none’ and/or ‘visibility:hidden’. It will then add the ARIA ‘aria-hidden’ and give it a role of ‘presentation’. This makes the element hidden from screen readers. There is also a method to make the element un hidden if the state changes.

Hidden Message (has auto)

This method uses the given class in the options to make the element display off the page. This means that the screen reader can see the message and read it out, but sighted users won’t be able to see the message. This is useful if you want to give extra information only to the users using a screen reader.

Notifications

This sets the attributes for ‘aria-atomic’, ‘role’ and ‘aria-live’. These are the attributes best served as a notification.

Alert (has auto)

This is for error messages and other alerts to the user. This will use the notification method above with the settings as ‘aria-atomic: true’, ‘role: alert’ and ‘aria-live: rude’. This can be automatically run with a set class.

Warning (has auto)

This is for warning messages and other none critical alerts to the user. This will use the notification method above with the settings as ‘aria-atomic: true’, ‘role: alert’ and ‘aria-live: assertive’. This can be automatically run with a set class.

Message (has auto)

This is for any message that is not critical like a success message. This will use the notification method above with the settings as ‘aria-atomic: true’, ‘role: alert’ and ‘aria-live: polite’. This can be automatically run with a set class.

Required (has auto)

Any element, usually inputs, that has the attribute ‘required’ on them will have the ARIA tag ‘aria-required’ added to the element. This can also be done manually by passing the class.

Popup (has auto)

With this method you need to set up the popup classes for the control and the popup. It is mainly aimed at the tooltip example, e.g. if you click in a field and then a tooltip shows. The method will give the control the aria tags to show it has a popup and the tooltip the tags to show what controls it. You can also pass the role type, but by default it is ‘tooltip’.

Show and Hide Popup

These are more helper methods to the above. When the popup shows or hides you can call these method to update the elements settings.

Checked Elements (has auto)

Both Checkboxes and Radio buttons will automatically have the check item injected with the ARIA ‘aria-checked’. This marks if the element is checked or not, for which the change event is also added to all of the elements so if it becomes checked or unchecked then it is updated.

Disabled (has auto)

Any disabled element will have the ‘aria-disabled’ tag added to it.

Selected Option (has auto)

This will make all the options in a select element ‘aria-selected: false’ then find the selected option to set it to true. It also adds the event change to detect when the selected has changed and updates them.

Max and Min (has auto)

This will mainly be for inputs with a max or min value. It finds if they have a value then puts them in their relative tags, either ‘aria-valuemin’ or ‘aria-valuemax’.

Navigation (only has auto)

A complex one, but easy to set up. With all the correct settings this can add the tags to show up to screen readers as a navigation. It will also tag the links as menu items and the sub menu as well as being a popup. It uses the hover event to detect when the sub menu is being shown.

Button (has auto)

This will detect the all button types and add its role as ‘button’

 

ARIA Control Library V1 Options Breakdown

autoDetect (default = true)

This determines if to automatically tag the elements or to only allow manual running.

alertClass (default = .acAlert)

Used for the auto detection for Alert Notifications.

warningClass (default = .acWarning)

Used for the auto detection for Warning Notifications.

msgClass (default = .acMsg)

Used for the auto detection for Message Notifications.

popupClass (default = .acTooltip)

The class of the popup or, as the example was, the tooltip.

popupCtrlClass (default = .acTooltipCtrl)

The element that triggers the popup or tooltip to show.

popupType (default = tooltip)

The role of the popup.

hiddenMsgClass (default = .acHiddenMsg)

The class of any hidden messages that don’t show to slighted users.

navClass (default = .acNav)

The navigation containers class.

navParentClass (default = .acSubNav)

The top level links class.

navSubNavClass (default = .acSubMenu)

The sub menu class.

Galen Framework Hover in JavaScript

A bit of a small audience for this one, but a project I was put on wanted us to use the Galen Framework to test their UI. For people who do not know what this framework is, it is a method of writing acceptance code that matches up to the output in the browser window. This can be coded to work for all different device, sizes and URLs. One hard space I came to was to action the hover state of an element and then test it.

If you would like to read up more about the Galen Framework first then you can find all the information you need on the website.

To test you can either run it in the Galen syntax to run in the Command Prompt or you can also run it using JavaScript. I opted of the Galen Syntax for no real reason, but there was a method to action the hover in the JavaScript version.

Ivan Shubin, the creator of the Galen Framework, point me here for the example.

load("init.js");

load("pages/WelcomePage.js");

 

testOnAllDevices("Welcome page", "/", function (driver, device) {

new WelcomePage(driver).waitForIt();

checkLayout(driver, "specs/welcomePage.gspec", device.tags);

});

 

testOnDevice($galen.devices.desktop, "Menu Highlight", "/", function (driver, device) {

var welcomePage = new WelcomePage(driver).waitForIt();

logged("Checking color for menu item", function () {

checkLayout(driver, "specs/menuHighlight.gspec", ["usual"]);

})

 

logged("Checking color for highlighted menu item", function () {

welcomePage.hoverFirstMenuItem();

checkLayout(driver, "specs/menuHighlight.gspec", ["hovered"]);

});

});

You can see the ‘hoverFirstMenuItem’ that actions the hover. This is built into the Framework that comes with the JavaScript. You can find more about the API and the ‘hover’ method on the Reference Guide for JavaScript.

However I was trying to use the Galen Framework in the command prompt, which can inject JavaScript into the page that runs once the page has loaded. The first idea I had then was to run a ‘hover’ action, which because the site I was running it on has Jquery loaded I could use like below:

$(document).ready(function () {

//hover links

$('a').trigger('mouseenter');

$('a').trigger('mouseover');

$('a').trigger('hover');

$('a').hover();

});

Though as you can see I went a bit overboard trying these all out as none of them seemed to work. I knew the Jquery was working as I was able to run other method to do click events and other thing. After some searching I found a method.

I found a way to get all the style sheets and then search through them. Once I could search them I could find out what the ‘hovered’ styling was for that element. Then I could extract the styling and inject it onto the element, so now its standard style becomes its hovered style.

You can see the below method that I use ‘document.styleSheet’ to loop through each style sheet, then get each rule and loop them. If the class I am looking for is found the I user ‘cssText’ to get all the styling from the rule. This does come back as ‘{background-color:blue}’ so the response text is stripped down to just the CSS.

function getStyle(className) {

            var c = '';

            for (var i = 0; i < document.styleSheets.length; i++) {

try{

                var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;

                if (classes) {

                    for (var x = 0; x < classes.length; x++) {

                        try {

                            if (classes[x].selectorText.indexOf(className) > -1) {

                                var s = (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText;

                                s = s.substring(s.indexOf("{") + 1);

                                c += s.substring(0, s.indexOf("}"));

                            }

                        } catch (ex) {

                        }

                    }

                }

                        } catch (ex) {

                        }

            }

            return c;

        }

You will notice there is a few try catches in the loops, these are because some style sheets it picks up are not accessible so they create an error in the JavaScript. The try catches mean it can keep looping on through the ones it can access instead of breaking out. Another bug fix is where it uses ‘rules’ or ‘cssRules’ and ‘.cssText’ or ‘.style.cssText’. This is due to different browser standards, some of the browsers use one set and some use the other, this prepares for either case when your tests run.

Below is how the full code sits together and can be used. You can see I invoke the method by passing ‘a:hover’ as it is the hover state I need to access to the link.

$(document).ready(function () {

function getStyle(className) {

            var c = '';

            for (var i = 0; i < document.styleSheets.length; i++) {

try{

                var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;

                if (classes) {

                    for (var x = 0; x < classes.length; x++) {

                        try {

                            if (classes[x].selectorText.indexOf(className) > -1) {

                                var s = (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText;

                                s = s.substring(s.indexOf("{") + 1);

                                c += s.substring(0, s.indexOf("}"));

                            }

                        } catch (ex) {

                        }

                    }

                }

                        } catch (ex) {

                        }

            }

            return c;

        }

        //all links

        $('a').attr('style', getStyle('a:hover'));

});