Help us understand the problem. What is going on with this article?

CSSで運転席を再現してみた。

More than 3 years have passed since last update.

driver_view.png

メーター
meter.png

たまには無機質なモノもいい。

html

html
<div class="driver-view">
  <!-- フロントガラス -->
  <div class="windshield"></div>
  <div class="car">
    <!-- ワイパー操作 -->
    <input type="checkbox" id="wiper-switch">
    <label class="toggle-switch" for="wiper-switch"></label>
    <!-- ワイパー -->
    <div class="wiper1"></div>
    <div class="wiper2"></div>
    <!-- ルームミラー -->
    <div class="room-mirror"></div>
    <!-- センタークラスター -->
    <div class="center-cluster">
      <div class="hazard">
        <div class="triangle"></div>    
      </div>
      <div class="air-panel1">
        <div class="filter"></div>
      </div>
      <div class="air-panel2">
        <div class="filter"></div>
      </div>
      <div class="nav">
        <div class="arrow"></div>
        <div class="road"></div>
      </div>
    </div>
    <!-- ハンドル -->
    <div class="handle">
      <div class="horn"></div>
    </div>
    <!-- メーター -->
    <div class="meters">
      <div class="speed-meter">
        <div class="pointer"></div>
        <span>0</span>
        <span>20</span>
        <span>40</span>
        <span>60</span>
        <span>80</span>
        <span>100</span>
        <span>120</span>
        <span>140</span>
        <span>160</span>
        <span>180</span>
      </div>
      <!-- タコメーター -->
      <div class="tacho-meter">
        <div class="pointer"></div>
        <span>0</span>
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
        <span>6</span>
        <span>7</span>
        <span>8</span>
        <span>9</span>
      </div>
      <!-- 燃料メーター -->
      <div class="fuel-meter">
        <div class="pointer"></div>
        <span>F</span>
        <span>E</span>
      </div>
    </div>
  </div>
</div>

CSS

css
html,body{
  width: 100%;
  height: 100%;
  margin: 0;
}

/* 運転席 */
.driver-view{
  position: absolute;
  width: 100%;
  height: 100%;
  background: #000;
  -webkit-perspective: 200;
}

.windshield{
  position: absolute;
  width: 100%;
  height: 65%;
  border-top: 30px solid #000;
  border-right: 50px solid #000;
  border-bottom: 10px solid #000;
  border-left: 50px solid #000;
  border-radius: 15% 15% 10% 10%;
  background: skyblue;
  box-sizing: border-box;
  transform: rotateX(-3deg);
  -webkit-perspective: 300;
  box-shadow: 
    0 0 0 3px #eee inset,
    0 -5px 0 3px #eee inset,;
}

.car{
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.wiper1,.wiper2{
  position: absolute;
  top: 460px;
  width: 35%;
  height: 15px;
  border-radius: 50% 30% 0 20%;
  background: #000;
  transform-origin: right top;
  transform: rotate(6deg);
}

.wiper1{
  left: 140px;
}

.wiper2{
  left: 335px;
}

#wiper-switch{
  display: none;
}

.toggle-switch{
  position: absolute;
  top: 70%;
  left: 64%;
  width: 30px;
  height: 200px;
  border-radius: 35% 15% 0 0;
  background: #464845;
  transform: rotate(-70deg);
}

.room-mirror{
  position: absolute;
  top: 1%;
  left: 50%;
  width: 300px;
  height: 65px;
  border-radius: 10%;
  background: skyblue;
  box-shadow: 0 0 10px 5px #303B3D inset;
  transform: translateX(-50%);
}

/* センタークラスター */
.center-cluster{
  position: absolute;
  top: 65%;
  left: 48%;
  width: 180px;
  height: 250px;
  transform: rotateX(2deg) translateX(-50%);
}

.hazard{
  position: absolute;
  top: 10px;
  left: 50%;
  width: 0;
  height: 0;
  border: 10px solid transparent;
  border-bottom: 20px solid red;
  transform: translateX(-50%);
}

.hazard .triangle{
  position: absolute;
  left: -5px;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  border-bottom: 13px solid #fff;
}


/* 空調パネル */
.air-panel1,.air-panel2{
  position: absolute;
  top: 10px;
  width: 60px;
  height: 40px;
  border: 3px solid #303B3D;
  border-radius: 25%;
  transform: rotateX(15deg);
}

.air-panel1{
  left: 5px; 
}

.air-panel2{
  right: 5px; 
}

/* フィルター */
.filter{
  position: absolute;
  top: 10px;
  width: 100%;
  height: 3px;
  border-radius: 50% 50% 0 0;
  background: #303B3D;
  box-shadow: 
    0 10px 0 0 #303B3D,
    0 20px 0 0 #303B3D;
}

.nav{
  position: absolute;
  top: 70px;
  left: 10px;
  width: 160px;
  height: 100px;
  border: 2px solid #eee;
  transform: rotateX(-15deg);
  box-sizing: border-box;
}

.nav .road{
  position: absolute;
  left: 50%;
  width: 10px;
  height: 100%;
  background: #fff;
  transform: translateX(-50%);
  z-index: 1;
}

.nav .arrow{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border: 10px solid transparent;
  border-bottom: 20px solid red;
  box-sizing: border-box;
  transform: translateX(-50%);
  z-index: 2;
}

.handle{
  position: absolute;
  top: 60%;
  left: 60%;
  width: 450px;
  height: 450px;
  border: 30px solid #89827A;
  border-radius: 100%;
  box-sizing: border-box;
  z-index: 3;
}

