I have to float multiple elements around the midpoint of their element. This is currently solved in css by using display: table
/ display: table-cell
.
The problem with this solution is that each group of blocks must wrapped in an extra element, what makes it hard to layout this responsive. Moreover, the visible order is not correct.
I would like to use javascript, to align the elements by using position: absolute
, but I have just no clue how to calculate the offsets. Another option might be to create each group dynamically (depending on the window width / height), and to use the actual css (below) to align the elements.
html, body {
height: 100%;
}
.blocks {
display: table;
margin-left: auto;
margin-right: auto;
max-width: 40em;
width: 100%;
height: 100%;
}
.group {
display: table-cell;
vertical-align: middle;
}
.block {
background-color: rgb(50, 50, 50);
color: rgb(255, 255, 255);
height: 8em;
line-height: 8em;
margin: 1em;
text-align: center;
width: 8em;
}
/* Debug
------------------------------------------------ */
.blocks {
counter-reset: tile;
}
.block:before {
counter-increment: tile;
content: counter(tile);
}
<!-- small screens -->
<div class="blocks">
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
</div>
<hr>
<!-- large screens -->
<div class="blocks">
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
</div>
<!-- huge screens -->
<div class="blocks">
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="group">
<div class="block"></div>
<div class="block"></div>
</div>
</div>
...for completeness, position:absolute
approach:
.blocks {
margin-left: auto;
margin-right: auto;
max-width: 40em;
position: relative;
}
.block {
background-color: rgb(0, 225, 225);
border: 1px solid white;
box-sizing:border-box;
height: 8em;
line-height: 8em;
position: absolute;
text-align: center;
width: 8em;
}
.block:nth-of-type(1) {
top: 8em;
left: 0;
}
.block:nth-of-type(2) {
top: 4em;
left: 8em;
}
.block:nth-of-type(3) {
top: 0;
left: 16em;
}
.block:nth-of-type(4) {
top: 4em;
left: 24em;
}
.block:nth-of-type(5) {
top: 8em;
left: 32em;
}
.block:nth-of-type(6) {
top: 16em;
left: 0;
}
.block:nth-of-type(7) {
top: 12em;
left: 8em;
}
.block:nth-of-type(8) {
top: 8em;
left: 16em;
}
.block:nth-of-type(9) {
top: 12em;
left: 24em;
}
.block:nth-of-type(10) {
top: 16em;
left: 32em;
}
.block:nth-of-type(11) {
top: 20em;
left: 8em;
}
.block:nth-of-type(12) {
top: 16em;
left: 16em;
}
.block:nth-of-type(13) {
top: 20em;
left: 24em;
}
.block:nth-of-type(14) {
top: 24em;
left: 16em;
}
/* Debug
------------------------------------------------ */
.blocks {
counter-reset: tile;
}
.block:before {
counter-increment: tile;
content: counter(tile);
}
<div class="blocks">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
Ideally the layout would respect both, the window width and height. So that the blocks always fit in the current screen size. Could be done with something like this:
var cols = Math.floor(innerWidth / children[0].clientWidth)
var rows = Math.round(innerHeight / children[0].clientHeight)
I have searched now for a while, but have not found any existing solutions. The closest are:
- Position icons into circle
- Centre multiple elements within div using css
- Other elements wrap around center positioned div
By the way, I'm inspired by https://typekit.com/ ;)