Nội dung bài viết

Gần như mọi website doanh nghiệp ở Việt Nam đều cần một khối liên hệ nhanh: gọi điện, Zalo, Messenger, chỉ đường. Nhiều người cài hẳn một plugin cho việc này, trong khi nó chỉ cần HTML và CSS thuần, không một dòng JavaScript.

Đây là bản tôi dùng đi dùng lại cho nhiều dự án.

Cấu trúc HTML

<div class="quick-contact">
  <ul>
    <li>
      <a href="https://goo.gl/maps/xxxxx" rel="nofollow" target="_blank">
        <i class="ticon-heart"></i>Tìm đường
      </a>
    </li>
    <li>
      <a href="https://zalo.me/0123456789" rel="nofollow" target="_blank">
        <i class="ticon-zalo-circle2"></i>Chat Zalo
      </a>
    </li>
    <li class="phone-mobile">
      <a href="tel:0123456789" rel="nofollow" class="button">
        <span class="phone_animation animation-shadow">
          <i class="icon-phone-w" aria-hidden="true"></i>
        </span>
        <span class="btn_phone_txt">Gọi điện</span>
      </a>
    </li>
    <li>
      <a href="https://www.messenger.com/t/username" rel="nofollow" target="_blank">
        <i class="ticon-messenger"></i>Messenger
      </a>
    </li>
    <li>
      <a href="sms:0123456789" class="chat_animation">
        <i class="ticon-chat-sms" aria-hidden="true"></i>Nhắn tin SMS
      </a>
    </li>
    <li class="to-top-pc">
      <a href="#" rel="nofollow">
        <i class="ticon-angle-up" aria-hidden="true"></i>
      </a>
    </li>
  </ul>
</div>

Vài điểm đáng chú ý trong phần HTML:

  • href="tel:..."href="sms:..." là giao thức chuẩn, điện thoại sẽ tự mở ứng dụng gọi hoặc nhắn tin. Trên desktop chúng thường không làm gì, nên mục gọi điện được gắn class phone-mobile để chỉ hiện trên di động.
  • rel="nofollow" báo cho công cụ tìm kiếm không truyền giá trị liên kết sang các tên miền ngoài.
  • Dùng thẻ <ul> chứ không phải một đống <div>, vì đây thực sự là một danh sách liên kết. Trình đọc màn hình sẽ đọc được số lượng mục.

CSS cho desktop

Khối liên hệ được ghim cố định ở cạnh trái màn hình:

.quick-contact {
  position: fixed;
  left: 13px;
  bottom: 50px;
  z-index: 150;
  width: auto;
  padding: 10px 0;
  background: #fff;
  border: 1px solid #f2f2f2;
  border-radius: 5px;
}

.quick-contact ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.quick-contact ul > li a {
  display: block;
  padding: 3px;
  border: none;
  border-radius: 5px;
  text-align: center;
  text-decoration: none;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  color: #515151;
  max-width: 72px;
}

.quick-contact ul > li a i {
  display: block;
  width: 33px;
  height: 33px;
  margin: auto;
}

/* Mục SMS chỉ dành cho di động */
.quick-contact ul > li .chat_animation {
  display: none;
}

Icon được nạp bằng ảnh nền, mỗi loại một class:

.quick-contact ul > li a i.ticon-zalo-circle2 {
  display: block;
  width: 36px;
  height: 36px;
  background: url(/images/icon-zalo.png) no-repeat;
  background-size: contain;
}

.quick-contact ul > li a i.ticon-messenger {
  display: block;
  width: 36px;
  height: 36px;
  background: url(/images/icon-messenger.png) no-repeat;
  background-size: contain;
}

Bản gốc của tôi trỏ icon sang Imgur cho tiện. Nếu bạn dùng thật thì nên tải ảnh về đặt trong thư mục của mình: dịch vụ chia sẻ ảnh miễn phí có thể đổi chính sách hoặc xóa ảnh bất cứ lúc nào, và mỗi icon là thêm một lần kết nối tới tên miền lạ.

Chuyển thành thanh dưới đáy trên di động

Đây là phần thú vị nhất. Trên màn hình hẹp, khối dọc bên trái sẽ che mất nội dung, nên nó được biến thành một thanh ngang chạy hết chiều rộng ở đáy màn hình:

@media only screen and (max-width: 600px) {
  .quick-contact {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 60px;
    padding: 5px;
    margin: 0;
    border-radius: 0;
    background: #fff;
    box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.3);
    z-index: 999;
  }

  .quick-contact li {
    float: left;
    width: 20%;
    height: 50px;
    list-style: none;
  }

  .quick-contact ul > li a {
    padding: 0;
    margin: 0 auto;
  }

  /* Hiện mục gọi điện và SMS, vốn bị ẩn trên desktop */
  .phone-mobile {
    display: block !important;
  }

  .quick-contact li .chat_animation {
    display: block !important;
  }

  /* Nút gọi điện nổi lên giữa thanh */
  .quick-contact li .button .phone_animation {
    position: absolute;
    top: -16px;
    left: 50%;
    transform: translate(-50%, 0);
    width: 50px;
    height: 50px;
    border: 2px solid #fff;
    border-radius: 100%;
    background: #6cb917;
    box-shadow: none;
  }
}

width: 20% chia đều 5 mục hiển thị trên di động. Nếu bạn thêm hoặc bớt mục thì phải sửa lại con số này, hoặc thay float bằng flexbox để nó tự chia:

.quick-contact ul {
  display: flex;
}
.quick-contact li {
  flex: 1;
}

Cách dùng flex gọn hơn và không cần tính phần trăm bằng tay. Bản gốc dùng float vì hồi đó còn phải hỗ trợ trình duyệt cũ, giờ thì không cần nữa.

Vài điểm nên cải thiện

Nếu triển khai lại từ đầu, tôi sẽ sửa mấy chỗ sau:

Thêm nhãn cho trình đọc màn hình. Các thẻ <i> chỉ là ảnh nền, người dùng trình đọc màn hình không biết đó là gì. Mục “Quay lên trên” hiện chỉ có icon mà không có chữ:

<a href="#" rel="nofollow" aria-label="Quay lên đầu trang">
  <i class="ticon-angle-up" aria-hidden="true"></i>
</a>

Chừa chỗ cho thanh ở đáy. Thanh cố định trên di động sẽ che mất phần cuối trang. Thêm padding vào body để nội dung không bị khuất:

@media only screen and (max-width: 600px) {
  body {
    padding-bottom: 60px;
  }
}

Dùng biến CSS cho màu. Nếu định dùng lại widget này cho nhiều dự án, tách màu ra biến sẽ đỡ phải tìm và thay thủ công:

.quick-contact {
  --qc-bg: #fff;
  --qc-text: #515151;
  --qc-accent: #6cb917;
}

Không cần JavaScript, không cần plugin, và toàn bộ chỉ nặng vài KB.