Hướng dẫn thiết kế blogspot căn bản - thiết kế header đầu trang

Hướng dẫn thiết kế blogspot từng bước thiết kế header đầu trang gồm tiêu đề trang, hộp tìm kiếm trang web, dropdown menu, thêm các tiện ích widget, thiết kế giao diện hiển thị, Javascript đóng mở menu trên thiết bị di động

Về cơ bản bố cục element của một trang được chia thành ba element chính header, main và footer theo thứ tự từ trên xuống dưới. Từ các element chính này lại chia bố cục các element con để tạo thành một trang. Đấy là mình nói thế 😁 còn thực tế các bạn nên tham khảo những trang web lớn dạy thiết kế có uy tín.

Bài hôm nay mình hướng dẫn các bạn tự thiết kế phần header trong blogspot, nhưng trước tiên các bạn cần có một theme với những yêu cầu tối thiểu của mẫu chủ đề xml trong blogspot trước, mình khuyên các bạn nên sử dụng theme trắng để thiết kế không nên sử dụng các theme đã tùy biến rồi vì rất khó triển khai sau này.

Quan trọng: Blog đã có sẵn data bài viết, danh sách label, các trang tĩnh vì nếu thiếu các yêu cầu này thì các tiện ích Nhãn, Tiện ích Trang không hiển thị vì blog không lưu trữ data.

Theme blogspot chuẩn seo - themeblogspot.com
Giao diện header đầu trang

Nếu bạn muốn tạo header như hướng dẫn của bài này thì xem demo trang theme blogspot của mình trước còn không chỉ đọc tham khảo.

Tạo header

Header bao gồm ba phần chính cũng là các tiện ích widget:

  • Tiêu đề blog hoặc logo: Tiện ích Tiêu đề Trang
  • Hộp tìm kiếm: Tiện ích Tìm kiếm blog, Tiện ích HTML
  • Menu: Tiện ích Nhãn, Tiện ích Trang, Tiện ích Danh sách Liên kết, Tiện ích HTML

Để thêm được tiện ích ngoài Bố cục, cần tạo các <b:section> trước. Mình sẽ tạo 2 <b:section> chứa các tiện ích:

  • Bên trái: Tiện ích Tiêu đề Trang, Tiện ích Tìm kiếm blog, Tiện ích HTML
  • Bên phải: Tiện ích Nhãn, Tiện ích Trang, Tiện ích Danh sách Liên kết, Tiện ích HTML

Tham khảo thêm: Tìm hiểu các thuộc tính có trong thẻ b:section

Ngay bên dưới thẻ <body> trong theme, mình sẽ chèn như sau:

<header>
  <div class='main-container'>
    <b:section class='header' id='header' showaddelement='true'/>
    <b:section class='menu' id='menu' showaddelement='true'/>
  </div>
</header>

Lưu chủ đề lại tiếp theo chuyển đến phần cài đặt Bố cục, tại đây các bạn thêm các tiện ích bên trái và bên phải

Hướng dẫn thiết kế blogspot căn bản - thiết kế header đầu trang
Bên trái: Tiện ích Tiêu đề Trang, Tiện ích Tìm kiếm blog, Tiện ích HTML, Bên phải: Các Tiện ích Nhãn, Tiện ích Trang, Tiện ích HTML

Cấu hình cài đặt tiện ích:

Tiện ích Tiêu đề Trang

Chèn logo và tích chọn Đặt mô tả sau hình ảnh
Chèn logo và tích chọn Đặt mô tả sau hình ảnh

Tiện ích Nhãn

Hướng dẫn thiết kế blogspot căn bản - thiết kế header đầu trang
Chọn Nhãn đã chọn như hình

Tiện ích Trang

Hướng dẫn thiết kế blogspot căn bản - thiết kế header đầu trang
Chọn Trang để hiển thị

Khi đã thêm và cấu hình các tiện ích, vào chỉnh sửa HTML Chủ đề chọn Chuyển đến tiện ích

Hướng dẫn thiết kế blogspot căn bản - thiết kế header đầu trang
Nhấp chọn vào tên Tiện ích cần chỉnh sửa