.horn{
  position: absolute;
  top: 25%;
  left: 25%;
  width: 200px;
  height: 150px;
  border-radius: 50% 50% 20% 20%;
  background: #89827A;
}

.horn:before{
  position: absolute;
  top: 25px;
  left: -103px;
  content: "";
  width: 400px;
  height: 45px;
  border-radius: 50% 50% 0 0;
  background: #89827A;
}

/* メーター全体 */
.meters{
  position: absolute;
  top: 68%;
  left: 73%;
  transform: scale(0.65);
  z-index: 1;
}

.speed-meter,.tacho-meter{
  position: absolute;
  margin: 0 auto;
  width: 150px;
  height: 150px;
  border: 1px solid transparent;
  border-top: 1px solid #FFD022;
  border-right: 1px solid #FFD022;
  border-left: 1px solid #FFD022;
  border-radius: 100%;
  background: #070604;
  box-sizing: border-box;
}

.speed-meter{
  left: -80px;
  z-index: 2;
}

.tacho-meter{
  left: 80px;
  z-index: 2;
}

.fuel-meter{
  position: absolute;
  top: 50px;
  left: -150px;
  width: 80px;
  height: 80px;
  border-top: 1px solid #FFD022;
  border-right: 1px solid #FFD022;
  border-radius: 100%;
  box-sizing: border-box;
  transform: rotate(45deg);
  z-index: 1;
}

.pointer{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border: 2px solid transparent;
  border-right: 70px solid #A01811;
  transform-origin: left top;
  transform: rotate(-30deg) translateX(-50%) translate(-50%,-50%);
}

.speed-meter .pointer{
  transform: rotate(75deg) translateX(-50%) translate(-50%,-50%);
}

.tacho-meter .pointer{
  transform: rotate(65deg) translateX(-50%) translate(-50%,-50%);
}

.fuel-meter .pointer{
  border: 2px solid transparent;
  border-right: 40px solid #A01811;
  transform: rotate(60deg) translateX(-40%) translate(-50%,-50%);
}

/* class名が'meter'で終わる要素 */
div[class$="meter"] span{
  position: absolute;
  left: 50%;
  top: 50%;
  color: #FFD022;
  font-size: 0.8em;
  line-height: 0.1em;
  text-align: center;
  transform-origin: left top;
}

.speed-meter span:nth-of-type(1){
  transform: rotate(-120deg) translate(0, -55px) rotate(120deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(2){
  transform: rotate(-95deg) translate(0, -55px) rotate(95deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(3){
  transform: rotate(-70deg) translate(0, -55px) rotate(70deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(4){
  transform: rotate(-45deg) translate(0, -55px) rotate(45deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(5){
  transform: rotate(-15deg) translate(0, -55px) rotate(15deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(6){
  transform: rotate(15deg) translate(0, -55px) rotate(-15deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(7){
  transform: rotate(45deg) translate(0, -55px) rotate(-45deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(8){
  transform: rotate(70deg) translate(0, -55px) rotate(-70deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(9){
  transform: rotate(95deg) translate(0, -55px) rotate(-95deg) translate(-50%,-50%); 
}
.speed-meter span:nth-of-type(10){
  transform: rotate(120deg) translate(0, -55px) rotate(-120deg) translate(-50%,-50%); 
}

.tacho-meter span:nth-of-type(1){
  transform: rotate(-120deg) translate(0, -55px) rotate(120deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(2){
  transform: rotate(-95deg) translate(0, -55px) rotate(95deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(3){
  transform: rotate(-70deg) translate(0, -55px) rotate(70deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(4){
  transform: rotate(-45deg) translate(0, -55px) rotate(45deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(5){
  transform: rotate(-15deg) translate(0, -55px) rotate(15deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(6){
  transform: rotate(15deg) translate(0, -55px) rotate(-15deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(7){
  transform: rotate(45deg) translate(0, -55px) rotate(-45deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(8){
  transform: rotate(70deg) translate(0, -55px) rotate(-70deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(9){
  transform: rotate(95deg) translate(0, -55px) rotate(-95deg) translate(-50%,-50%); 
}
.tacho-meter span:nth-of-type(10){
  transform: rotate(120deg) translate(0, -55px) rotate(-120deg) translate(-50%,-50%); 
}

.fuel-meter span:nth-of-type(1){
  transform: rotate(-45deg) translate(10px,-30px) translate(-50%,-50%); 
}
.fuel-meter span:nth-of-type(2){
  transform: rotate(-45deg) translate(10px,30px) translate(-50%,-50%); 
}

アニメーション

簡単なアニメーションも作りました。

/* チェックされたらアニメーション起動 */
#wiper-switch:checked ~ .wiper1,
#wiper-switch:checked ~ .wiper2{
  animation: wiper 1.5s ease-in-out infinite alternate;
}


.speed-meter .pointer{
  animation: _meter 4s ease-in-out infinite alternate;
}

@keyframes _meter{
  from{
    transform: rotate(75deg) translateX(-50%) translate(-50%,-50%);
  }

  to{
    transform: rotate(85deg) translateX(-50%) translate(-50%,-50%);
  }
}


@keyframes wiper{
  from{
    transform: rotate(5deg);
  }

  to{
    transform: rotate(170deg);
  }
}


wiperGif.gif

perspectiveについて

perspectiveは奥行き(遠近感)の表現ができます。

詳しく下記参照
perspective - CSS | MDN

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away