Достъпен Слайдер (Accessible Slider) – 1/2
22.01.2019
За годините, изминали от оригиналното публикуване на статията, технологиите са се променили прекалено много. Моля не следвайте описаното по-долу като урок как да създадете slider, а гледайте на нещата само като на насоки за някои основни принципи като:
- функционалност дори и без включен JavaScript
tabindex
иfocus
на DOM елементи- стилове по допълнителен клас при наличие на JS
През последните години е много модерно да се говори за достъпност на сайтовете, но реално това е една трудно постижима задача.
Когато започнах работа и тепърва пишех JavaScript, шефът ми на работа ми каза нещо важно, което винаги имам предвид когато правя сайтове:
Един сайт трябва винаги да върви, дори и да нямаш JavaScript
От една страна изглежда като нещо съвсем просто и естествено, но който е правил сайт знае, че винаги ще се намери поне едно малко препъни камъче.
Но не само това е необходимо, когато става въпрос за достъпност.
Достъпността изисква не само да може да се достигне до съдържанието когато няма JavaScript, а и да можем да достигнем лесно до него когато има JavaScript, но има и някакви други спънки.
Тук ще разгледаме един пример, който ще ни покаже как с малко повече от 100 реда код можем да си направим цялостен достъпен слайдер.
Структура
Да започнем с празна HTML5 страница.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Slider</title>
</head>
<body>
</body>
</html>
Да припомним, че DOCTYPE
декларацията на HTML5 е опростена до максимум, като се оставя възможност на браузърите сами да определят най-добрия начин, по който могат да представят съдържанието.
Също така да припомним, че сложният HTML4 мета таг за оказване на кодировката също е опростен до <meta charset="utf-8" />
.
Ще продължим като добавим един <div>
таг, койго ще съдържа нашия слайдер, както и самия слайдер, описан чрез неподреден списък.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Slider</title>
</head>
<body>
<div id="slider" tabindex="0">
<ul>
<li><img src="images/slide-1.jpg" alt="" /></li>
<li><img src="images/slide-2.jpg" alt="" /></li>
<li><img src="images/slide-3.jpg" alt="" /></li>
<li><img src="images/slide-4.jpg" alt="" /></li>
<li><img src="images/slide-5.jpg" alt="" /></li>
</ul>
</div>
</body>
</html>
В примера, който представям в отделните слайдове използвам картинки, но съдържанието може да бъде абсолютно всякакво.
Стилове
След като вече структурата ни е готова остава да добавим стил, jQuery (за по-прост пример, ще го заредим директно от официалния сайт, без да го теглим на нашия сървър) както и малко наш JavaScript, за да заработи слайдера.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Slider</title>
<link rel="stylesheet" href="style.css" media="all" />
<script type="text/javascript" charset="utf-8" src="http://code.jquery.com/jquery-1.6.min.js"></script>
<script type="text/javascript" charset="utf-8" src="func.js" defer="defer"></script>
</head>
<body>
<div id="slider" tabindex="0">
<ul>
<li><img src="images/slide-1.jpg" alt="" /></li>
<li><img src="images/slide-2.jpg" alt="" /></li>
<li><img src="images/slide-3.jpg" alt="" /></li>
<li><img src="images/slide-4.jpg" alt="" /></li>
<li><img src="images/slide-5.jpg" alt="" /></li>
</ul>
</div>
</body>
</html>
Може би забелязвате tabindex атрибута на <div id="slider">
. Това е с цел повишена достъпност, която ще уточним когато стигнем до JavaScript частта.
Първо ще обърнем внимание на стиловете и когато сме достатъчно доволни от начина, по който слайдерът ни изглежда когато няма JavaScript вече можем да продължим нататък.
Ето това е най-добрият начин за разработка на сайтове – първо да се прави всичко без JS и чак тогава вече, когато сме убедени, че всичко изглежда и върви наред, можем да си позволим просто да добавим бонус функционалност за тези, които имат feature-а наречен JavaScript. Добре де – feature е силно казано, но за да работим качествено понякога трябва някои полу-дадености да ги приемаме за нещо много голямо, така че когато липсват сайтът ни да не се омаже.
Стилът си започваме с два реда, които да изчистят основните стилове и да придадат някакъв основен вид на сайта ни:
* { margin: 0; padding: 0; }
body { padding: 20px 0; background: #333; color: #FFF; font: normal 12px Arial, Helvetica, sans-serif; }
В първия ред премахваме всички отстояния, които браузърите добавят по подразбиране. Не само, че в много случаи са излишни, ами и варират при отделните браузъри и после защо сайтът ни не изглежда еднакво навсякъде.
Стиловете, които задаваме на <body>
тага са за да добавим малко отстояние отгоре и отдолу, да зададем тъмносив фон, бял цвят на текста, който да се вижда на този фон, основен размер и шрифт на текста.
#slider { position: relative; width: 960px; margin: 0 auto; border: 2px solid #000; }
#slider:focus { outline: none; }
#slider ul { width: 100%; list-style-type: none; overflow: hidden; }
#slider ul li { display: inline; float: left; }
#slider li img { float: left; }
Следват стилове, които използваме за слайдера по подразбиране. Не забравяйте – на този етап трябва да пригодим слайдера си да изглежда така, че да ни върши работа, ако няма JavaScript.
На #slider
задавам position: relative;
защото вътре имам списък, чиято широчина знам, че ще задам на 100% и ще очаквам да е колкото #slider
контейнера.
На самия #slider
задавам широчина и отстояние margin: 0 auto;
така че той да се центрира на страницата. Задавам черна рамка с дебелина 2px
.
Тъй като в HTML-а сме задали tabindex
на <div id="slider">
, трябва да се погрижим за ограждащия стил на браузърите по подразбиране. Премахваме го като на #slider:focus
задаваме outline: none;
.
На самия списък задаваме 100% широчина (не забравяйте, че това е широчината на най-близкия относително разположен родителски елемент – в нашия случай това е #slider
, тъй като именно на него сме задали position: relative;
).
На <li>
елементите задаваме display: inline;
както и float: left
, защото в противен случай когато заредим страницата между картинките се получават по няколко празни пиксела. Когато зададем float
на самите <img>
елементи той изчезва, но за да бъдат и <li>
елементите високи колкото картинките трябва и на тях също да зададем float
стил.
Остава като проблем обаче височината на списъка, в който са разположени float
-натите <li>
елементи. На него обаче не можем да зададем float
, защото после ще искаме да го позиционираме за да бъде в крайна сметка наистина слайдер. По тази причина на списъка задаваме overflow: hidden
.
Необяснимо и незнайно точно защо, този стил почти винаги върши работата, която истаме и елементът получава правилната височина (включваща всичките му дъщерни елементи).
По принцип това поже да се получи и с елемент със стил clear: both
, който е разположен след float
-натите елементи, но самият <ul>
таг не може да има други дъщерни елементи освен <li>
тагове, а не можем да използваме <li>
таг с друг стил и друго предназначение, тъй като броят на тези елементи при нас после ще окаже голямо значение за слайдера.
В момента нашият слайдер представлява просто едни вертикално подредени елементи. Може да не е особено красив и да не е точно слайдер, но поне всички елементи, които съдържа, са видими и без JavaScript.
В някои случаи дизайнът на страницата, на която добавяте слайдера може да има други изисквания за представяне на съдържанието, но там вече зависи от вас да приложите подходящи стилове, за да бъде уместно в текущия контекст на страницата.
С или без JavaScript?
Сега следва да поработим и върху стиловете, в случай че имаме JavaScript.
Най-лесно е през JS да добавим просто още един клас към нашия слайдер и посредством този клас да приложим нови стилове. С цел да улесня разработките си, аз първо ще добавя този нов клас на ръка в HTML-а, ще въведа новите стилове и когато всичко е готово и е тествано ще добавя самия JavaScript.
Новите стилове задавам като разширение към старите селектори като просто използвам един клас повече, който ще ми покаже, че има включен JavaScript.
#slider.js { height: 540px; overflow: hidden; }
#slider.js:focus { border-color: #666; }
#slider.js ul { position: absolute; width: 50000em; height: 100%; }
#slider.js ul li { width: 960px; height: 100%; }
#slider.js a { position: absolute; top: 250px; z-index: 10; width: 20px; height: 40px; background: rgba(255, 255, 255, 0.2); }
#slider.js .next { right: 10px; }
#slider.js .prev { left: 10px; }
На #slider.js
задавам фиксирана височина, колкото ще е височината на един елемент и задавам overflow: hidden
, защото този контейнер ще играе ролята на едно прозорче, през което ще се вижда част от една голяма лента от елементи, които от време на време ще се сменят с анимация.
При фокус на #slider
сега вече сменям и цвета на рамката, за да имат посетителите на сайта някаква индикация, че елементът е на фокус и биха имали възможност за по-специална интеракция (повече информация – когато стигнем до JS-а). На списъка задавам абсолютно позициониране, за да мога после да го премествам, някаква голяма широчина, за която да съм убеден, че би побрала всички елементи, които ще присъстват в него, защото за хоризонтален слайдер, какъвто ще правя, ми е нужно дъщерните елементи да са хоризонтално един до друг.
Задавам и височина 100%, за да съм сигурен, че ще бъде точно колкото прозорчето.
На <li>
елементите в списъка задаваме широчина колкото прозореца, за да го запълват изцяло, както и височина 100%. Широчина 100% тук няма да свърши работа, тъй като тя се отнася не само до relative позиционирани родителски елементи, а и за абсолютно позиционирани, така че 100% широчина би довело до 50000em
в конкретния случай.
Освен на тези елементи задаваме стилове и за едни линкове, които не присъстват в HTML-а, а ще ги добавим динамично с JS. Техните стилове можем да въведем спокойно и без .js
класа, тъй като ако няма JS тези елементи дори няма да съществуват, но за консистентност ще го оставя да следват тази конвенция на именуване.
Стиловене на тези линкова в общи линии включва просто позиция и фон (в моя случай фонът е просто бял полупрозрачен, но вие може да поискате да сложите картинка на стрелки, които да показват посоката на движение на елементите в слайдера).
Същинската част от слайдера – неговият JS код – очаквайте в нов пост (втора част от урока) в най-скоро време.
[…] по подразбиране. По този въпрос съм говорил и в първа и втора част на урока си за достъпен […]