Kalkulator w przeglądarce z JavaScript

Pokażę jak to dzięki pomocy jednej funkcji JavaScript – eval() i podstawowej znajomości HTML, CSS i JavaScript można zbudować kalkulator w przeglądarce internetowej.

Od prostej wersji z obliczeniami w konsoli:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Calculator</title>
</head>

<body>
  <p>
    <button onclick="
      calculation +='1';
      console.log(calculation);
      ">
      1
    </button>
    <button onclick="
    calculation +='2';
    console.log(calculation);
    ">
      2
    </button>
    <button onclick="
    calculation +='3';
    console.log(calculation);
    ">
      3
    </button>
    <button onclick="
    calculation += ' + ';
    ">
      +
    </button>
  </p>
  <p>
    <button onclick="
      calculation +='4';
      console.log(calculation);
      ">
      4
    </button>
    <button onclick="
      calculation +='5';
      console.log(calculation);
      ">
      5
    </button>
    <button onclick="
      calculation +='6';
      console.log(calculation);
      ">
      6
    </button>
    <button onclick="
      calculation += ' - ';
      ">
      -
    </button>
  </p>
  <p>
    <button onclick="
      calculation +='7';
      console.log(calculation);
      ">
      7
    </button>
    <button onclick="
      calculation +='8';
      console.log(calculation);
      ">
      8
    </button>
    <button onclick="
      calculation +='9';
      console.log(calculation);
      ">
      9
    </button>
    <button onclick="
      calculation += ' * ';
      ">
      *
    </button>
  </p>
  <p>
    <button onclick="
    calculation +='0';
    console.log(calculation);
    ">
      0
    </button>
    <button onclick="
calculation += '.';
">
      .
    </button>

    <button onclick="
    calculation = eval(calculation);
    console.log(calculation);
    ">
      =
    </button>

    <button onclick="
      calculation += ' / ';
      ">
      /
    </button>
  </p>
  <p>
    <button onclick="
    calculation = '';
    console.log(0);
    ">
      Clear
    </button>
  </p>

  <script>
    let calculation = "";
  </script>
</body>

</html>

 

 

Z dodaniem domyślnych stylów i animacji z Bootstrap-a:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculator</title>
  <!-- Add Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    .calc-button {
      width: 60px;
      height: 60px;
      margin: 5px;
    }

    .display {
      font-size: 2rem;
      margin-bottom: 20px;
      text-align: right;
      padding: 10px;
    }
  </style>
</head>

<body class="bg-light">

  <div class="container mt-5">
    <div class="row justify-content-center">
      <div class="col-md-4">
        <div class="card p-3 shadow">
          <div class="display bg-white border rounded" id="display">0</div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
            <button class="btn btn-success calc-button" onclick="calculate()">=</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
          </div>

          <div class="d-flex justify-content-center">
            <button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Add Bootstrap JS -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

  <script>
    let calculation = '';

    function updateCalculation(value) {
      calculation += value;
      document.getElementById('display').innerText = calculation;
    }

    function calculate() {
      try {
        calculation = eval(calculation);
        document.getElementById('display').innerText = calculation;
      } catch (e) {
        document.getElementById('display').innerText = 'Error';
      }
    }

    function clearCalculation() {
      calculation = '';
      document.getElementById('display').innerText = '0';
    }
  </script>
</body>

</html>

 

Później dodaniem więcej animacji korzystając z biblioteki jQuery:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculator</title>

  <!-- Add Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- Add jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <!-- Add jQuery UI for animations -->
  <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

  <style>
    .calc-button {
      width: 70px;
      height: 70px;
      margin: 8px;
      font-size: 1.5rem;
    }

    .display {
      font-size: 2.5rem;
      margin-bottom: 20px;
      text-align: right;
      padding: 15px;
      background-color: #f8f9fa;
    }

    .container {
      margin-top: 50px;
    }

    .btn-primary,
    .btn-warning,
    .btn-danger,
    .btn-success {
      transition: transform 0.1s ease;
    }
  </style>
</head>

