Windows calculator с HTML5 и CSS3 (3)

ЧАСТ 1: Подготвяне на работни файлове

ЧАСТ 2: Разделяне калкулатора на зони 

ЧАСТ 3: Структуриране на HTML файла

Целия код за калкулатора може да видите ТУК. А сега стъпка по стъпка, за да стане ясна логиката.

1. Оформяне на <head> частта 

HTML-parts-head

Началото на всеки HTML файл задължително съдържа:

  • указание за HTML версията, на която е писан документът: използваме <!DOCTYPE html>, което означава, че пишем на езика HTML5
  • заглавие на HTML страницата: съдържанието на <title> елемента ще видим като заглавие за този таб на браузъра, в който сме отворили нашия HTML документ
  • указание за кодировката: използваме кодировка UTF-8 според препоръката на w3schools 
  • линк към свързания CSS файл: винаги е по-добре стилизирането да се отделя във външен файл, а не да се пише в HTML таговете; тук имаме дори два файла, тъй като за IE7 се налага добавянето на отделни стилове

Да се пишат inline стилове не е добра практика. Дори при сложен код, когато се стигне до такъв, използването на вградени стилове е показател, че нещо не е направено достатъчно добре.

Стилове могат да се поставят и в <style> тага в началото на нашия HTML файл, но и това не е добро решение по две причини:

  • първо заради неудобството да въртиш нагоре и пак надолу при писане на документа, особено при по-дълъг код
  • второ, не може да се преизползва написаният CSS в други HTML документи, без да се включи в отделен файл

По своя преценка може да добавите и други елементи в <head> частта на документа. Това зависи от целите на уеб страницата, които следвате. Тук просто се упражняваме, затова ще се ограничим само до гореизброеното.

2. Оформяне на <body> частта 

HTML-parts-body

Имаме един главен контейнер за калкулатора, който държи всички други елементи в себе си. Той си има тюркоазен фон и фиксирани размери, които ще зададем във файла със стиловете по съответния начин. Използваме <div> за контейнера и му даваме id=“calculator“. Ползваме id, а не class, понеже няма да имаме друг обект калкулатор на нашата уеб страница. Какво ще се съдържа вътре в контейнера?

1|Лента с икона и главни бутони 

1-main-buttons

За самата лента няма нужда от ограждащ елемент. Пишем директно тагове за елементите в нея: <img> за иконката, <span> за заглавието Calculator и останалото са <input> тагове от типа image. Понеже имаме бутони, <form> елементът е задължителен. Отваряме го тук и ще го затворим, след като приключим с всички бутони на уеб страницата ни.

Виждаме, че иконката на приложението е вляво, а главните бутони са подравнени вдясно. Заглавието е между тях, по средата. Различното подравняване означава, че ще трябва в стиловете да го зададем индивидуално за всеки от тях. За по-голямо удобство, слагаме още класове:

  • class=“icon“ за иконата
  • class=“name“ за заглавието
  • class=“main-button“ за трите дясно подравнени бутона

Защо за иконата и заглавието не задаваме id, въпреки че са „уникални“ елементи за нашата уеб страница? Отговорът е прост: в някакъв несбъднат все още сценарий на уеб страницата може да се появи друг контейнер, с аналогична подредба на икона, заглавие и бутони. Понеже работим само върху един контейнер (той държи целия калкулатор), напълно оправдано е вместо класове, да се ползват id-та. Но аз все пак ще се въздържа да слагам такива. Оставям си вратичка, да се върна към тях в момента, когато ми се наложи да ги ползвам за по-голям приоритет при писането на стилове. Въпросът е принципен: минимум id-та, освен когато контекстът не ги налага и не можем да ги заменим с класове; минимум class атрибути, освен когато стилизирането ги изисква, за да можем да манипулираме повече елементи наведнъж.

Използването на композитни селектори

