Внимание! Данная версия сайта не поддерживается с 2013 года.
Актуальная версия сайта — giryaev.com

Задача для знатоков CSS «Найди ошибку в слайдере»

В процессе редизайна данного сайта я столкнулся с необходимостью сделать слайдер (который вы сейчас можете наблюдать в правой части "шапки"). Сейчас он реализован с использованием JavaScript, но изначально у меня было желание сделать его на чистом CSS. Поскольку я не являюсь знатоком HTML и CSS (мои знания и умения в этой области исключительно любительского уровня), то я, естественно, решил "нагуглить" качественный CSS-слайдер для последующей его модификации под мои нужды. Более всего мне понравилось решение, предлагаемое в одной из статей на Хабре. Но позже я понял, что, к сожалению, такой слайдер, вопреки утверждениям в указанной статье, имеет проблему в работе со ссылками. Далее я подробно её опишу и, быть может, кого-то этот вопрос заинтересует — и в результате совместными усилиями будет найдено решение данной проблемы.

Итак, в уже упомянутой статье приводится подробный разбор создания аккуратного слайдера (плавная смена изображений) на CSS3. И реализовать такой слайдер мне было не сложно. Однако всё же одна существенная ошибка, хоть и не заметная на первый взгляд, закралась. Причём она в некотором роде присутствует и в самой статье на Хабрахабре. При описании контенера, который играет роль отдельно взятого слайда, говорится дословно следующее: «Это более универсальный способ, чем переключение свойств картинки, поскольку в div-контейнер, в отличие от пустого элемента img, можно поместить любую дополнительную информацию (например, название слайда, или связанное описание, включая ссылки).» Для уже ознакомившихся со статьёй на Хабре поясню, что тут речь идёт о контейнере:

<div class="slider__item">...</div>

В примере, на который ссылается статья, данный контейнер заполнен лишь изображением (и именно поэтому там слайдер и работает корректно):

<div class="slider__item">
<img src="[ссылка]" title="" alt="" class="slider__img">
</div>

Я же попытался сделать изображение кликабельным, т.е. использовать конструкции вида:

<div class="slider__item">
<a href="[ссылка]"><img src="[ссылка]" title="" alt="" class="slider__img"></a>
</div>

Однако по какой-то причине при такой реализации при смене слайдов ссылка каждый раз берётся с последнего изображения (т.е. какие бы я ссылки не прописал изображениям, содержащимся в первых слайдах, при клике мы всегда будем переходить на URL, указанный в последнем слайде).

Вот вам и задача: как исправить эту ошибку?:)

Для удобства читателей ниже приведу полный код примера из статьи на Хабре:

<style>
pre{overflow: scroll; width: 500px;}

.slider /* MODIFIER */
{
 position: relative;
 display: inline-block;
 z-index:0; 
} 
.slider .slider__img
{
 margin: 0px;
}
.slider .slider__radio
{
 display: none;
}
.slider .slider__number
{
 bottom: 10px;
 display: inline-block;
 z-index: 2;
 width: 26px;
 height: 20px;
 transition: all 0.1s linear;
 -moz-transition: all 0.1s linear;
 -webkit-transition: all 0.1s linear;
 -o-transition: all 0.1s linear;
 
 border: 1px solid #ccc;
 border-color: #e6e6e6 #e6e6e6 #bfbfbf;
 border-radius: 4px;
 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
 text-align: center;
 cursor: pointer;
 font: 14px/20px arial, tahoma, verdana;
 color: #333;
 text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
}
.slider .slider__number-list
{
 position: absolute;
 bottom: 15px;
 right: 15px;
 z-index: 11;
}
.slider .slider__item
{
 opacity: 1.0;
 position: relative;
 transition: opacity 0.0s linear 0.2s;
 -moz-transition: opacity 0.0s linear 0.2s;
 -webkit-transition: opacity 0.0s linear 0.2s;
 -o-transition: opacity 0.0s linear 0.2s;
}
.slider .slider__item:not(.ie)
{
 opacity: 0.0;
}


.image-tape:hover .image-tape__item,
.image-tape:hover .image-tape__number-after
{
 -moz-animation-play-state: paused;
/* -webkit-animation-play-state: paused; */
 -o-animation-play-state: paused;
 animation-play-state: paused;
}