Lưu ý: Mã XML của mỗi tiện ích bắt đầu bằng <b:widget> và kết thúc bằng </b:widget>

Các bạn thay lại toàn bộ tiện ích Header có id='Header1' thành như sau:

<b:widget id='Header1' locked='true' title='' type='Header' version='2' visible='true'>
  <b:widget-settings>
    <b:widget-setting name='displayUrl'>https://cdn.jsdelivr.net/gh/thietkeblogspot/images/logo.png</b:widget-setting>
    <b:widget-setting name='displayHeight'>32</b:widget-setting>
    <b:widget-setting name='sectionWidth'>389</b:widget-setting>
    <b:widget-setting name='useImage'>true</b:widget-setting>
    <b:widget-setting name='shrinkToFit'>false</b:widget-setting>
    <b:widget-setting name='imagePlacement'>BEFORE_DESCRIPTION</b:widget-setting>
    <b:widget-setting name='displayWidth'>32</b:widget-setting>
  </b:widget-settings>
    <b:includable id='main' var='this'>
    <b:attr name='id' value=''/>
    <b:attr name='data-version' value=''/>
    <div class='header-widget'>
      <b:if cond='data:view.isMultipleItems and !data:view.search.label and !data:blog.searchQuery'>
        <h1 class='hidden'><data:blog.title/></h1>
      </b:if>
      <b:include cond='data:imagePlacement in {&quot;REPLACE&quot;, &quot;BEFORE_DESCRIPTION&quot;}' name='image'/>
      <b:include cond='data:imagePlacement not in {&quot;REPLACE&quot;, &quot;BEFORE_DESCRIPTION&quot;}' name='title'/>
      <b:include cond='data:imagePlacement != &quot;REPLACE&quot;' name='description'/>
    </div>
    <b:include cond='data:imagePlacement == &quot;BEHIND&quot;' name='behindImageStyle'/>
  </b:includable>
  <b:includable id='behindImageStyle'>
    <b:if cond='data:sourceUrl'>
      <b:include cond='data:this.image' data='{image: data:this.image, selector: &quot;.header-widget&quot;}' name='responsiveImageStyle'/>
      <style type='text/css'>
       .header-widget {background-position: <data:blog.locale.languageAlignment/>;background-repeat:no-repeat;}
      </style>
    </b:if>
  </b:includable>
  <b:includable id='description'>
    <h2 class='hidden'><data:this.description/></h2>
  </b:includable>
  <b:includable id='image'>
    <a class='has-img' expr:href='data:blog.homepageUrl' expr:title='data:title'><img expr:alt='data:title' expr:height='data:height' expr:src='data:sourceUrl' expr:width='data:width'/></a>
  </b:includable>
  <b:includable id='title'>
    <a expr:href='data:blog.homepageUrl' expr:title='data:blog.title'><data:blog.title/></a>
  </b:includable>
</b:widget>

Thay lại tiện BlogSearch có id='BlogSearch1' thành như sau:

<b:widget id='BlogSearch1' locked='true' title='Tìm kiếm' type='BlogSearch' version='2' visible='true'>
  <b:includable id='main'>
    <b:attr name='class' value='widget web-search'/>
    <b:attr name='id' value=''/>
    <b:attr name='data-version' value=''/>
    <b:include name='content'/>
  </b:includable>
  <b:includable id='content'>
    <div>
      <b:include name='searchForm'/>
    </div>
  </b:includable>
  <b:includable id='searchForm'>
    <form expr:action='data:blog.searchUrl' method='get' role='search'>
      <b:include name='searchSubmit'/>
      <input autocomplete='off' autofocus='' expr:aria-label='data:messages.search' expr:placeholder='data:messages.search'  name='q' required='' spellcheck='false' type='search'/>
      <button aria-label='reset' class='reset hidden has-svg-icon' type='reset'/>
    </form>
  </b:includable>
  <b:includable id='searchSubmit'>
    <button class='submit has-svg-icon' expr:aria-label='data:messages.search' type='submit'/>
  </b:includable>
</b:widget>