Стилизирането може да се прави и без класове или id-та, само чрез композитни селектори. Въпрос на личен избор. Но трябва да се помисли дали при бъдещо оптимизиране на уеб страницата ни за по-стари версии на браузърите няма да ни се отвори повече работа: Internet Explorer 6 не разбира този тип селектори и ще ни принуди да сложим класове на елементите, за да ги стилизираме. Добрата новина е, че от март 2011 г. Microsoft натиска уеб потребителите да спрат да ползват този браузър и да се насочат към по-нови версии. С особен трепет очакват кончината на IE6 уеб разработчиците, които наблюдават процеса на официалния сайт, който Microsoft създадоха за целта. Поддръжката на IE6 от Microsoft продължава официално до 2014 г., като част от пакета на операционната система Windows XP SP3. Въпреки това, поради нарастващата несъвместимост на „гениалния“ браузър със съвременните уеб стандарти, гига-сайтове като YouTube спират поддръжката му. Google са с официална позиция по въпроса още от януари 2010 г.

Друго съображение, което можем да имаме: при композитните селектори може да се стигне до повече нива на влагане, което поначало трябва да се избягва. Пример: img + div + input + input + input.

Картинките имат alt атрибути. Добре е да имат, затова сме ги сложили: alt атрибутът изписва посочения от нас текст, когато по някакви причини картинката не успее да се зареди. По този начин потребителят добива представа какво е трябвало да види на съответното място.

Пътищата до самите картинки се посочват в src атрибута: всичко вземаме от img папката. За бутона minimize сме включили кратък JavaScript, който сменя изображението при посочване с мишката върху този бутон. При input бутоните този ефект няма как да се постигне чрез стилове, затова сме използвали скрипт.

Приложение на класа .clear

Виждате, че освен id=“calculator“, за най-външния div, който държи всичко останало, сме приложили и class=“clear“. Това е „служебен“ клас, който се поставя при писането на стиловете за елементите, които съдържат в себе си вътрешни елементи с приложен float. С класа .clear извършваме т.нар. зачистване на флоутовете. Защо и как се прави, си струва да се обясни в отделна тема. За момента просто имайте предвид, че това е смисълът на този клас, ще го видите и по-надолу в кода.

Тялото на калкулатора разделяме на две главни части:

  • навигационна лента
  • всичко останало

И двете се намират в общ div елемент с class=“body“. По-горе вече се написаха някои неща по повод избора на клас, а не на id. Същото важи и за останалата част от кода.

2|Лента с навигация (менюта View, Edit, Help)

2-menu

По навигацията нямаме нещо особено: ul елемент с li елементи, в които има линкове <a>. Някои пояснения по създаването на навигационен блок можете да прочетете тук.

Понеже по-нататък в кода имаме още списъци (при radio бутоните), които ще се стилизират различно, тук сме поставили class=“menu“ за менюто.

Всичко под менюто на калкулатора обхващаме в общ div елемент, на който слагаме class=“holder“. Името на класа е достатъчно говоримо.

3|Поле за въвеждане на данни и за извеждане на резултат от калкулация 

3-result

Самото поле ограждаме в собствен div и вътре в него input от типа text. Виждате, че на div-а сме сложили два класа, освен служебния: class=“result section clear“. Първо е записан „уникалният“ клас result, който говори за смисъла на тази част от кода, а именно поле за извеждане на резултат. Следва по-общ клас section, който се прилага на още няколко места. Да спрем за момент и да обясним за него.

Погледнете пак калкулатора. Вижте как основните „парцели“ в него имат сива външна рамка:

  • полето за резултат
  • полето за бинарно представяне
  • полето с бройните системи
  • полето с типовете данни
  • бутони (при тях е специфично, разясненията са по-долу)

Някои от тези зони имат и вътрешна бяла рамка, но тя се задава по различни начини. Освен това, парцелите са на еднакво отстояние от лявата страна на най-външния елемент. При дясната страна има вариране, но дори да приложим еднакво отстояние, то после може да се презапише чрез индивидуални стилове за конкретния парцел.

Стремим се да мислим за цялостта и да не повтаряме стиловете, които пишем отделно за всяка зона. По тази причина е оправдано да ползваме общ клас, който да прилага еднаквите стилове. Този общ клас в случая е section. По-нататък ще има и други такива класове.