.slider .slider__item ~ .slider__item
{
 position: absolute;
 top: 0px;
 left: 0px;
 opacity: 0.0;
}
.slider .slider__radio:nth-of-type(1):checked ~ .slider__number-list .slider__number:nth-of-type(1),
.slider .slider__radio:nth-of-type(2):checked ~ .slider__number-list .slider__number:nth-of-type(2),
.slider .slider__radio:nth-of-type(3):checked ~ .slider__number-list .slider__number:nth-of-type(3),
.slider .slider__radio:nth-of-type(4):checked ~ .slider__number-list .slider__number:nth-of-type(4),
.slider .slider__radio:nth-of-type(5):checked ~ .slider__number-list .slider__number:nth-of-type(5)
{
 color: #fff;
}
.slider .slider__radio:nth-of-type(1):checked ~ .slider__item:nth-of-type(1),
.slider .slider__radio:nth-of-type(2):checked ~ .slider__item:nth-of-type(2),
.slider .slider__radio:nth-of-type(3):checked ~ .slider__item:nth-of-type(3),
.slider .slider__radio:nth-of-type(4):checked ~ .slider__item:nth-of-type(4),
.slider .slider__radio:nth-of-type(5):checked ~ .slider__item:nth-of-type(5)
{
 opacity: 1.0;
 transition: opacity 0.2s linear;
 -moz-transition: opacity 0.2s linear;
 -webkit-transition: opacity 0.2s linear;
 -o-transition: opacity 0.2s linear;
 z-index: 6;
}

/* autorotation of slides */
@keyframes slider__item-autoplay_count_2 {0%{opacity:0;}20%{opacity:1;}50%{opacity:1;}70%{opacity:0;}100%{opacity:0;}}
@keyframes slider__item-autoplay_count_3 {0%{opacity:0;}10%{opacity:1;}33% {opacity:1;}43% {opacity:0;}100%{opacity:0;}}
@keyframes slider__item-autoplay_count_4 {0%{opacity:0;}8% {opacity:1;}25% {opacity:1;}33% {opacity:0;}100%{opacity:0;}}
@keyframes slider__item-autoplay_count_5 {0%{opacity:0;}7% {opacity:1;}20%{opacity:1;}27% {opacity:0;}100%{opacity:0;}}

@-moz-keyframes slider__item-autoplay_count_2 {0%{opacity:0;}20%{opacity:1;}50%{opacity:1;}70%{opacity:0;}100%{opacity:0;}}
@-moz-keyframes slider__item-autoplay_count_3 {0%{opacity:0;}10%{opacity:1;}33% {opacity:1;}43% {opacity:0;}100%{opacity:0;}}
@-moz-keyframes slider__item-autoplay_count_4 {0%{opacity:0;}8% {opacity:1;}25% {opacity:1;}33% {opacity:0;}100%{opacity:0;}}
@-moz-keyframes slider__item-autoplay_count_5 {0%{opacity:0;}7% {opacity:1;}20%{opacity:1;}27% {opacity:0;}100%{opacity:0;}}

@-webkit-keyframes slider__item-autoplay_count_2 {0%{opacity:0;}20%{opacity:1;}50%{opacity:1;}70%{opacity:0;}100%{opacity:0;}}
@-webkit-keyframes slider__item-autoplay_count_3 {0%{opacity:0;}10%{opacity:1;}33% {opacity:1;}43% {opacity:0;}100%{opacity:0;}}
@-webkit-keyframes slider__item-autoplay_count_4 {0%{opacity:0;}8% {opacity:1;}25% {opacity:1;}33% {opacity:0;}100%{opacity:0;}}
@-webkit-keyframes slider__item-autoplay_count_5 {0%{opacity:0;}7% {opacity:1;}20%{opacity:1;}27% {opacity:0;}100%{opacity:0;}}

@-o-keyframes slider__item-autoplay_count_2 {0%{opacity:0;}20%{opacity:1;}50%{opacity:1;}70%{opacity:0;}100%{opacity:0;}}
@-o-keyframes slider__item-autoplay_count_3 {0%{opacity:0;}10%{opacity:1;}33% {opacity:1;}43% {opacity:0;}100%{opacity:0;}}
@-o-keyframes slider__item-autoplay_count_4 {0%{opacity:0;}8% {opacity:1;}25% {opacity:1;}33% {opacity:0;}100%{opacity:0;}}
@-o-keyframes slider__item-autoplay_count_5 {0%{opacity:0;}7% {opacity:1;}20%{opacity:1;}27% {opacity:0;}100%{opacity:0;}}

.slider .slider__number-after
{
 position: absolute;
 display: block;
 top: 1px;
 width: 26px;
 height: 20px;
 position: absolute;
 border-radius: 4px;
 margin: 0px;
 opacity: 0.0;
 color: #fff;
}

