20200328のCSSに関する記事は8件です。

flexで孫要素の高さを揃える

若干ハマったので自分用にメモ。

See the Pen KKpbeEo by koji hirai (@koji_5) on CodePen.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrapの画面分割

Bootstrapの基本

html.
<html>
<div class="container">
  <div class="row">
    <div class="col-サイズ-割合">
  </div>
</div>
</html>

containerの中にrow、rowの中にcolを入れていく。
div class="col-サイズ-割合"
サイズ表:

xs sm md lg
~767px 768~911px 912~1119px 1120px~
スマホ タブレット PC PC大画面

割合:
画面を12分割し、割合を決めることで画面を分けることが簡単にできる。

例1:
col-lg-4
col-lg-4
col-lg-4
これらは横並びに3列均等に分割できる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

指定したエリアだけを印刷する処理

こんな場面で使えます。

 例えば、ユーザーに何らかのアンケートに回答をしてもらうサイトで
ユーザーが自分の回答結果の部分だけを印刷したい場合などに使えます。
普通の印刷では余計な箇所も入ってくるので、必要なエリアだけを印刷できるようにします。
※実際の挙動が確認できるwebアプリのURLを一番下に載せてますので、そちらもご確認ください。
11printImg1.jpg

実装の流れ

 1:印刷ボタンを作成
 2:プリントしたいエリアの取得の指定
 3:2のエリア全体のコピーを作成
 4:3以外を非表示にする処理を作成
 5:印刷ダイアログの呼び出し➡︎印刷する
 6:3で作成した印刷用エリアを削除 ・ 4で非表示にした要素を表示する

実装スタート

1:印刷ボタンを作成

print.html
<button class="print-btn">
 <span>結果だけを印刷する</span>
</button>

2:プリントしたいエリアの取得

 プリントしたい範囲を以下の「divタグ」で囲む。

print.html
<div class="print-area">
 <!-- この中に要素を入れる。印刷しないものは、後で非表示にする処理で消します。 -->
</div>

3:2のエリア全体のコピーを作成

 1:プリントしたい範囲を取得
 2:プリント用の要素「#print」を作成。
 3:2の子要素に1を入れる。

print.js
$(function(){
//個別印刷ボタンをクリックした時
$('.print-btn').on('click', function(){

//プリントしたいエリアの取得
var printArea = document.getElementsByClassName("print-area");

//プリント用の要素「#print」を作成し、上で取得したprintAreaをその子要素に入れる。
$('body').append('<div id="print" class="printBc"></div>');
$(printArea).clone().appendTo('#print');

//この下に、以降の処理が入ります。

 });
});

4:3以外を非表示にする処理を作成

print.js
//プリントしたいエリア意外に、非表示のcssが付与されたclassを追加
$('body > :not(#print)').addClass('print-off');
print.css
.print-off {
 display: none;
}

5:印刷ダイアログの呼び出し➡︎印刷する

print.js
window.print();

6:3で作成した印刷用エリアを削除 ・ 4で非表示にした要素を表示して終了です。

print.js
//window.print()の実行後、作成した「#print」と、非表示用のclass「print-off」を削除
$('#print').remove();
$('.print-off').removeClass('print-off');

終わりに。

いかがでしょうか。
印刷したいエリアだけを取り出せるのでユーザーにとって不要なエリアが無くなり使い勝手の良いページが作成できると思います。
自作の家庭用備蓄をチェックできるアプリでも、チェックした備蓄情報を印刷できるようにしてありますので
良かったら作業の合間にそちらを見ていただけると具体的な挙動を確認していただけます。
https://saku2stockcheck.herokuapp.com/

では、最後まで見ていただいてありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ヘッダーを途中から固定させたい!

概要

ポートフォリオサイト作成時、
スクロールしてヘッダーを途中から固定させたいと思い実装していたのですが、
なかなか上手くいかなかったので備忘録としてまとめます。

おかしなところあったらご指摘ください・・・

条件

ビューはHamlで記載
jQuery導入済み

Html

スクロールしてtop-visualを過ぎた後にheaderが固定されるイメージです。