<body class="bg-light">

  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-4">
        <div class="card p-4 shadow-lg rounded">
          <div class="display border rounded" id="display">0</div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
          </div>

          <div class="d-flex justify-content-between">
            <button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
            <button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
            <button class="btn btn-success calc-button" onclick="calculate()">=</button>
            <button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
          </div>

          <div class="d-flex justify-content-center">
            <button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Add Bootstrap JS -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

  <script>
    let calculation = '';

    function updateCalculation(value) {
      // Add animations for button press
      animateButton(value);

      calculation += value;
      $("#display").text(calculation);
    }

    function calculate() {
      try {
        calculation = eval(calculation);
        $("#display").text(calculation).effect("bounce", { times: 3 }, 500);
      } catch (e) {
        $("#display").text('Error').effect("shake", { times: 3 }, 500);
      }
    }

    function clearCalculation() {
      calculation = '';
      $("#display").text('0').fadeOut(100).fadeIn(100);
    }

    // Add animation for button clicks
    function animateButton(value) {
      $(".btn").each(function () {
        if ($(this).text() === value) {
          $(this).addClass("pressed");
          $(this).css("transform", "scale(0.95)");
          setTimeout(() => {
            $(this).css("transform", "scale(1)");
          }, 100);
        }
      });
    }

    // Animation for button press style
    $(".btn").on("mousedown", function () {
      $(this).css("transform", "scale(0.95)");
    });
    $(".btn").on("mouseup", function () {
      $(this).css("transform", "scale(1)");
    });
  </script>

</body>

</html>

 

Kończąc na kalkulatorze z motywem prosto z Matrix-a:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Matrix Calculator</title>

  <style>
    body,
    html {
      margin: 0;
      padding: 0;
      height: 100%;
      background-color: #000;
      color: #00ff00;
      font-family: 'Courier New', monospace;
      overflow: hidden;
    }

    #matrix-bg {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
      pointer-events: none;
    }

    .matrix-column {
      position: absolute;
      top: -50px;
      font-size: 14px;
      line-height: 1.5;
    }

    .container {
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      z-index: 2;
    }

    .calculator {
      background-color: rgba(0, 20, 0, 0.8);
      border: 2px solid #00ff00;
      border-radius: 10px;
      padding: 20px;
      box-shadow: 0 0 20px #00ff00;
      transition: all 0.5s ease;
    }

    .calculator:hover {
      transform: scale(1.05);
      box-shadow: 0 0 30px #00ff00;
    }

    .display {
      width: 240px;
      height: 60px;
      margin-bottom: 20px;
      text-align: right;
      padding: 15px;
      background-color: #001400;
      color: #00ff00;
      border-radius: 5px;
      border: 1px solid #00ff00;
      text-shadow: 0 0 5px #00ff00;
      transition: all 0.5s ease;
      overflow-x: scroll;
      overflow-y: hidden;
      white-space: nowrap;
      font-size: 2.5rem;
      display: flexbox;
      align-items: center;
      justify-content: flex-end;
      cursor: text;
      user-select: text;
    }

    .display-content {
      transition: all 0.3s ease;
    }

    .display.animate .display-content {
      animation: pulse 0.5s;
    }

    @keyframes pulse {
      0% {
        transform: scale(1);
      }

      50% {
        transform: scale(1.1);
      }

      100% {
        transform: scale(1);
      }
    }

    .btn {
      width: 60px;
      height: 60px;
      margin: 5px;
      font-size: 1.2rem;
      background-color: #001400;
      color: #00ff00;
      border: 1px solid #00ff00;
      border-radius: 5px;
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }

    .btn::before {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      width: 0;
      height: 0;
      background-color: rgba(0, 255, 0, 0.5);
      border-radius: 50%;
      transform: translate(-50%, -50%);
      transition: width 0.6s ease, height 0.6s ease;
    }

    .btn:hover {
      color: #000;
      box-shadow: 0 0 15px #00ff00;
    }

    .btn:hover::before {
      width: 200%;
      height: 200%;
    }

    .btn:active {
      transform: scale(0.95);
      box-shadow: 0 0 5px #00ff00;
    }

    .btn span {
      position: relative;
      z-index: 1;
    }

    @keyframes glowPulse {
      0% {
        box-shadow: 0 0 5px #00ff00;
      }

      50% {
        box-shadow: 0 0 20px #00ff00;
      }

      100% {
        box-shadow: 0 0 5px #00ff00;
      }
    }

    .btn:focus {
      outline: none;
      animation: glowPulse 1s infinite;
    }

    .display:focus {
      outline: none;
      box-shadow: 0 0 15px #00ff00;
    }
  </style>
</head>