.slider.slider_count_2 .slider__item, .slider.slider_count_2 .slider__number-after
{
 animation: slider__item-autoplay_count_2 10s infinite;
 -moz-animation: slider__item-autoplay_count_2 10s infinite;
 -webkit-animation: slider__item-autoplay_count_2 10s infinite;
 -o-animation: slider__item-autoplay_count_2 10s infinite;
}
.slider.slider_count_3 .slider__item, .slider.slider_count_3 .slider__number-after
{
 animation: slider__item-autoplay_count_3 15s infinite;
 -moz-animation: slider__item-autoplay_count_3 15s infinite;
 -webkit-animation: slider__item-autoplay_count_3 15s infinite;
 -o-animation: slider__item-autoplay_count_3 15s infinite;
}
.slider.slider_count_4 .slider__item, .slider.slider_count_4 .slider__number-after
{
 animation: slider__item-autoplay_count_4 20s infinite;
 -moz-animation: slider__item-autoplay_count_4 20s infinite;
 -webkit-animation: slider__item-autoplay_count_4 20s infinite;
 -o-animation: slider__item-autoplay_count_4 20s infinite;
}
.slider.slider_count_5 .slider__item, .slider.slider_count_5 .slider__number-after
{
 animation: slider__item-autoplay_count_5 25s infinite;
 -moz-animation: slider__item-autoplay_count_5 25s infinite;
 -webkit-animation: slider__item-autoplay_count_5 25s infinite;
 -o-animation: slider__item-autoplay_count_5 25s infinite;
}
.slider .slider__item:nth-of-type(2), .slider .slider__number:nth-of-type(2) > .slider__number-after{animation-delay:5s;-moz-animation-delay:5s;-webkit-animation-delay:5s;-o-animation-delay:5s;}
.slider .slider__item:nth-of-type(3), .slider .slider__number:nth-of-type(3) > .slider__number-after{animation-delay:10s;-moz-animation-delay:10s;-webkit-animation-delay:10s;-o-animation-delay:10s;}
.slider .slider__item:nth-of-type(4), .slider .slider__number:nth-of-type(4) > .slider__number-after{animation-delay:15s;-moz-animation-delay:15s;-webkit-animation-delay:15s;-o-animation-delay:15s;}
.slider .slider__item:nth-of-type(5), .slider .slider__number:nth-of-type(5) > .slider__number-after{animation-delay:20s;-moz-animation-delay:20s;-webkit-animation-delay:20s;-o-animation-delay:20s;}

.slider .slider__radio:checked ~ .slider__item
{
 animation: none;
 -moz-animation: none;
 -webkit-animation: none;
 -o-animation: none;
}
.slider .slider__radio:checked ~ .slider__number-list .slider__number-after
{
 opacity: 0.0;
 animation: none;
 -moz-animation: none;
 -webkit-animation: none;
 -o-animation: none;
}
 
.slider .slider__number
{
 height: 27px;
 border: 0px;
 border-radius: 0px;
 background: transparent url(/_mod_files/ce_images/blog/image-tape__number.png) no-repeat;
 box-shadow: none;
 font: 14px/29px arial, tahoma, verdana;
}
.slider .slider__number:hover
{
 background: transparent url(/_mod_files/ce_images/blog/image-tape__number.png) no-repeat;
}
.slider .slider__radio:nth-of-type(1):checked ~ .slider__number-list .slider__number:nth-of-type(1),
.slider .slider__radio:nth-of-type(2):checked ~ .slider__number-list .slider__number:nth-of-type(2),
.slider .slider__radio:nth-of-type(3):checked ~ .slider__number-list .slider__number:nth-of-type(3),
.slider .slider__radio:nth-of-type(4):checked ~ .slider__number-list .slider__number:nth-of-type(4),
.slider .slider__radio:nth-of-type(5):checked ~ .slider__number-list .slider__number:nth-of-type(5)
{
 background: transparent url(/_mod_files/ce_images/blog/image-tape__number_sel.png);
}
.slider .slider__number_state_checked,
.slider .slider__number_state_checked:hover,
.slider .slider__number-after
{
 top: 0px;
 height: 27px;
 border-radius: 0px;
 background: transparent url(/_mod_files/ce_images/blog/image-tape__number_sel.png);
 font: 14px/29px arial, tahoma, verdana !important; /* конфликт стилей amiro.ru */
}


/* ie8 */
.slider .slider__item{visibility: hidden\9;}
.slider .slider__item_state_checked{visibility: visible\9;}

/* ie7 */
*+html .slider .slider__item{visibility: hidden;}
*+html .slider .slider__item_state_checked{visibility: visible;}