Với tiện ích HTML có id='HTML1', các bạn chỉ cần thay lại toàn bộ code trong thẻ <b:includable id='main'> của tiện ích thành:

<b:attr name='class' value='nav-icon'/>
<b:attr name='id' value=''/>
<b:attr name='data-version' value=''/>
<button aria-expanded='false' aria-label='menu' aria-pressed='false' class='open has-svg-icon'/>

Làm tương tự với tiện ích HTML có id='HTML2'

<b:attr name='id' value=''/>
<b:attr name='data-version' value=''/>
<div class='title home'><a expr:href='data:blog.homepageUrl' expr:title='data:messages.home'><data:messages.home/></a></div>

Với các tiện ích Label, các bạn cần thay lại code xml trong 2 thẻ <b:includable>

+ Thẻ <b:includable id='main'>

<b:attr name='id' value=''/>
<b:attr name='data-version' value=''/>
<div class='title'><data:title/></div>
<b:include name='content'/>

+ Thẻ <b:includable id='list'>

<div class='dropdown'/>
<ul>
  <b:loop values='data:labels' var='label'>
    <li><a expr:href='data:label.url' expr:title='data:label.name'><data:label.name/></a></li>
  </b:loop>
</ul>

Với tiện ích PageList, các bạn thay lại code xml trong các thẻ <b:includable> sau:

+ Thẻ <b:includable id='main'>

<b:attr name='id' value=''/>
<b:attr name='data-version' value=''/>
<div class='title'><data:title/></div>
<b:include name='content'/>

+ Thẻ <b:includable id='content'>

<div class='widget-content'>
  <div class='dropdown'/>
  <b:include name='pageList'/>
</div>

+ Thẻ <b:includable id='pageLink'>

<li><a expr:href='data:link.href' expr:title='data:link.title'><data:link.title/></a></li>

+ Thẻ <b:includable id='pageList'>

<ul>
  <b:class cond='data:pageListClass' expr:name='data:pageListClass'/>
  <b:loop values='data:links' var='link'>
    <b:include name='pageLink'/>
  </b:loop>
</ul>

Giao diện cho header