index.html.haml
.top
  .top-visual
    .top-visual__movie-area
      = image_tag "top-image"
  .header
    .header__line
      .header__nav-bar
        .header__container
          .header__title
            My portfolio
          .header__nav-area
            %ul.header__nav-lists
              %li.header__nav-item
                = link_to "HOME", "#"
              %li.header__nav-item
                = link_to "ABOUT", "#"
              %li.header__nav-item
                = link_to "WORKS", "#"
              %li.header__nav-item
                = link_to "SERVISE", "#"
              %li.header__nav-item
                = link_to "CONTACT", "#"
  .main
    .main-content

CSS

index.scss
.fixed {
  // 本来であれば「position: fixed」の「!important」は不要です。
  // 上手く固定されないときは試してみてください。
  position: fixed !important;
  top: 0;
  left: 0;
  z-index: 2;
  width: 100%;
  color: #fff;
  margin-bottom: 100px;
  background-color: #1A1A1A;
}

.header{
  // position: absoluteを指定しないと固定させるときにガクンとビューが崩れます。
  position: absolute;
  height: 50px;
  width: 100%;
}

jQuery

index.js
$(function() {
    var $win = $(window),
        $main = $('main'),
        $nav = $('header'),
        navHeight = $nav.outerHeight(),
        navPos = $nav.offset().top,
        fixedClass = 'fixed';

    $win.on('load scroll', function() {
      var value = $(this).scrollTop();
      if ( value > navPos ) {
        $nav.addClass(fixedClass);
        $main.css('margin-top', navHeight);
      } else {
        $nav.removeClass(fixedClass);
        $main.css('margin-top', '0');
      }
    });
  });

完成

Image from Gyazo

CSSとJSは奥が深い・・・!引き続き精進してまいります・・・!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrap縛りで制作するポートフォリオ #1

今回は、この時期にあるといいポートフォリを制作していきます。その際、普通に使うのでは面白くないので、Bootstrapを導入して実装するという縛りで実装していきます。

本来ポートフォリオにはフレームワークなどをどんどん取り入れてくのは良くないと個人的には思います。というのも自身のコードでないとその実力ははかりえないので。。。ということで今回はポートフォリオの簡単な作成の流れとBootstrapの簡単な使い方を紹介することを意図しています。

はじめに

まずは、簡単なレイアウトを決めていきます
このポートフォリオは、誰も依頼したわけでも〜な機能を必要ともされていません。それ故に、自分で決めなければいけません。ではどこで判断基準になるのでしょうか? 

UXが全て

実際にそのサイトをみてどの様に印象を持たせるかが、このポートフォリオで一番大切な点です。
~の機能がないとかは判断されませんが、ある程度の機能があった方がその評価は高くなります。

レスポンシブデザインは行なっているか

今の時代、サイトにアクセスするユーザの大半がスマートフォンからのアクセスです。つまりそのサイトにアクセスする人もPCではなく、画面表示領域の少ないスマートフォンであるかもしれません。
どんなに、hoverされた時のデザインにこだわっていてもスマホではその効果は発揮できないと言っても過言ではありません。
いくら見た目にこだわった、タブメニューを実装してもスマホで押しやすくなければ意味の無いということです。

ブレイクポイントについて

それでは、モバイルデザインを行う上で、必要となってくるメディアクエリ
ブレイクポイントを指定することにより、どの画面表示領域からそのデザインを行うかを指定することができます。
Bootstrapの場合は、デフォルトで4つのブレイクポイントが指定されています。

画面横幅 class名
576px768px以下(スマホ) col-xs-
768px以上992px未満 cos-sm-
992px以上、1200px未満 col-md-
1200px以上 col-lg-

この768pxというブレイクポイントに関してはiPad(横画面)の画面表示領域を表しています。最近のiPadではある程度画面表示領域も多くてスマホと同じスタイリングを行うべきでは無いと思います。

自前で実装する場合はここまでなくても良いかと思います。
smallスクリーンとmidiumスクリーンの二つで今回は実装していきます。

それでは、ある程度決め終わったので次回から作成していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