Вътре в div-а сме включили input от типа text за въвеждане на числа и извеждане на резултат. Максималният брой цифри, който може да се впише тук, е 16. Това е причината да зададем maxlength=“16″. Именували сме input-а (name=“total-result“), с идеята, че този атрибут може да се ползва по-късно от зададено с JavaScript поведение. На същото основание ще видите имена на всички останали input елементи в този код.

4|Поле за бинарна репрезентация на числата 

4-bits

Ако погледнете как е построено това поле, ще видите, че под всеки ред с битове (нуличките) има по три указателя с номер на позицията за съответния бит, като отброяването започва от 0. Това идва да покаже, че действието се развива отдолу-нагоре и отдясно-наляво, по редове, а не по колони, макар че за прегледност, а и поради логиката на запис в паметта, битовете са разделени на групи по четири. Това може да се проследи и с превключване режимите за типа данни на калкулатора:

Byte (1 байт) 

byte

Word (2 байта) 

word

Dword (4 байта) 

dword

Qword (8 байта) 

qword

Отбелязахме в началото, че при кликване върху отделните битове се превключва от стойност 0 в 1, и обратно. Това означава, че нулите са своеобразни бутони. Тъй като няма да имплементираме програмна логика, а само ще създадем HTML шаблон за калкулатора, ще оставим битовете в span елементи, като всеки от тях ще съдържа по четири бита, за да можем да ги позиционираме по групи. На по-късен етап, ако разработваме функционалност за калкулатора, може да се преработи тази част от кода, като всеки бит се включи в отделен <span> или друг подходящ таг, за да бъде отделна единица, на която да се зададе поведение.

Всеки от редовете е поставен в отделен div елемент със съответен клас: class=“bytes“ за битовете или class=“bits-position“ за номерацията на техните позиции. Четирите реда от своя страна са обградени с общ div с class=“bits section“. Класът .bits дава възможност да зададем специфични стилове за този отрязък от калкулатора. Виждате, че на отделни <span> тагове е приложен class=“second“, а на други class=“last“. Причината е в позиционирането: средните номерации на битови позиции, както и крайните (последни), които са най-вдясно, приемат различен подход при стилизиране за IE7. Подробностите може да видите в CSS файловете.

5|Поле за избор на бройна система, към която да се конвертира (Hex, Dec, Oct, Bin)

5-systemТози участък представяме с ul-списък. Даваме собствен клас на списъка (class=“systems section“), за да го стилизираме чрез него, както направихме по-горе за списъка на навигацията.

Във всеки ред с li елемент включваме input бутон от тип radio с label елемент към него (за името). Атрибутът for следва да приема същото съдържание като value атрибута в дадения input, за който се отнася label-ът. За да може да остава маркиран само един от радио бутоните, върху които щракаме, задаваме на всички  общо име: name=“system“. Начална селекция на бутона dec сме задали чрез атрибута checked=“checked“. Може да се запише и съкратено, само като checked (при XHTML това е забранено).

6|Поле за избор на тип данни, към който да се конвертира (Qword, Dword, Word, Byte)

6-data-type

Участъкът е построен по същия начин, както полето за избор на бройна система, само класовете са различни: class=“data-types section“ за списъка и name=“data-type“ за радио бутоните.

7|Поле с бутони

Как процедираме с всичките тези бутони? Цяла плантация, която трябва да се организира по-прилично. 🙂

7-buttons

Имаме един блок с бутони в него, подравнени по редици и колони. Можем да си ги редим така до безкрайност и всичко щеше да е толкова лесно, ако не бяха бутоните за нулата и равното, които така неприлично се открояват. Видно е, че са специални по размер. Съответо, ни прекъсват хубавите редички и стройни колони.

Ако бяхме ползвали таблица за изграждането на layout-а, сега без никакъв проблем щяхме да обединим по два реда или по две колони, за да образуваме тези големи бутони. Само че ние работим с div-ове.

