Leaderboard
Popular Content
Showing content with the highest reputation on 11/12/2013 in Posts
-
1 point
-
По дате можно систематизировать файлы, если имя одинаково, то добавлять к нему номер счётчика.1 point
-
Я не буду использовать чужие регулярки - сайты часто делаются для Украины и Беларуссии, а если из-за саной регулярки, которая что-то не учла клиент начнет долбится как дятел на сайте не в состоянии отослать свой номер телефона - это будет потеря потерь. Я уже пробовала брать готовые скрипты - и в них часто нельзя было ввести мой номер телефона - так что, пусть будет лучше 3 цифры телефона, чем потерянный клиент. К тому же у меня стоит через жабу легкая регулярка, а кто захочет подолбится в сайт, чтобы напортачить, его регулярка не остановит. Например, Хабрабарская регулярка не пропускает 5значный простой номер "23510" и даже шестизначник - представляю лицо пожилого человека, который вводит свой номер из какого-нибудь города Уссурийска - а ему выдает ошибку - сколько он будет пыхтеть над этой формой с сайтом, пытаясь понять, что вообще происходит?... Как видите авторы таких регулярок просто недееспособны в этом плане. А чтобы написать самой по-настоящему правильную регулярку, мне нужно прочитать целый ликбез о телефонах и телефонных форматах в россии и в мире, потратить сколько дней - 1-2, а также возможно вероятно прийти к выводу как с проверкой почты сейчас советуют - проверять только на знак @. И также и я могу в итоге прийти к выводу, что лучшая проверка - цифры и спец-знаки.1 point
-
1 point
-
Если я правильно понял связь между элементами массивов происходит не по значению параметра id а просто по порядковому номеру элемента в массиве. Попробуй так: for (i in arrVal) { for (j in arr) { if (i == j) { document.getElementById(arrVal[i].id).value = arr[j].data; } }}1 point
-
Посмотрите на http://getbootstrap.com/components/#navbar там в коде есть эта кнопка button.navbar-toggle с data-target, указывающей на id сворачивающегося меню (#bs-example-navbar-collapse-1). Она и появляется на узких экранах. У вас в коде этого нет, потому нет и кнопки. Кроме того, для этого меню нужен еще js бутстрапа.1 point
-
Вдобавок http://habrahabr.ru/post/136622/#surprise (конкретно про этот случай). По спецификации, «желаемая ширина» флоата рассчитывается по контенту, размещенному в одну строку везде, где только можно. Но вот включать ли в эту ширину вложенные флоаты или нет — браузеры расходятся во мнениях. Fx и Вебкит/Блинк впихивают вложенный флоат в уже рассчитанный внешний, отчего текст перестает вмещаться и переносится, IE и старая Опера (на Престо) добавляют ширину флоата к контейнеру, текст при этом не переносится. Насколько я понимаю спецификацию, ее букве и духу лучше отвечает поведение IE (как ни странно), а поведение Fx и хромиумов является багом.1 point
-
меня всегда удивляло: php'шники пишут mvc на сервере, а на клиенте абру-кадабру делают. И типа это нормально, так и должно быть php <?php$messages = array( 'true' => '<true msg>', 'false' => '<false msg>' );$status = true;$result = array( 'status' => $status, 'messages' => $messages ); // правда, не понятно зачем отправлять все сообщения...echo json_encode( $result );?>js success: function(data) { var status = data.status; var messages = data.status; $("#results").html( messages[status] ); $('.error')[ !status ? 'fadeIn' : 'fadeOut' ](); $('.true')[ status ? 'fadeIn' : 'fadeOut' ](); $('.overlay, .order')[ status ? 'show' : 'hide' ]();},разумеется писал в форум и не проверял1 point
-
История о том, как выбесить верстальщика. Заказчик дает макет шириной 1267px, нужна ему резина от 768 до 960. Делаю ему резину. Картинки задаю в процентах, чтобы уменьшались. В общем через два дня 5 страниц готовы. По безопасной сделке. Через два дня отдаю ему готовую резину - заказчик недоволен. Потому что сжимается только по ширине, а ему надо, оказывается что "все элементы логически должны сжиматься по высоте и ширине". Пытаюсь ему объяснить, что шрифты не должны сжиматься по высоте и ширине. Сжимаются только блоки-контейнеры и изображения, заданные в процентах. Ему все не нравится. Не соответствует макету. Притом что макет на 1267px ! Я в шоке. Два дня коту под хвост. Договариваемся, что я делаю фикс на 960px. Он мне пишет "Насчет картинки – возможно нарисовано под 1267, это не так важно т.к это относительные величины – просто так качество изображений будет лучше значит нужно изменить размер под необходимый". Уменьшаю в фотошопе исходник до ширины 960px, "логически блин сжимаю элементы по высоте и ширине". Меняю все картинки, шрифты, сверяю по пиксел перфект - все один в один. Впереди выходные три дня - заказчика нет. Безопасная сделка просрочена. Появляется во вторник - опять все не так. И началось. Увеличить шрифт здесь, вон там и еще в 10 местах. Меняю. Отдаю. Еще через три часа - увеличить это там вон там и вот тут. И так уже два дня. Никаких конечно же соответсвий макету нет. А он еще вопрос задает - это что, сложно шрифты увеличить. Я вообще в шоке. С каким макетом сверяться. То ли с первым на 1267, то ли с уменьшенным. В общем сделай то, незнаю что.1 point
-
Обрабатываем клик по клетке Итак, у нас уже почти все готово для полноценной игры. Осталось только обработать клик по клетке на доске. Давайте создадим метод который назовем showInfo, внутри данного метода мы будем проверять проиграл ли уже пользователь, что отобразить на клетке и т.п. Метод будет принимать в качестве параметра элемент на котором кликнули: var MyMineSweeper = { init: function(o) { this.W = o ? o.W : 7; this.H = o ? o.H : 7; this.bombs = o ? o.bombs : Math.floor(this.W * this.H / 4); this.placedBombs = this.bombs; this.generateGUI(); }, generateGUI: function() { if (!this.game) { this.game = this.writeMainContainer(); this.gameCont = document.createElement('table'); this.gameCont.className = 'game-cont'; this.gameCont.insertRow(0); this.gameCont.insertRow(1); this.gameMenu = this.gameCont.rows[0].insertCell(0); this.gameMenu.rowSpan = 2; this.gameMenu.className = 'game-menu'; this.gameMenu.appendChild(document.createTextNode('Ширина поля:')); this.gameMenu.appendChild(document.createElement('br')); this.WInput = document.createElement('input'); this.WInput.type = 'text'; this.gameMenu.appendChild(this.WInput); this.gameMenu.appendChild(document.createTextNode('Высота поля:')); this.gameMenu.appendChild(document.createElement('br')); this.HInput = document.createElement('input'); this.HInput.type = 'text'; this.gameMenu.appendChild(this.HInput); this.gameMenu.appendChild(document.createTextNode('Кол-во мин:')); this.gameMenu.appendChild(document.createElement('br')); this.BInput = document.createElement('input'); this.BInput.type = 'text'; this.Init = document.createElement('input'); this.Init.type = 'button'; this.Init.value = 'Старт'; this.Init.className = 'game-start-button'; this.gameMenu.appendChild(this.BInput); this.gameMenu.appendChild(this.Init); this.gameStats = this.gameCont.rows[0].insertCell(1); this.gameField = this.gameCont.rows[1].insertCell(0); this.gameField.className = 'game-field'; this.game.appendChild(this.gameCont); } if (this.board) { this.board.parentNode.removeChild(this.board); this.board = null; } this.board = this.generateField(); this.board.cellSpacing = 0; this.board.className = 'game-board'; this.gameField.appendChild(this.board); this.gameStats.innerHTML = 'Новая игра: поле ' + this.W + 'x' + this.H + ', ' + this.bombs + 'мин'; this.setupEvents(); }, setupEvents: function() { var self = this; var buttonClick = function() { self.init({W: self.WInput.value, H: self.HInput.value, bombs: self.BInput.value}); } Event.add(this.Init, 'click', buttonClick); }, generateField: function() { var self = this; var table = document.createElement('table'); for (var i = 0; i < this.H; i++) { var r = table.insertRow(i); for (var j = 0; j < this.W; j++) { var c = r.insertCell(j); c.num = 0; c.index = [i, j]; c.clickHandler = function() { self.showInfo(this); } Event.add(c, 'click', c.clickHandler); } } do { var hNum = this.rand(0, this.H - 1); var wNum = this.rand(0, this.W - 1); if (!table.rows[hNum].cells[wNum].bomb) { table.rows[hNum].cells[wNum].num = null; table.rows[hNum].cells[wNum].bomb = true; this.placedBombs--; } } while (this.placedBombs > 0); for (var i = 0, len = table.rows.length; i < len; i++) { for (var j = 0, len2 = table.rows[i].cells.length; j < len2; j++) { if (table.rows[i].cells[j].bomb) { this.placeNumbers(table, j, i); } } } return table; }, placeNumbers: function(t, x, y) { if (x > 0) { t.rows[y].cells[x - 1].num++; } if (x < this.W - 1) { t.rows[y].cells[x + 1].num++; } if (x > 0 && y > 0) { t.rows[y - 1].cells[x - 1].num++; } if (y > 0) { t.rows[y - 1].cells[x].num++; } if (y > 0 && x < this.W - 1) { t.rows[y - 1].cells[x + 1].num++; } if (x > 0 && y < this.H - 1) { t.rows[y + 1].cells[x - 1].num++; } if (y < this.H - 1) { t.rows[y + 1].cells[x].num++; } if (x < this.W - 1 && y < this.H - 1) { t.rows[y + 1].cells[x + 1].num++; } }, showInfo: function(elem) { if (!elem.bomb) { this.openCell(elem); } else { this.openCell(elem); this.gameOver(); } }, openCell: function(elem) { if (!elem.bomb) { if (elem.num > 0) { elem.innerHTML = '<b>' + elem.num + '</b>'; } else { elem.innerHTML = ' '; } switch (elem.num) { case 1: elem.style.color = 'blue'; break; case 2: elem.style.color = 'green'; break; case 3: elem.style.color = 'red'; break; case 4: elem.style.color = 'dakrblue'; break; case 5: elem.style.color = 'pink'; break; case 6: elem.style.color = 'navy'; break; case 7: elem.style.color = 'brown'; break; case 8: elem.style.color = 'grey'; break; default: elem.style.color = 'black'; } } else { elem.innerHTML = '<b>M</b>'; } elem.style.background = '#d8e0ec'; }, writeMainContainer: function() { var html = '<div id="game" class="game"></div>'; document.writeln(html); return document.getElementById('game'); }, rand: function(min, max) { min = parseInt(min); max = parseInt(max); return Math.floor(Math.random() * (max - min + 1)) + min; } } Обрабатываем Game Over Теперь подумаем, что должно происходить когда юзер нарвался на мину: 1) нам нужно показать все мины на доске, 2) нам нужно снять все слушатели событий с клеток, чтобы пользователь не мог никуда больше кликнуть пока не начнет новую игру, 3) нам нужно уведомить пользователя о том что он проиграл. Реализуем все в коде: gameOver: function() { // пробегаемся циклом по доске for (var i = 0, len1 = this.board.rows.length; i < len1; i++) { // цикл по вертикали for (var j = 0, len2 = this.board.rows[i].cells.length; j < len2; j++) { // цикл по горизонтали if (this.board.rows[i].cells[j].bomb) { // если на клетке стоит мина // показываем мину this.openCell(this.board.rows[i].cells[j]); } // снимаем обработчик события "click" с каждой клетки Event.remove(this.board.rows[i].cells[j], 'click', this.board.rows[i].cells[j].clickHandler); } } // красим ячейку статистики в красный цвет this.gameStats.style.background = 'red'; // и говорим юзеру, что он подорвался this.gameStats.innerHTML = '<b>БАБАХ!!! GAME OVER!</b>'; } У нас все готово для полноценной игры. Ура! Однако радоваться рано. Если посмотреть на настоящего сапёра, то можно увидет одну особенность - если мы кликнем на клетку рядом с которой нет мин (т.е. номер на ней 0), то откроются все соседние пустые клетки, т.е. все клетки, граничащие с открытой, рядом к которыми тоже нет мин. То есть происходит так называемый каскад. Пожалуй это будет самая сложная функция в нашем сапёре. Итак... Реализуем каскад Вы себе даже не представляете как долго я бился на этим методом. Что я только не делал, где только не гуглил И вот, наконец я допер, что в нелегком деле каскадирования нам поможет рекурсия! Что такое рекурсия? Это когда функция вызывает сама себя. Что обязательно должно быть в рекурсивной функции? Первым делом в рекурсивной функции должен быть продуман выход из нее, чтобы не было бесконечного зацикливания. В принципе это все, что нужно знать о рекурсии, но без примера все равно сложно это понять, поэтому я вам приведу пример простейшей рекурсии: // функция принимает в качестве параметра начальное число и конечное число function myRecursion(num, maxNum) { /* * первым делом продумываем * выход из бесконечной рекурсии */ if (num > maxNum) { // если начальное число больше конечного // выходим из функции return; } // пишем в документ текущую цифру document.write(num + ', '); // увеличиваем число на 1 num++; // вызываем саму себя (рекурсивный вызов) myRecursion(num, maxNum); } myRecursion(0, 5); // выведет 0, 1, 2, 3, 4, 5 Ну вот, теперь вы должны представлять что такое рекурсия и мы можем начать писать наш метод-каскад, назовем его roll, метод будет принимать в качестве параметров координаты клетки на доске: roll: function(x, y) { /* * первым делом продумываем * выход из бесконечной рекурсии */ // если x или y выходят за границы доски if (x < 0 || y < 0 || x >= this.W || y >= this.H) { // выходим return; } // открываем клетку this.openCell(this.board.rows[y].cells[x]); // если рядом с клеткой есть бомба (т.е. номер в ней больше 0) if (this.board.rows[y].cells[x].num > 0) { // вставляем в клетку цифру this.board.rows[y].cells[x].innerHTML = '<b>' + this.board.rows[y].cells[x].num + '</b>'; // выходим return; } // если мы уже эту клетку проверяли if (this.board.rows[y].cells[x].check) { // выходим return; } // отмечаем, что эту ячейку мы уже проверяли this.board.rows[y].cells[x].check = true; // далее пошла рекурсия this.roll(x + 1, y); // делаем шаг вправо this.roll(x - 1, y); // делаем шаг влево this.roll(x, y + 1); // делаем шаг вниз this.roll(x, y - 1); // делаем шаг вверх this.roll(x - 1, y - 1); // делаем шаг вверх влево this.roll(x + 1, y - 1); // делаем шаг вверх вправо this.roll(x - 1, y + 1); // делаем шаг вниз влево this.roll(x + 1, y + 1); // делаем шаг вниз вправо } Вызывать наш каскад будем в методе showInfo, для этого нам его надо будет немного изменить, добавив дополнительные проверки: showInfo: function(elem) { if (!elem.bomb) { // если в клетке нет мины if (elem.num > 0) { // если рядом есть мины (номер больше 0) // открываем клетку this.openCell(elem); } else { // если рядом нет ни одной мины /* * запускаем каскад * тут нам и пригодилось дополнительное * свойство хранимое в клетке (index), * в котором храняться в виде массива * координаты клетки на доске */ this.roll(elem.index[1], elem.index[0]); } } else { // если в клетке мина // открываем клетку this.openCell(elem); // завершаем игру this.gameOver(); } } Вот и все. Теперь у нас готов полноценный сапер. Он конечно не совсем похож на того сапера который присутствует в винде. В нем нельзя отмечать места с предполагаемой миной и нет счетчика времени, зато в нем можно варьировать уровень сложности и размер доски по своему усмотрению, а все недостатки легко доделать. Главное вы теперь знаете устройство такой замечательной логической игры как сапёр! Ах да, вот полный код нашего сапера: var MyMineSweeper = { init: function(o) { this.W = o ? o.W : 7; this.H = o ? o.H : 7; this.bombs = o ? o.bombs : Math.floor(this.W * this.H / 4); this.placedBombs = this.bombs; this.generateGUI(); }, generateGUI: function() { if (!this.game) { this.game = this.writeMainContainer(); this.gameCont = document.createElement('table'); this.gameCont.className = 'game-cont'; this.gameCont.insertRow(0); this.gameCont.insertRow(1); this.gameMenu = this.gameCont.rows[0].insertCell(0); this.gameMenu.rowSpan = 2; this.gameMenu.className = 'game-menu'; this.gameMenu.appendChild(document.createTextNode('Ширина поля:')); this.gameMenu.appendChild(document.createElement('br')); this.WInput = document.createElement('input'); this.WInput.type = 'text'; this.gameMenu.appendChild(this.WInput); this.gameMenu.appendChild(document.createTextNode('Высота поля:')); this.gameMenu.appendChild(document.createElement('br')); this.HInput = document.createElement('input'); this.HInput.type = 'text'; this.gameMenu.appendChild(this.HInput); this.gameMenu.appendChild(document.createTextNode('Кол-во мин:')); this.gameMenu.appendChild(document.createElement('br')); this.BInput = document.createElement('input'); this.BInput.type = 'text'; this.Init = document.createElement('input'); this.Init.type = 'button'; this.Init.value = 'Старт'; this.Init.className = 'game-start-button'; this.gameMenu.appendChild(this.BInput); this.gameMenu.appendChild(this.Init); this.gameStats = this.gameCont.rows[0].insertCell(1); this.gameField = this.gameCont.rows[1].insertCell(0); this.gameField.className = 'game-field'; this.game.appendChild(this.gameCont); } if (this.board) { this.board.parentNode.removeChild(this.board); this.board = null; } this.board = this.generateField(); this.board.cellSpacing = 0; this.board.className = 'game-board'; this.gameField.appendChild(this.board); this.gameStats.innerHTML = 'Новая игра: поле ' + this.W + 'x' + this.H + ', ' + this.bombs + 'мин'; this.WInput.value = this.W; this.HInput.value = this.H; this.BInput.value = this.bombs; this.gameStats.style.background = '#bfd3ed'; this.setupEvents(); }, setupEvents: function() { var self = this; var buttonClick = function() { self.init({W: self.WInput.value, H: self.HInput.value, bombs: self.BInput.value}); } Event.add(this.Init, 'click', buttonClick); }, generateField: function() { var self = this; var table = document.createElement('table'); for (var i = 0; i < this.H; i++) { var r = table.insertRow(i); for (var j = 0; j < this.W; j++) { var c = r.insertCell(j); c.num = 0; c.index = [i, j]; c.clickHandler = function() { self.showInfo(this); } Event.add(c, 'click', c.clickHandler); } } do { var hNum = this.rand(0, this.H - 1); var wNum = this.rand(0, this.W - 1); if (!table.rows[hNum].cells[wNum].bomb) { table.rows[hNum].cells[wNum].num = null; table.rows[hNum].cells[wNum].bomb = true; this.placedBombs--; } } while (this.placedBombs > 0); for (var i = 0, len = table.rows.length; i < len; i++) { for (var j = 0, len2 = table.rows[i].cells.length; j < len2; j++) { if (table.rows[i].cells[j].bomb) { this.placeNumbers(table, j, i); } } } return table; }, placeNumbers: function(t, x, y) { if (x > 0) { t.rows[y].cells[x - 1].num++; } if (x < this.W - 1) { t.rows[y].cells[x + 1].num++; } if (x > 0 && y > 0) { t.rows[y - 1].cells[x - 1].num++; } if (y > 0) { t.rows[y - 1].cells[x].num++; } if (y > 0 && x < this.W - 1) { t.rows[y - 1].cells[x + 1].num++; } if (x > 0 && y < this.H - 1) { t.rows[y + 1].cells[x - 1].num++; } if (y < this.H - 1) { t.rows[y + 1].cells[x].num++; } if (x < this.W - 1 && y < this.H - 1) { t.rows[y + 1].cells[x + 1].num++; } }, showInfo: function(elem) { if (!elem.bomb) { if (elem.num > 0) { this.openCell(elem); } else { this.roll(elem.index[1], elem.index[0]); } } else { this.openCell(elem); this.gameOver(); } }, openCell: function(elem) { if (!elem.bomb) { if (elem.num > 0) { elem.innerHTML = '<b>' + elem.num + '</b>'; } else { elem.innerHTML = ' '; } switch (elem.num) { case 1: elem.style.color = 'blue'; break; case 2: elem.style.color = 'green'; break; case 3: elem.style.color = 'red'; break; case 4: elem.style.color = 'dakrblue'; break; case 5: elem.style.color = 'pink'; break; case 6: elem.style.color = 'navy'; break; case 7: elem.style.color = 'brown'; break; case 8: elem.style.color = 'grey'; break; default: elem.style.color = 'black'; } } else { elem.innerHTML = '<b>M</b>'; } elem.style.background = '#d8e0ec'; }, gameOver: function() { for (var i = 0, len1 = this.board.rows.length; i < len1; i++) { for (var j = 0, len2 = this.board.rows[i].cells.length; j < len2; j++) { if (this.board.rows[i].cells[j].bomb) { this.openCell(this.board.rows[i].cells[j]); } Event.remove(this.board.rows[i].cells[j], 'click', this.board.rows[i].cells[j].clickHandler); } } this.gameStats.style.background = 'red'; this.gameStats.innerHTML = '<b>БАБАХ!!! GAME OVER!</b>'; }, roll: function(x, y) { if (x < 0 || y < 0 || x >= this.W || y >= this.H) { return; } this.openCell(this.board.rows[y].cells[x]); if (this.board.rows[y].cells[x].num > 0) { this.board.rows[y].cells[x].innerHTML = '<b>' + this.board.rows[y].cells[x].num + '</b>'; return; } if (this.board.rows[y].cells[x].check) { return; } this.board.rows[y].cells[x].check = true; this.roll(x + 1, y); this.roll(x - 1, y); this.roll(x, y + 1); this.roll(x, y - 1); this.roll(x - 1, y - 1); this.roll(x + 1, y - 1); this.roll(x - 1, y + 1); this.roll(x + 1, y + 1); }, writeMainContainer: function() { var html = '<div id="game" class="game"></div>'; document.writeln(html); return document.getElementById('game'); }, rand: function(min, max) { min = parseInt(min); max = parseInt(max); return Math.floor(Math.random() * (max - min + 1)) + min; } } Всем спасибо за внимание, надеюсь урок был вам полезен. Предложения, замечания и т.п. пишите в личку.1 point
-
Помогите сделать php скрипт для обработки форм обратной связи, и скиньте урок какой нибудь на эту тему. Нужна форма обратной связи как на этом сайте http://idandy.ru/ внизу-1 points
-
@zaka4kin, что ты лезешь в мою тему! Есть вопрос, задавай его отдельно.-1 points
This leaderboard is set to Kiev/GMT+02:00
-
Upcoming Events
No upcoming events found -
Сообщения форума
-
Доброго всем времени суток. Прошу помощи. Научите принципу изменения футера. Движок Xenforo. Версия 2.2.10. Стиль дефолтный. Что именно нужно в итоге на фото примере. Мой шаблон app.footer less имеет следующее значение. .p-footer { .xf-publicFooter(); a { .xf-publicFooterLink(); } } .p-footer-inner { .m-pageWidth(); .m-pageInset(); padding-top: @xf-paddingMedium; padding-bottom: @xf-paddingLarge; } .p-footer-row { .m-clearFix(); margin-bottom: -@xf-paddingLarge; } .p-footer-row-main { float: left; margin-bottom: @xf-paddingLarge; } .p-footer-row-opposite { float: right; margin-bottom: @xf-paddingLarge; } .p-footer-linkList { .m-listPlain(); .m-clearFix(); > li { float: left; margin-right: .5em; &:last-child { margin-right: 0; } a { padding: 2px 4px; border-radius: @xf-borderRadiusSmall; &:hover { text-decoration: none; background-color: fade(@xf-publicFooterLink--color, 10%); } } } } .p-footer-rssLink { > span { position: relative; top: -1px; display: inline-block; width: 1.44em; height: 1.44em; line-height: 1.44em; text-align: center; font-size: .8em; background-color: #4682B4; border-radius: 2px; } .fa-rss { color: white; } } .p-footer-copyright { margin-top: @xf-elementSpacer; text-align: center; font-size: @xf-fontSizeSmallest; } .p-footer-debug { margin-top: @xf-paddingLarge; text-align: right; font-size: @xf-fontSizeSmallest; .pairs > dt { color: inherit; } } @media (max-width: @xf-responsiveMedium) { .p-footer-row-main, .p-footer-row-opposite { float: none; } .p-footer-copyright { text-align: left; padding: 0 4px; // aligns with other links } }
-
Нужны сайты с примерами верстки, типа https://css-tricks.com/. Типовые приемы и нестандартные на все случаи жизни. Накидайте ссылок.
-
By Katerina23 · Posted
Да, подходит. Спасибо. -
<input type="number">
-
By Katerina23 · Posted
Здравствуйте, подскажите какой тег использовать для увеличения значения, пример на картинке. Вроде, про такой тег я слышала. Если есть тег прогресс бар, значит и такое должно быть.
-