div要素を横並びにしたいがdisplay: flexが効かない原因

ドットインストールで学習中です。
div要素を横並びにするために
display: flex;
を記述しましたが、効いていないようです。

div要素が横並びにならない原因が分かる方いましたら指摘して頂けるとありがたいです。
よろしくお願いします。

以下が全体のコードです。

<!DOCTYPE html>



JaveScript Practice





<script>
  'use strict';

  const target1 =  document.getElementById('target1');
  const target2 =  document.getElementById('target2');
  const target3 =  document.getElementById('target3');

  target1.addEventListener('click', () => {
    target1.classList.toggle('circle');
  });
  target2.addEventListener('click', () => {
    target2.classList.toggle('circle');
  });
  target3.addEventListener('click', () => {
    target3.classList.toggle('circle');
  });
</script>


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPでポートフォリオ作成:カレンダー

記事の概要

作った背景、工夫したところ、機能をまとめました。

下にコードを記載しました。

背景

一般的なカレンダー(家の壁にかかっているものを想像してほしいです)を作成したときに、自分のスケジュールを書き込めると、カレンダーとしての価値がアップするのでないかなと思い作成にいたりました。

エクセルのようなレイアウトで日付とスケジュールを同時に表示するようなカレンダーを作成します。

工夫としては、当たり前ですが見た目を分かりやすく、使用者が使いやすいようにシンプルにしました。

目的

・PHPを用いて簡単なアプリケーションを作る
・見やすくて使いやすいアプリを作る
・カレンダー機能+スケジュール機能で単純なカレンダーに価値をつける

スペック

言語
PHP 7.4.2
データーベース
MariaDB 10.4.11
開発環境
Apache 2.4.41

ビジュアルスタジオコード使用

主な機能

・今月の日付の表示機能
・来月、前月のカレンダーへのリンク
リンクをクリックすると、来月もしくわ前月のカレンダーに飛びます

・スケジュールの表示機能
カレンダーの日付の横にスケジュールの時間と内容を表示する

・スケジュールの保存機能
日付、時間、スケジュールという情報をデータベースに保存する

・スケジュールの更新機能
スケジュールを更新する

・スケジュールの削除機能
スケジュールを削除する

※データベースのカラムの情報があると説明しやすいので、詳しくは下部で説明します。

開発手順

1、要件定義
2、環境選定
3、データベース設計
4、設計
5、コーディング

1、要件定義

今回のアプリでの主要な機能は
・今月の日付の表示
・スケジュールの表示
・スケジュールの保存、更新、削除

今月の日付が表示できるということは、月(month)の部分を変更することで来月、前月のカレンダーが表示可能になります。
ということは、すべての日付のカレンダーが作成可能になります。

スケジュールの保存には、データベースが必要です。

環境選定

PHP,MySQL,apacheを使用。

Windowsローカル上に環境を構築しました。

データベース設計

記入例

id day time   message  
5 2018-12-15 18:00 予定を書く

スケジュールの情報をデータベースに保存。
スケジュールの情報としては
id,day,time,messageとして
idにはオートインクリメントを設定して、idの値がかぶることはないようにしました。
dayには2020-03-27の形式で年月日を保存
timeにはtextタイプなので時間の表現の仕方は自由です
messageにはスケジュールの内容を保存します

設計

のちほど追加予定

 5.コーディング

設計を書いたのですが、後々変更することは多かったです。
理由は、コーディングしていて「このように表示する方が使用者にとっては、使いやすいのではないか」という考えの結果、レイアウトの変更をしました。

5.1データベース作成

ローカル環境のMysqlサーバーに
データーベースを作成。テーブルを作成。

5.2データベース接続確認

PDOを用いて、データーベースの接続。
try~catchを用いて、成功しているか判断

5.3今月の日付の表示機能

GIF 2020-03-28 8-39-33.gif

urlに?t=2020-04のような表記があれば、その年月(この場合2020-03)で取得し、表記がなければ今月の年月を取得する
これで、年月日の年月の情報を取得したので、年月の情報からDatePeriodを使って、年月日における日の部分の情報を取得します。
これで年月日の情報がそろったのでエクセルや表のような形式で表現します

