There is a grid in several lines of the same blocks. By clicking on each block after the current line, the hub should open, pushing the next lines of the grid, with an arrow pointing to the block to which they clicked. Like in iTunes.

How to impose?

enter image description here

  • I forgot to add that all this lies in a rubber container: there can be three or more blocks in a row - elijah-cdr
  • elijah-cdr, you'd better move your add from comment directly to the question - Pavel Mayorov
  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

3 answers 3

To impose on radio as a link in the questionable question is wrong from the point of view of semantics. Yes, such crutches are used on examples like "how to make it only via css" and even, it seems, work. But you don’t need to do that if you don’t want to show off with your knowledge of CSS, but want to get a really working copy without crutches.

Here's how to proceed in your case:
1. Making a grid of squares.
2. A child element is added to each square (a block that will “fall out”)
3. JavaScript'om catch a click on the square
4. When you click add child class "show"
5. We define the style for the class .show as follows:
First add visibility: visible;
After that, we increase the height of the element to the desired
Then we change the text color to the desired one (at first it was equal to the background so that it was not visible)

When you click on another element, remove .show in the current element and add it to the clicked (if the task requires it).

Now I am implementing something similar, and if you cannot impose yourself on my algorithm, I will add code.

UPD

So far my solution is: http://codepen.io/smellyshovel/pen/gMwzKa .
Cons: tip does not occupy the entire width of the parent block. This is treated by adding position: absolute; , but with this solution the next row of blocks does not move downwards. Alternatively, you can set the parent ( .container ) class .show , which will add padding it equal to the height of the emerging .tip. But writing this is work. And any work must be paid. So, at least, I thought of you, I think.

  • And, well, of course, with each new execution of the openTip() .show remove .show from the other blocks, so that only one .tip is always visible. - smellyshovel
  • And yet, about the triangle on top. With JavaScript, we get the center of the block that was clicked on, and then set :: before .tip (just this triangle) to the left for as many pixels as we received with JavaScript. - smellyshovel

Something like this. The data in the block can be loaded by Ajax (but you’ll have to do it yourself).

The only BUT is the calculation of the position of the triangle some kind of crutch. Surely it can be done better. But what we have, we have.

 "use strict"; var notification_status = new Array; var row_elems = document.querySelectorAll(".wrap > .row > div"); var current_tab = undefined; // Считает позицию элемента function elemPosition(a_this, items_count) { var block_position = 0; var cur = a_this.previousElementSibling; for (var i = 0; i < items_count; i++) { if (cur) { cur = cur.previousElementSibling; block_position += 1; } else { break; } } return block_position; } // Удаляет созданное окно, если оно было создано. function removeNotification() { if (document.querySelector(".notification") != null) { var elem = document.querySelector(".notification"); elem.remove(); } } // Создание информационного окна function addNotification(a_this) { var wrap = a_this.parentNode.parentNode; var notification = document.createElement("div"); notification.className = "notification"; var triangle = document.createElement("div"); triangle.className = "triangle"; var items_count = a_this.parentNode.children.length var item = elemPosition(a_this, items_count); var triangle_position_left = (50 / items_count) - (10 / items_count) + ((50 / items_count) * item * 2); triangle.style.marginLeft = triangle_position_left + "%"; wrap.appendChild(notification); notification.appendChild(triangle); } // Навешиваение обработчиков на нужные элементы row_elems.forEach(function(item, i, row_elems) { row_elems[i].onclick = function() { if (i == current_tab) { removeNotification(); current_tab = undefined; } else { removeNotification(); addNotification(this); current_tab = i; } }; }); 
 input:focus, button:focus, textarea:focus { outline: none; } input:active, button:active, textarea:active { outline: none; } * { box-sizing: border-box; } html, body { height: 100%; } body { font-family: Verdana; font-size: 16px; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } div.row { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; } div.row > div { width: 100px; height: 100px; background-color: rgba(39, 174, 96, 0.7); margin: 10px; border-radius: 5px; } div.row > div:hover { cursor: pointer; -webkit-transition: 0.5s; transition: 0.5s; background-color: #e74c3c; } div.row > div:not(:hover) { -webkit-transition: 0.5s; transition: 0.5s; } .notification { width: 100%; height: 100px; border-radius: 5px; background-color: rgba(243, 156, 18, 0.7); margin: 10px 0 10px 0; } .triangle { width: 10px; height: 10px; position: relative; } .triangle:before, .triangle:after { content: ''; position: absolute; top: -19px; border: 10px solid transparent; } .triangle:after { border-bottom: 10px solid rgba(243, 156, 18, 0.7); } 
 <div class="wrap"> <div class="row"> <div></div> <div></div> </div> </div> <div class="wrap"> <div class="row"> <div></div> <div></div> <div></div> </div> </div> <div class="wrap"> <div class="row"> <div></div> <div></div> <div></div> <div></div> </div> </div> 

    If you have a static page and not too many of these lines, you can pre-impose the "hub", set its height as 0px and the desired transition , and by clicking to increase the height of the "hub" to the desired one.