<body>
  <div id="matrix-bg"></div>

  <div class="container">
    <div class="calculator">
      <div class="display" id="display">
        <div class="display-content">0</div>
      </div>
      <div>
        <button class="btn" data-value="7"><span>7</span></button>
        <button class="btn" data-value="8"><span>8</span></button>
        <button class="btn" data-value="9"><span>9</span></button>
        <button class="btn" data-value="+"><span>+</span></button>
      </div>
      <div>
        <button class="btn" data-value="4"><span>4</span></button>
        <button class="btn" data-value="5"><span>5</span></button>
        <button class="btn" data-value="6"><span>6</span></button>
        <button class="btn" data-value="-"><span>-</span></button>
      </div>
      <div>
        <button class="btn" data-value="1"><span>1</span></button>
        <button class="btn" data-value="2"><span>2</span></button>
        <button class="btn" data-value="3"><span>3</span></button>
        <button class="btn" data-value="*"><span>*</span></button>
      </div>
      <div>
        <button class="btn" data-value="0"><span>0</span></button>
        <button class="btn" data-value="."><span>.</span></button>
        <button class="btn" data-value="="><span>=</span></button>
        <button class="btn" data-value="/"><span>/</span></button>
      </div>
      <div>
        <button class="btn" data-value="clear"><span>Clear</span></button>
      </div>
    </div>
  </div>

  <script>
    const matrixBg = document.getElementById('matrix-bg');
    const display = document.getElementById('display');
    const displayContent = display.querySelector('.display-content');
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-=[]{}|;:,.<>?';
    const rows = Math.floor((window.innerHeight + 50) / 20);
    let calculation = '';
    let isDisplayFocused = false;

    function createColumn() {
      const column = document.createElement('div');
      column.className = 'matrix-column';
      column.style.left = `${Math.random() * window.innerWidth}px`;
      let y = -50;
      let output = '';
      for (let j = 0; j < rows; j++) {
        output += characters[Math.floor(Math.random() * characters.length)] + '<br><br>';
      }
      column.innerHTML = output;
      matrixBg.appendChild(column);

      function updateColumn() {
        y += 5;
        if (y > window.innerHeight) {
          matrixBg.removeChild(column);
        } else {
          column.style.transform = `translateY(${y}px)`;
          requestAnimationFrame(updateColumn);
        }
      }
      requestAnimationFrame(updateColumn);
    }

    function startMatrixEffect() {
      createColumn();
      setTimeout(startMatrixEffect, Math.random() * 500);
    }

    for (let i = 0; i < 5; i++) {
      setTimeout(startMatrixEffect, i * 200);
    }

    function updateDisplay() {
      const scrollPosition = display.scrollLeft;
      displayContent.textContent = calculation || '0';
      display.classList.add('animate');
      setTimeout(() => display.classList.remove('animate'), 500);

      if (!isDisplayFocused) {
        display.scrollLeft = display.scrollWidth;
      } else {
        display.scrollLeft = scrollPosition;
      }
    }

    function handleButtonClick(e) {
      const btn = e.target.closest('.btn');
      if (!btn) return;

      btn.classList.add('active');
      setTimeout(() => btn.classList.remove('active'), 200);

      const value = btn.dataset.value;
      if (value === '=') {
        try {
          calculation = eval(calculation).toString();
        } catch (error) {
          calculation = 'Error';
        }
      } else if (value === 'clear') {
        calculation = '';
      } else {
        calculation += value;
      }
      updateDisplay();
    }

    document.querySelector('.calculator').addEventListener('click', handleButtonClick);

    // Make the display focusable
    display.tabIndex = 0;

    // Track focus state
    display.addEventListener('focus', () => {
      isDisplayFocused = true;
    });

    display.addEventListener('blur', () => {
      isDisplayFocused = false;
    });

    // Prevent default calculator behavior when interacting with the display
    display.addEventListener('mousedown', (e) => {
      e.stopPropagation();
    });

    display.addEventListener('touchstart', (e) => {
      e.stopPropagation();
    });

    // Prevent keyboard input on the display
    display.addEventListener('keydown', (e) => {
      e.preventDefault();
    });

    let lastTime = 0;
    function animate(currentTime) {
      if (currentTime - lastTime > 500) {
        createColumn();
        lastTime = currentTime;
      }
      requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
  </script>
</body>

</html>

 

Tutaj link do repozytorium z wszystkimi wersjami aplikacji: kalkulator-github

 

Oraz proste demo z działania:

 

Tabele w HTML i animacja JavaScript

W tym wpisie zaprezentuję możliwe zastosowanie HTML, CSS i JS do strony, w której są  odpowiednio ostylowane dwie tabele i animacja przewijania strony w JS.

Środowisko programistyczne użyte do utworzenia projektu to Visual Studio Code z rozszerzeniem “Live Server“.
Po zainstalowaniu i włączeniu wtyczki klikamy prawym przyciskiem myszy na utworzonym pliku HTML, a następnie w “open with Live Server”. Powinna nam się otworzyć domyślna przeglądarka z podglądem strony webowej.

Poniżej zdjęcia poglądowe jak to mniej więcej powinno wyglądać:

Od razu umieszczę końcowy kod ze szczegółowymi komentarzami, a następnie opiszę co po kolei tworzyłem.

<!-- plik HTML -->
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8"/>
<title>Let's go start</title>
<!-- zewnętrzny arkusz stylów-->
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<h1 class="header">
    <div class="wrapper">

        <table> <!--tabela w HTML-->
            <tr> <!-- naglowek -->
                <th colspan="4">USŁUGI INTERNETOWE</th> 
             </tr>
            <tr> <!-- naglowki-->
               <th>Nr</th> <th>HOSTING</th> <th>DOMENA_1</th> <th>DOMENA_2</th>
            </tr>
            <tr> <!-- wiersz-->
               <td>1</td> <td>100</td> <td>0</td> <td>40</td> <!-- kolumny-->
            </tr>
            <tr> 
                <td>2</td> <td>100</td> <td>40</td> <td>40</td> <!-- kolumny-->
             </tr>
             <tr> 
                <td>3</td> <td>120</td> <td>50</td> <td>50</td> <!-- kolumny-->
             </tr>
             <tr id="scroll"> <!-- utworzenie id w celu umożliwienia identyfikacji do animacji-->
                <td colspan="4">przewiń w dół</td>
             </tr>
         </table>
        
       
    </div>
    <div class="wrapper">
    <table>
        <tr>
            <th colspan="3">PODSUMOWANIE USŁUG INTERNETOWYCH<br>
                            na dzień xx.xx.xxxx</th>
        </tr>
        <tr>
            <th>HOSTING</th> <th>DOMENA_1</th> <th>DOMENA_2</th>
        </tr>
        <tr>
            <td>jest do xx.xx.xxxx</td> <td>jest do xx.xx.xxxx</td> <td>jest do xx.xx.xxxx</td>
        </tr>
        <tr>
            <td colspan="3">Dotychczasowy poniesiony koszt</td>
        </tr>
        <tr>
            <td>320</td> <td>90</td> <td>130</td>
        </tr>
        <tr>
            <td colspan="2">410</td>  <td>130</td>
        </tr>
        <tr>
            <td colspan="3">540 - łącznie zł</td>
        </tr>
    </table>
    </div>
</h1>
<!-- zewnętrzny plik javascript-->
<script src="js/script.js"></script>
</body>
</html>
/* plik CSS */
body{ /* tło strony */
    background-color: rgb(79, 173, 76);
}
.header{ /*kolor tekstu*/
    color: darkblue;
}
.wrapper{ /* najczęściej stosowana metoda wyśrodkowania elemntu
            wrapper musi być rozciągnięty na całą szerokość i wysokość okna */    
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

table, th, tr, td { /* utworzenie obramowania */
    border: 1px solid black;
}
th, td{ /* utworzenie odpowiedniego odstępu od obramowania i wycentrowania zawartości*/
    padding: 20px;
    text-align: center;
}
//plik JS
//pobranie elementu o id 'scroll' i w momencie jego kliknięcia wywołanie funkcji scroll()
document.getElementById("scroll").onclick = function() {scroll()};


//funkcja scroll z zainicjowana na 0 zmienną i oraz wywołaniem podfunkcji move()
function scroll(){
    i = 0;   
    move();
}


function move(){
    i++; //zwiększanie o jeden zmiennej i
    window.scrollBy(0,1); //przesuwanie ekranu w pionie
    /*jeżeli i będzie mniejsza o wysokość ekranu, wykonuj co pewien czas upłynięcia funkcję move(),
    czyli inaczej mówiąc przesuwaj w dół zawartość ekranu o całą jego wysokość względem czasu*/
    if (i < screen.height) setTimeout('move()',1);
}

Najpierw utworzyłem strukturę katalogów.
Odpowiednio folder js dla plików JS, CSS dla arkuszów styli, index.html pozostał w głównym katalogu. Oraz odpowiednio w katalogu css plik style.css, a w js script.js.

Na wstępie pisania strony tworzę typowy plik html w strukturze HTML5.
Od razu dodaje zewnętrzny arkusz styli w znaczniku head. A na końcu ciała body odwołanie do zewnętrznego skryptu JavaScript.

Początkowo mam zamiar wszystko wypośrodkować więc tworzę do tego celu div-a z nazwą klasy wrapper. Potem tak jak jest napisane w pliku arkuszów styli za pomocą .wrapper odwołuje się do tego elementu oraz go wypośrodkowuje w poziomie i pionie.

Przyszedł czas na utworzenie tabel.
Słowo kluczowe/ znacznik table odpowiada za utworzenie tabeli.
tr – to wiersz
th– nagłówek
td– podział na kolumny
Najpierw tworzymy wiersz, następnie w zależności ile chcemy kolumn tyle tworzymy nagłówków. Kolumny możemy łączyć za pomocą słowa kluczowego colspan, jako argument podajemy na ile kolumn dana kolumna ma się rozszerzyć.
Kolejno tworzymy następne wiersze i kolumny.
Czas na stylizację. Dodajemy do tabeli i wszystkiego co wewnątrz obramowanie. Stosując przecinek jak pokazane w przykładzie możemy bez multiplikowania kodu użyć do kilku elementów tego samego bloku CSS. Odpowiednio następnie dodaje odstęp w tabeli od obramowania i wypośrodkowuje tekst, żeby to w miarę estetycznie wyglądało.

Kolej na drugą tabelę. Pamiętam o tym, żeby tabela była umieszczona we wrapperze, żeby zachować odpowiednie ostylowanie co do wyśrodkowania.

I teraz końcowo dodaje identyfikator scroll do ostatniego wiersza w pierwszej tabeli w celu umożliwienia odwołania się w skrypcie do wywołania funkcji scroll po kliknięciu na wiersz w tabeli.

Plik JS to prosta głównie jedna funkcja move() odpowiedzialna za przewijanie strony w dół ekranu.

Poniżej końcowy efekt:

O

Link do repo:

https://github.com/traininguniverse/simple-table

Proste poziome menu nawigacyjne z pionowym rozwijanym w HTML i CSS

Przedstawię mniej więcej jak utworzyć menu i podmenu, które powinno wyglądać tak jak poniżej:

Menu

 

 

 

 



Składać się będą na to dwa pliki “index.html” i “style.css”.
Dokładniejszy opis wykonania będzie umieszczony w plikach źródłowych.

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Menu</title>
<!--zewnętrzny arkusz stylów-->
<link rel="stylesheet" href="styles/style.css">
</head>
<body>
<header>
<nav>
<ul>
<li><a href="#home">Home</a></li>
<li class="dropdown">
<!--to bedzie rozwijana do dołu lista-->
<a href="javascript:void(0)" class="dropbtn">News</a>
<!--po wybraniu nic sie nie dzieje-->
<div class="dropdown-content">
<!--zagnieżdżona lista rozwijana w dół-->
<a href="#news1">News 1</a>
<a href="#news2">News 2</a>
<a href="#news3">News 3</a>
</div>
</li>
<li><a href="#contact">Contact</a></li>

</ul>
</nav>
</header>
</body>
</html>

 

 

 

/*jako że są to kaskadowe arkusze stylów, to kolejno od góry do dołu są dokonywane kolejne zmiany i też jak zajdzie potrzeba nadpisywane*/
ul {
    list-style-type: none; /*wyłączenie punktowania elementów listy*/
    margin: 0; /*zerowy margines naokoło listy*/
    padding: 0; /*otoczenie wewnętrzne*/
    overflow: hidden; /*ukrycie nadmiarowego rozmiaru listy*/
    background-color: #333;
}

li {
    float: left; /*ustawienie elementów listy tak by "pływały" w lewym kierunku*/
}

li a, .dropbtn {/*znak spacji w css oznacza następujące (niekoniecznie kolejno) po sobie elementy, natomiast przecinek oznacza tylko, że ".dropbtn" jest kolejnym elementem do takiego samego ostylowania*/
    display: block; /*wyświetlanie jako bloku*/
    color: white;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none; /*wyłączenie podkreślenia w linkach*/
}

li a:hover, .dropdown:hover .dropbtn {/*":hover", czyli co będzie się działo po najechaniu na podstawowe menu*/
    background-color: #04AA6D;
}
li.dropdown {
    display: block;
}
.dropdown-content {
    display: none; /*pierwotne ukrycie menu rozwijanego w dół*/
    position: absolute; /*tak jakby usunięte jest zajmowane miejsce w dokumencie zajmowane przez element i ustawione do najbliższego pozycyjnego przodka;*/
    background-color: #333;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1; /*określenie pozycji w dokumencie (że menu będzie widoczne nad elementami ciała dokumentu*/
}

.dropdown-content a:hover {
    background-color: #04AA6D; /*kolor po najechaniu na element rozwijany w dół*/
}

.dropdown:hover .dropdown-content {
    display: block;
}

HTML, CSS i JavaScript: przykładowy kod strony

Poniżej przedstawiam przykładowe zastosowanie tych języków w utworzeniu prostej strony www. Składa się z czterech plików dostępnych poniżej.

 

Plik index.html:

<!DOCTYPE html>
<html>
<head>
<title>Menu</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="skrypt.js"></script>
</head>
<body>
<div id="menu">
<ul>Kurs: 
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
</ul>
</div>
<div id="srodek">
Strona z odrobiną HTML-a, CSS-a i JavaScript. Kliknij na podkreślony tekst, a zmieni on kolor: <div onclick="zmiana(this);" class="czarny" id="podkreslonyDiv">kliknij tu, a zmienię kolor.</div>
</div>
</body>
</html>

Strona jest zgodna ze specyfikacją HTML5. Składa się ze standardowej struktury znaczników: html, head, body.

W głowie dokumentu w znaczniku link umieszczamy odnośnik do zewnętrznego arkusza stylów. Dalej podobnie w znaczniku script zewnętrzny skrypt napisany w języku JavaScript.

W ciele dokumentu znajduje się menu w postaci listy nieuporządkowanej.

Następnie blok, który wypośrodkujemy i zastosujemy w znajdującym się w nim tekście, dynamikę strony, polegającą na wywołaniu funkcji zmiana(), która jest odpowiedzialna po kliknięciu na element o id podkreslonyDiv, za zmianę klasy tego elementu.

 

Plik style.css:

body{
background-color: #C0C0C0;
}
ul{
list-style-type:none;
background: url(menu.png) repeat-x;
font-size:23px;
width:332px;
border-radius:15px;
margin:0;
}
ul li{
display:inline;
padding:5px;
}
ul li a:hover{
background: rgb(45,75,80);
border-radius:2px;
color:white;
}
a{
text-decoration:none;
color:#303030 ;
}
#menu{
width:372px;
height:27px;
margin-left: auto ;
margin-right: auto ;
}
#srodek{
margin-top:10px;
width:700px;
margin-left: auto ;
margin-right: auto ;
border-radius:15px;
background-color:#e8edef;
padding:30px;
}
.czerwony{
color:red;
}
.czarny{
color:black;
}
#podkreslonyDiv{
text-decoration:underline;
display: inline;
cursor: pointer;
}