По идея, division-ите изпълват на 100% широчината на parent елемента, в който сме ги сложили, и съответно го удължават, докато ги побере всичките. Ако опитаме да си поиграем с float-ване, каквото ще се случи и тук (за да се наредят div-овете един до друг, а не всеки да е на отделен ред), нещата стават малко по-сложни. Още повече, че самият външен div, който държи всички бутони в себе си, трябва да се позиционира отдясно на зоните с бройните системи и с типовете данни. По тази причина сме му задали class=“buttons“, за да можем да го местим чрез класа. При поясненията върху CSS файла ще обясним повече за това как е осъществено позиционирането.

Защо избираме да поставим в div елемент всеки бутон, а не в span, след като очевидно ще ги редим един до друг? Поради това, че span елементите нямат собствена широчина/височина и ще трябва да ги третираме като блокови (да сменим начина, по който се display-ват), за да им зададем такава. Не, че и това не може да се случи. Може. Въпрос на личен избор.

А защо ги пъхаме в обвивки, а не ги стилизираме директно като input-и? Знаем, че икономията е основен принцип и при изграждането на HTML построенията: минимум код, нищо излишно. HTML-ът е като тялото, а CSS са дрехите: в нормалния случай никой не мечтае за трета ръка, само за да може да носи дреха с три ръкава. Обграждащите div-ове тук са като едни трети ръце, но се налага да ги ползваме, поради една особеност на input елементите, за която ще стане въпрос при поясненията върху стилизирането. Ако не беше тази особеност, щяхме да минем без тях, тъй като са излишно натоварване на HTML кода. Само за първия (празен) бутон може да се остави div без input в него.

Разкрояване на плантацията

Сред бутоните могат да се обособят отделни смислови групи:

  • бутони за логически и побитови операции
  • бутони за шестнайсетични пресмятания
  • бутони с цифри и други оператори

Дизайнът на калкулатора разделя формално тези групи чрез рамките, размера на шрифта и фона на отделните кутийки. Рамките са единични или двойни, имат по-тъмен или по-светъл цвят. Фонът е прост (едноцветен) или градиентен (с преливащи цветове). Цифрите, колоната с букви (A, B, C, D, E, F) и отделни знаци (стрелка, +, *, =) са с по-едър шрифт. Единствените бутони, които се различават по размер, са „0“ и „=“.

Класовете, които създаваме, групират бутоните с общ стил. За input елементите прилагаме:

  • class=“disabled“ – без вътрешна рамка, прост фон (по-светъл)
  • class=“simple-background“ – прост фон
  • class=“bigger“ – по-едър шрифт
  • class=“number“ – градиентен фон (по-ярък)
  • class=“equal“ – различна височина, градиентен фон и по-едър шрифт за бутона „=“

За div елементите около input-ите прилагаме:

  • class=“disabled“ – единична рамка (по-светла)
  • class=“simple-background“ – различен цвят на външната рамка при hover
  • class=“equal“ – различно позициониране и височина за бутона „=“
  • class=“zero“ – различна широчина за бутона „0“

При писането на HTML-а поставяме кутийката с бутона „=“ веднага след кутийката с бутона „-“. Важно е да се спази тази поредност, за да се реализира по добър начин float-ването върху бутоните. Подробностите – при обясненията за стилизирането.

Сигурно сте се замислили, защо не добавихме .section класа и на бутоните. Те имат също такава външна и вътрешна рамка. Класът .section включва стилове за рамката (border и border-radius), но бутоните са доста и ако трябва да избираме дали да дописваме по един клас .section за всеки от тях, или да ги стилизираме „локално“ чрез класа на div елемента, който ги съдържа, то аз бих избрала второто.

Специални символи и знаци

В HTML математическите символи си имат кодови съответствия, с които се изписват. За калкулатора се налага да използваме тези:

code-signs

Разширена таблица с кодове можете да разгледате ТУК.

Input vs Button