<b:skin><![CDATA[
*{box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;text-rendering:geometricPrecision}
body,input,button{font-family:Roboto,Arial,sans-serif;font-size:1rem;-webkit-tap-highlight-color:rgba(0,0,0,0)}
.overlay{background:rgba(0,0,0,0.502);position:fixed;top:0;bottom:0;left:0;right:0;z-index:8}
.hidden{display:none}
.has-svg-icon:before{background-size:100%;content:"";display:inline-block;vertical-align:middle}
header{background:#fff;border-bottom:1px solid rgba(12,28,39,.15)}
header>.main-container{max-width:1920px;margin:0 auto;display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}
header>.main-container:after{content:"";display:table;clear:both}
header .header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;min-height:50px;height:100%;position:relative}
.header-widget a.has-img{display:flex;align-items:center;justify-content:center;border-radius:50%;height:48px;width:48px}
.header-widget img{height:32px;width:32px;vertical-align:middle;border-radius: 50%;}
.header-widget:hover a.has-img{background:rgba(60,64,67,0.08)}
.header-widget:focus a.has-img,.header .header-widget:active a.has-img{background:rgba(95,99,104,0.24)}
.web-search{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}
.web-search>div{line-height:30px;position:relative;width:100%}
.web-search form{background-color:#f5f8fa;position:relative;width:100%;border:1px solid #e6ecf0;-webkit-border-radius:21px;border-radius:21px}
.web-search input[type=search]{background:transparent;line-height:30px;font-size:15px;padding-left:40px;width:100%;color:#2d2d2d;border:0}
.web-search input[type=search]::-webkit-search-cancel-button{display:none}
.web-search button{width:40px;height:100%;border:0;background:transparent;position:absolute;top:0;padding:0}
.web-search button[type=reset]{right:0}
.web-search button[type=submit]:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' clip-rule='evenodd' fill-rule='evenodd' height='18px' viewBox='0 0 24 24' width='18px'%3E%3Cpath fill='hsl(0,0%25,53.3%25)' d='M15.853 16.56c-1.683 1.517-3.911 2.44-6.353 2.44-5.243 0-9.5-4.257-9.5-9.5s4.257-9.5 9.5-9.5 9.5 4.257 9.5 9.5c0 2.442-.923 4.67-2.44 6.353l7.44 7.44-.707.707-7.44-7.44zm-6.353-15.56c4.691 0 8.5 3.809 8.5 8.5s-3.809 8.5-8.5 8.5-8.5-3.809-8.5-8.5 3.809-8.5 8.5-8.5z'%3E%3C/path%3E%3C/svg%3E");width:18px;height:18px}
.web-search button[type=reset]::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px'%3E%3Cpath fill='hsl(0,0%25,53.3%25)' d='M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z'%3E%3C/path%3E%3C/svg%3E");width:24px;height:24px}
.web-search button:focus,.web-search input:focus,.web-search .results li:focus{outline:none!important}
.web-search .results-content{position:absolute;top:41px;height:100vh;z-index:9;width:100%}
.web-search.dropdown{overflow:hidden;position:absolute;display:block;width:28px;height:14px;top:-14px;left:15%;-ms-transform:translateX(-15%);transform:translateX(-15%)}
.web-search .dropdown::after{position:absolute;display:block;width:14px;height:14px;bottom:-7px;left:7px;background-color:#fff;border-radius:3px 0 0 0;box-shadow:0 0 10px rgba(0,0,0,0.2);-ms-transform:rotate(45deg);transform:rotate(45deg);content:""}
.web-search .searchresults-wrapper{background:#fff;box-shadow:0 1px 4px rgba(0,0,0,0.25);background-clip:padding-box;max-height:calc(100% - 50px);overflow-x:hidden;overflow-y:auto}
.web-search li{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:15px;line-height:36px}
.web-search li:not(.hidden){display:block}
.web-search li:before{content:"+";padding:0 17px 0 15px}
.web-search li:focus,.web-search .results li:active,.web-search .results li.active{background:#E4F0F6}
.web-search li:hover{background:#fff9e7}
.menu ul{list-style:none}
.menu a{color:#2d2d2d}
@media(min-width:1280px) and (max-width:1365px){
header>.main-container{padding:0 2%}
}
@media(min-width:1366px) and (max-width:1439px){
header>.main-container{padding:0 5%}
}
@media(min-width:861px){
body{padding-top:70px}
header{position:fixed;top:0;left:0;right:0;height:50px;z-index:9}
header .header{margin-right:auto}
.menu{display:flex;align-items:center;position:relative;margin-left:auto}
.menu .widget{line-height:50px;position:relative}
.menu .title{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#2d2d2d;display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 15px;position:relative;font-size:15px}
.menu .title>a{color:#2d2d2d}
.menu .title:hover{background:rgba(60,64,67,0.08)}
.menu .title:focus,.menu .title:active{background:rgba(95,99,104,0.24)}
.menu .widget-content{visibility:hidden;width:200px;position:absolute;z-index:9;top:50px;left:50%;background:#fff;border-radius:4px;box-shadow:0 2px 10px 0 rgba(0,0,0,0.3);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}
.menu .widget-content .dropdown{overflow:hidden;position:absolute;display:block;width:28px;height:14px;top:-14px;left:50%;-ms-transform:translateX(-50%);transform:translateX(-50%)}
.menu .widget-content .dropdown::after{position:absolute;display:block;width:14px;height:14px;bottom:-7px;left:7px;background-color:#fff;border-radius:3px 0 0 0;box-shadow:0 0 10px rgba(0,0,0,0.2);-ms-transform:rotate(45deg);transform:rotate(45deg);content:""}
.menu .widget:last-child .widget-content{left:unset;right:0;-ms-transform:unset;transform:unset}
.menu .widget:last-child .widget-content .dropdown{left:unset;right:5%}
.menu ul{list-style-type:none}
.menu li{line-height:20px;font-size:15px}
.menu li a{display:block;padding:10px 20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.menu li a:hover{background:#fff9e7}
.menu li a:focus,.menu li a:active{background:#E4F0F6}
.menu .widget:hover .widget-content{visibility:visible;animation:dropdown-show .3s ease forwards}
.menu .widget:last-child:hover .widget-content{animation:dropdown-last-show .3s ease forwards}
@keyframes dropdown-show{from{opacity:0;transform:translate(-50%,15px)}to{opacity:1;transform:translate(-50%,0)}}
@keyframes dropdown-last-show{from{opacity:0;transform:translate(0%,15px)}to{opacity:1;transform:translate(0%,0)}}
.nav-icon{display:none}
}
@media(min-width:1440px){
header>.main-container{padding:0 8%}
}
@media(max-width:1279px){
header>.main-container{padding:0 7px}
}
@media(max-width:860px){
header .header{width:100%}
header a,header a:hover{cursor:default!important}
.nav-icon{display:flex;margin-left:auto;justify-content:center;align-items:center}
.nav-icon button{background:transparent;padding:0;border:none;border-radius:50%;height:40px;width:40px}
.nav-icon button:hover{background:rgba(60,64,67,0.08)}
.nav-icon button:focus,.nav-icon button:active{background:rgba(95,99,104,0.24)}
header a:focus,.nav-icon button:focus{outline:none}
.nav-icon button:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px'%3E%3Cpath fill='hsl(0,0%25,53.3%25)' d='M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z'%3E%3C/path%3E%3C/svg%3E");width:24px;height:24px}
.menu{position:fixed;top:0;bottom:0;left:0;right:auto;background:#fafafa;z-index:30;line-height:20px;padding:0;width:280px;min-height:100%;overflow-y:auto;border-right:1px solid rgba(0,0,0,0.12);-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transition-timing-function:cubic-bezier(0,0,0.2,1);transition-timing-function:cubic-bezier(0,0,0.2,1)}
.menu.section{-webkit-transition-timing-function:cubic-bezier(0.4,0,0.6,1);transition-timing-function:cubic-bezier(0.4,0,0.6,1);-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%)}
.menu>.widget{border-bottom:1px solid rgba(0,0,0,0.12)}
.menu .title,.menu .home>a,.menu li>a{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.menu .title:not(.home),.menu li>a{line-height:40px}
.menu .title:not(.home){padding:0 15px;font-size:14px;font-weight:400;color:rgba(0,0,0,0.54);cursor:default}
.menu li>a{padding:0 15px 0 25px}
.menu .home{height:50px}
.menu .home>a{padding:0 15px;line-height:50px}
.menu .home>a,.menu li>a{font-size:15px}
}
]]></b:skin>

<b:if cond='data:view.isLayoutMode'>
  <b:template-skin><![CDATA[
    body#layout #header,body#layout #menu{width:44.5%}
    body#layout #header{float:left}
    body#layout #menu{float:right}
  ]]></b:template-skin>
</b:if>

Javascript đóng mở menu trên màn hình có kích thước nhỏ

Chèn trước thẻ đóng </body>

<script>//<![CDATA[
window.addEventListener('load',function(){
  const menu=document.querySelector('.menu'),
    button=document.querySelector('.header button.open'),
    input=document.querySelector('.web-search input'),
    reset=document.querySelector('.web-search .reset'),
    overlay=document.querySelector('.overlay')
  button.addEventListener('click',function(e){
    e.stopPropagation()
    button.setAttribute('aria-expanded','true')
    button.setAttribute('aria-pressed','true')
    overlay.classList.remove('hidden')
    menu.classList.remove('section')
  })
  menu.addEventListener('click',function(e){
    e.stopPropagation()
  })
  overlay.addEventListener('click',function(e){
    button.setAttribute('aria-expanded','false')
    button.setAttribute('aria-pressed','false')
    overlay.classList.add('hidden')
    menu.classList.add('section')
  })
  input.addEventListener('input',function(e){
    reset.classList.remove('hidden')
  })
  reset.addEventListener('click',function(e){
    reset.classList.add('hidden')
  })
})
//]]></script>

Thêm đánh giá

1 bình luận