5.4・来月、前月のカレンダーへのリンク

リンクをクリックすると、来月もしくわ前月のカレンダーに飛びます

GIF 2020-03-28 8-42-58.gif

5.3にて年月日の情報を取得しています。なのでリンクをその月(month)に+1すれば翌月、-1すれば前月へ飛ぶように設定しました。

5.5スケジュールの表示機能

カレンダーの日付の横にスケジュールの時間と内容を表示する

if文で取得している年月日とデータベースにあるdayの部分で一致するレコード(行部分)が存在したら、そのレコードのスケジュール時間と内容を日付の横に表示する

5.6スケジュールの保存機能

日付、時間、スケジュールという情報をデータベースに保存する
この時、日付の形式が2020-03-27のような形式でない場合はerrorとし
errorが存在する場合はエラーメッセージを表示する

GIF 2020-03-28 8-48-45.gif

5.7スケジュールの更新機能

スケジュールを更新する

GIF 2020-03-28 8-53-15.gif

構造上、日付1つに対して1つのメッセージになるため、
更新機能を使う場合、既存のスケジュールの情報を削除してから、また新しくスケジュールをデータベースに保存する方法を使用

※1つの日付に対して、複数のメッセージがある場合はidが新しいメッセージが表示される。
※また、ある日付に対してメッセージが存在するにも関わらず、メッセージを作成した場合は、メッセージは既存のメッセージが表示されるので、新しく作ったmemberテーブルは表示されない

5.8スケジュールの削除機能

スケジュールを削除する

削除ボタンを作って、削除を実行する
この時、日付に該当する箇所を変更した場合、その日付のメッセージが削除される。

5.9レイアウト

新しくスケジュールを作る機能はアイコンにして、右上に固定しました。
これは、下にスクロールしたとしても、スケジュール作成できるためです
配色の統一、シンプルにわかりやすいをこころがけました

課題点

・「1つの日付に対して、1つのスケジュール」でなく複数のスケジュールを表示すべきだが、技術的にできなかった。
・わかりやすく,シンプルに作ったつもりであるが、その分、説明不足で慣れれ宇までに時間がかかる可能性がある
・スケジュールの保存に関して、使用者の制約があり親切でない、
1999-03-20のような形式でなくタイプをradio形式(複数の選択肢から1つを選択する形式)で年、月、日に分けて表現すれば良かったかもしれない。
・スケジュールの削除に関して、入力されている年月日のデータの削除があることを説明していない
・オブジェクト思考がなってない。機能を別ファイルでプログラミングして、呼び出すことができてない

code

index.php
画像

index.php
<?php 
require('dbconnect.php');

//セキュリティ対策
function h($s){
  return htmlspecialchars($s,ENT_QUOTES,'UTF-8');
}
//

//今月を取得する
try{
if(!isset($_GET['t']) || !preg_match('/\A\d{4}-\d{2}\Z/',$_GET['t'])){
  throw new Exception();
}
  $thisMonth=new DateTime($_GET['t']);
}catch(Exception $e){
  $thisMonth = new DateTime('first day of this month');
}


//今月から来月と翌月を取得する
  $dt= clone $thisMonth;
  $prev = $dt->modify('-1 month')->format('Y-m');
  $dt= clone $thisMonth;
  $next=$dt->modify('+1 month')->format('Y-m');
//


$yearMonth=$thisMonth->format('F Y');

//日付、メッセージの表示機能
  $period=new DatePeriod(
    new DateTime('first day of'.$yearMonth),
    new DateInterval('P1D'),
    new DateTime('first day of'.$yearMonth.'+1 month')
  );

  //複数のメッセージをつけたいがつけれなかった
  $body='';
  $today=new DateTime('today');
  foreach($period as $day){

    $messages=$db->prepare('SELECT * FROM posts WHERE day=?');
    $messages->execute(array($day->format('Y-m-d')));
    $message=$messages->fetch();

    $todayClass=($day->format('Y-m-d') === $today->format('Y-m-d'))?'today':'';
    $body .= sprintf('<tr><td class="youbi_%d %s">%d</td><td>%s</td><td class="message"><a   href="message.php?t=%d-%02d-%2d">%s</a></td></tr>',$day->format('w'),$todayClass,$day->format('j'),$message['time'],$day->format('Y'),$day->format('n'),$day->format('d'),$message['message']);
  }