/* ie6 */
* html .slider {height: 210px;}
* html .slider .slider__item {position: absolute;}
* html .slider .slider__item{visibility: hidden;}
* html .slider .slider__item_state_checked{visibility: visible;}

/* ie */
.slider .slider__number-after
{
 display: none \9; /* ie8 *//* for ie9 there is an opacity 0.0 */
 *display: none; /* ie7 */
 _display: none; /* ie6 */
}
.slider .slider__item_state_checked
{
 z-index: 5;
}
.slider .slider__number_state_checked
{
 color: #fff;
}
</style>

<p><br></p>

<!-- Блок slider. Обратите внимание на модификаторы - это не просто лента изображений, а лента в режиме слайдшоу и количестве слайдов равным 3 -->
<div id="slider-group1341994720" class="slider slider slider_count_3">
 <!-- Список радиокнопок - они скрыты -->
 <input name="imagetape" id="imagetape1" class="slider__radio" type="radio">
 <input name="imagetape" id="imagetape2" class="slider__radio" type="radio">
 <input name="imagetape" id="imagetape3" class="slider__radio" type="radio">
 
 <!-- Список слайдов - в них можно помещать картинки и что угодно ещё -->
 <div class="slider__item">
 <img src="/_mod_files/ce_images/blog/1.jpg" title="" alt="" class="slider__img">
 </div>
 <div class="slider__item">
 <img src="/_mod_files/ce_images/blog/2.jpg" title="" alt="" class="slider__img">
 </div>
 <div class="slider__item">
 <img src="/_mod_files/ce_images/blog/3.jpg" title="" alt="" class="slider__img">
 </div>
 
 <!-- Контейнер лейблов с цифрами - по клику на них выбирается слайд и отменяется вся анимация -->
 <div class="slider__number-list">
 <label onclick="javascript:ami_gadget_image_tape_setSlideInIE(this);" data-ami-number="1" class="slider__number" for="imagetape1">
 <!-- DOM узел "-after" необходим для плавной анимации background-image в браузерах FF и Opera -->
 <!-- Псевдоэлемент ::after не анимируется в браузерах Chrome и Safari -->
 1<p class="slider__number-after">1</p>
 </label>
 <label onclick="javascript:ami_gadget_image_tape_setSlideInIE(this);" data-ami-number="2" class="slider__number" for="imagetape2">
 2<p class="slider__number-after">2</p>
 </label>
 <label onclick="javascript:ami_gadget_image_tape_setSlideInIE(this);" data-ami-number="3" class="slider__number" for="imagetape3">
 3<p class="slider__number-after">3</p>
 </label>
 </div>
</div>
<script type="text/javascript">/* for IE7-9, and maybe IE10 */function ami_gadget_image_tape_setSlideInIE(label){ if (navigator.appName != "Microsoft Internet Explorer") return; if (ami_gadget_image_tape_autorotation_group1346218401 === false && !label) return; if (typeof arguments.callee.counter === 'undefined') arguments.callee.counter = 0; if (typeof label === 'undefined') { var gallery = document.getElementById('slider-group1346218401'); } else { var gallery = label.parentNode.parentNode; ami_gadget_image_tape_autorotation_group1346218401 = false; } var slides = gallery.getElementsByTagName('div'); /* last element is number-list */ var number_list = slides[slides.length - 1]; var numbers = number_list.getElementsByTagName('label'); var label_checked_class = 'slider__number_state_checked'; var slide_checked_class = 'slider__item_state_checked'; var index = 0; /* current slide index */ /* finding number of clicked label */ for ( var i = 0 ; i <= numbers.length - 1 ; i++ ) { if ( label === numbers[i] ) index = i; slides[i].className = slides[i].className.replace(' ' + slide_checked_class, ''); numbers[i].className = numbers[i].className.replace(' ' + label_checked_class, ''); } if (!label) index = arguments.callee.counter; slides[index].className += ' ' + slide_checked_class; numbers[index].className += ' ' + label_checked_class; arguments.callee.counter++; if (arguments.callee.counter >= numbers.length) arguments.callee.counter = 0; if (ami_gadget_image_tape_autorotation_group1346218401) setTimeout(arguments.callee, 4000);}ami_gadget_image_tape_autorotation_group1346218401 = true;setTimeout(ami_gadget_image_tape_setSlideInIE, 0);</script>

Отмечу также, что при выборе слайда с помощью кнопок (см. пример), переход по ссылкам осуществляется корректно.

Обсуждение

▲ Наверх