Друг интересен въпрос е защо предпочитаме input елемента пред button, който има не по-лоши възможности? Отново лично предпочитание, можете спокойно да работите и с button. Избягват го главно заради проблемите с IE6, но в случая ние не правим уеб страницата ни да се отваря с този вече умиращ браузър.

Можете да прегледате също и дискусията в StackOverflow по темата.

ЧАСТ 4: Структуриране на CSS файла

Advertisements

11 responses to “Windows calculator с HTML5 и CSS3 (3)

  1. Ех, ако бях погледнала преди малко, щях да съм си изпратила и това домашно. Статията е супер!

  2. Добре де, защо това от точка 7 не е да речем елемент от тип (примерно). Всички елементи имат един и същи стил, а само „0“ и „=“ имат друг стил, съответно за „0“ различна ширина, а за „=“ височина и флоат в дясно, за да може следващите елементи да се позиционират точно както е на картинката. Имат си общ родител и само за двата различни бутона има по един клас. Спестява се доста от към хтмл структура.

  3. Прав си, че HTML структурата може още да се опрости: просто изреждане на div елементи с инпути вътре. Направих го и след малко ще го отразя и в статията. Достатъчно е да се даде десен флоут на „=“ и поместването му по-напред, вместо като последен бутон. Това премахва нуждата от разделянето на бутоните на групи.
    За стиловете обаче, там има още разлики:
    – в размера на цифрите, знака + и *
    – редът горе вдясно (бутоните MC, MR, MS, M+, M-) е с различен фон,
    – има неактивни бутони, които са с по-светла рамка и по-светъл фон
    Всички тези промени трябва да се хванат по някакъв начин в стиловете, за мен е по-удобно с класове, вместо да хващам input-ите по name атрибута им. Ако имаш по-добро предложение, ще се радвам да споделиш. Благодаря ти за включването! 🙂

  4. Идеята ми е следната: правиш си един и същи стил за всички инпути, само тези които искаш да са различни, им слагаш клас със съответния стил, не е удачно да засичаш name-а . За структурата имах предвид това:

    code …..

  5. Нещо се случва с кода, който си пратил, не се вижда. Ако искаш, дай линк към него в http://jsfiddle.net, http://jsbin.com или друго такова място. Бутоните ползват еднакъв стил, допълнителните класове са точно за различията. Можеш да го видиш и в самия код: http://jsbin.com/ifezik/2

  6. Като гледам кода ти, мога да кажа следното: Защо имаш обграден всеки инпут с див? Какъв е смисъл? 🙂 Просто в .buttons изсипи всички инпути и на тях сложи класове(на тези които са различни). Какъв в смисъла от див-а обграждащ .system .section ? Може и без тях 🙂

  7. Аха, да, обаче това е нещо друго от предното, за което си говорихме. 🙂
    Смисъл от div-ове около полетата .system и .data-types няма. По този въпрос имаме съгласие. Но за дивчетата около инпутите, както съм отбелязала и по-горе, поясненията са по структурирането на CSS файла, което обаче не съм публикувала все още.
    В аванс ти отговарям: на input-ите не може да се приложи псевдо-елементът :before, който е нужен при изграждането на двойния бордър. Затова се налага да ползвам div-ове. Както можеш да видиш, те носят определени класове със стилове към тях. 🙂
    Предложи как по друг начин да се реализира двойният бордър, без да се слагат div-ове.

  8. Вместо да се прави двоен бордър, не може ли да се направи бял бордър и бокс шадоу за да стане тъмната рамка ест е подходящи свойства 🙂

  9. Ами, давай да пробваме! 🙂 Аз де, ти явно си го пробвал вече.
    Ще обнародвам по-късно ъпгрейдите, ако паснат нещата.

Вашият коментар

Попълнете полетата по-долу или кликнете върху икона, за да влезете:

WordPress.com лого

You are commenting using your WordPress.com account. Log Out / Промяна )

Twitter picture

You are commenting using your Twitter account. Log Out / Промяна )

Facebook photo

You are commenting using your Facebook account. Log Out / Промяна )

Google+ photo

You are commenting using your Google+ account. Log Out / Промяна )

Connecting to %s