//




//cssでのレイアウト
//オブジェクト思考


//終了。前月次月のリンク.todayのリンク,データベースに保存する
//今日を太文字、土日は色変える,時間の指定もあり、消去、変更

?>



<!DOCTYPE html>
<html lang='ja'>
<head>
  <meta charset='utf-8'>
  <title>カレンダー</title> 
  <link rel='stylesheet' href='styles.css'>
</head>
  <body>
      <a class='write' href="message.php" name='write_message'><img  src="write.png"  alt="写真"></a>
    <table>
      <thead>
        <tr>
          <th><a href="/test/index.php?t=<?php echo h($prev); ?>">&laquo;</a></th>
          <th><?php echo $yearMonth; ?></th>
          <th><a href="/test/index.php?t=<?php echo h($next); ?>">&raquo;</a></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>day</td>
          <td>time</td>
          <td>message</td>
        </tr>   
        <?php echo $body;?>
      </tbody>
    </table>
  </body>
</html>

message.php
画像

message.php
<?php
require('dbconnect.php');


//入力機能は取得して、それをインサートするだけ

if(!empty($_POST)){
    //すでにメッセージが存在する場合、そのメッセージを消去する
    //先に消去をおした場合にはメッセージを消去してexitする
    if($_POST['delete'] ==='1'){
      $deletes=$db->prepare('DELETE FROM posts WHERE day=? ');
      $deletes->execute(array($_POST['day']));
      header('Location:index.php');
      exit();
    }


    if(!empty($_POST)){

      $posts=$db->prepare('SELECT * FROM posts WHERE day=?');
      $posts->execute(array($_POST['day']));
      $post=$posts->fetch();

      if(!empty($post['message'])){
      $deletes=$db->prepare('DELETE FROM posts WHERE day=? ');
      $deletes->execute(array($_POST['day']));
    }


  //日付の設定はシビアで形式が決まっているので、形式が違えばエラーをだす
  if( preg_match('/\A\d{4}-\d{2}-\d{2}\z/',$_POST['day'])){
    $message=$db->prepare('INSERT INTO posts SET day=? ,message=?,time=?');
    $message->execute(array(
      $_POST['day'],
      $_POST['message'],
      $_POST['time']
    ));

    header('Location:index.php');
    exit();
  }else{
    $error['day']='format';
  }

}


}
//messageの再取得、
  $messages=$db->prepare('SELECT * FROM posts WHERE day=?');
  $messages->execute(array($_REQUEST['t']));
  $message=$messages->fetch();

?>
<!DOCTYPE html>
<html lang='ja'>
<head>
  <meta charset='utf-8'>
  <title>カレンダー</title> 
  <link rel='stylesheet' href='styles.css'>
</
head>
  <body>
    <div class='title'>
      <a href="index.php"><< ホーム</a>
    </div>
    <div class='content'>

      <form action="" method='post'>
        <p class='delete_p'>メッセージを消去>><button type='subimt' class='delete'  name='delete' value='1'>消去</button></p>
        <p >日付 (※2020-01-01の形式で入力してください)</p>
        <input name='day' type="text" value="<?php echo $_REQUEST['t'];?>" >
        <?php if($error['day'] === 'format'): ?>
          <p class='error'>※2020-01-01の形式で入力してください。</p>
          <?php endif;?>
          <p>時間</p> 
          <input name='time' type="text" value='<?php echo $message['time'] ?>'>
          <p>メッセージ</p>

          <textarea name="message" id="" cols="30" rows="10" ><?php echo $message['message']; ?></textarea>
          <button type='submit'>メッセージを保存する</button>




    </div>
  </form> 

  </body>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 275日目

100日チャレンジの275日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
275日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む