W liście wyłączamy style listy (wypunktowanie). Następnie podajemy lokalizację do obrazka, który posłuży za tło menu, musimy go odpowiednio rozciągnąć w poziomie. Za pomocą ul li, odpowiednio przodka i potomka, określamy, że elementy listy mają wyświetlać się w jednej linii. Pseudoklasa :hover odpowiada za czynność najechania kursorem na element łącza a, zmieniamy tu, m.in. tło i kolor. W łączu wyłączamy charakterystyczne dla linków podkreślenie tekstu.

.czerwony i .czarny odpowiednio to zdefiniowane własne klasy, każda posiada określony inny kolor.

 

Plik skrypt.js:

function zmiana(div){
if (div.className == "czarny")
div.className = "czerwony";
else
div.className = "czarny";
}

Wspomniana wcześniej funkcja zmiana() wywołana z parametrem div. Początkowo klasa div-a jest ustawiona na kolor czarny. Odpowiednio po wywołaniu funkcji ma się zmieniać na przeciwną, o odmiennym kolorze.

 

Plik menu.png (kliknij prawym przyciskiem myszy na linie pionową i kliknij zapisz jako):

 

Wszystko umieszczamy w jednym folderze i uruchamiamy plik index.html za pomocą dowolnej przeglądarki internetowej.