20211007のCSSに関する記事は4件です。

【React】スタイルの扱い方 

はじめに Reactのスタイルの扱い方についてまとめてみました。私のプロジェクトではCSS Modulesを使うことが多いです。CSS Modulesは、今までのCSSの書き方と同じように書くことができます。 Inline Style Reactでも各タグにstyle属性を記述することで、スタイルの適用をすることができます。JavaScriptで記述するので、style={}のように波括弧で囲み、その中にオブジェクトでCSSに対応する要素を指定しているため、style={{}}と記載します。 App.jsx //文字を赤色に変更 export const App = () => { return ( <> <h1 style={{ color: "red" }}>こんにちは</h1> </> ); }; index.html import ReactDom from "react-dom"; import { App } from "./App"; ReactDom.render(<App />, document.getElementById("root")); 事前に定義する場合 App.jsx const contentStyle = { color: "blue", fontSize: "100px", }; return ( <> {console.log("a")} <h1 style={{ color: "red" }}>こんにちは</h1> <p style={contentStyle}>よろしくおねがいします。</p> </> ); }; index.html import ReactDom from "react-dom"; import { App } from "./App"; ReactDom.render(<App />, document.getElementById("root")); CSS Modulesを使う場合 はじめにパッケージをインストールします。私の環境がnode14なので、node14に対応したnode-sassを入れます。 terminal $ node -v v14.17.6 $ yarn add node-sass@4.14.1 .module.scssという拡張子で、CSSファイルを作成します。 CssModules.module.scss .title { margin: 0; color: red; } .button { background-color: #ddd; border: none; padding: 8px; border-radius: 8px; &:hover { background-color: #aaa; color: blue; cursor: pointer; } } 使うコンポーネントでimportします。 CssModules.module import classes from "./CssModules.module.scss"; export const CssModules = () => { return ( <> <p className={classes.title}>CSS Modulesです</p> <button className={classes.button}>ボタン</button> </> ); };
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLとCSSの基本記述

HTMLとCSSの基本記述 { ・CSSはクラスに記述する { エレメントやタグではなくクラスに指定する。 HTMLエレメントにCSSをかくと打ち消しのためのCSSが増える 制限されたCSSをかくと再利用性が下がる クラス名をわかりやすくする } ・CSSプロパティはアルファベット順 ・ HTMLタグとCSSのインデントは半角スペース2 ・CSSのプロパティをまとめる ・色の16進トリプット表記は可能なら3桁表記に ・CSSのネストは孫まで ・CSSのレンダリング速度 ・セレクタのマッチ数を減らすと高速に動作する ・CSSのセレクタは右から順に評価されるため、CSSの指定セレクタが多い場合は動作速度も遅くなる。 ・ベンタープレフィックス { ・各ブラウザごとの草案段階の先行実装や、独自拡張機能であることを判断するための識別子のこと。 メリット { ・ベンダープレフィックス対応のブラウザで、CSSの最新機能を反映できる } デメリット { ・CSSの仕様が固まれば、不要になり廃止される場合がある。 ・その場合、CSSファイルの中に不要なコードが残りCSSファイルを肥大化させる可能性がある。 } } ・JavascriptからアクセスするIDとクラス { JavascriptからIDもしくはクラスを利用する場合は、ブロック名の前に「js-」をつける。 js-がついたクラスは、CSSファイルには記述せず、デザインのスタイルを当てないようにする。 これはスクリプトとデザインで使用されているクラスを明確に分けるため HTMl要素の中に、CSS用のクラスと、JSクラスを作成しておく。 } ・IDにスタイルを当てない { IDはページ内で一つしあk使用できない IDは詳細度の計算を複雑にする ID経由で多重継承したCSSスタイルの継承は、複雑で難易度が高い クラスよりもIDの方が詳細度が強いという理由でのみ、IDにCSSが書かれている現場がある。 } ・インラインスタイル使用不可 { } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【第六回】コロナ禍だから何かできることをー 自宅療養者連絡ツール ー

前回までのあらすじ 【第五回】コロナ禍だから何かできることを 実装イメージ図 LINEを利用して保健所の担当者の負担を軽減するとともに、自宅療養者はいつでもつながっている安心感を持たせるためのツールイメージです。 ユーザー登録の仕組みを作ろう 今回はLIFFで表示する画面の開発部分です 初期表示の処理 1.LINE IDを渡して、データベースに存在するかチェックをする。 2.存在した場合は、「すでに登録されています」と表示。 3.存在しない場合は、「連絡を受けたユーザーIDを入力してください。」として、登録フォームを表示する。 ユーザー登録の処理 1.入力項目のチェックを行う。 2.エラーがなければ、LINE IDと入力されたユーザーIDをデータベースへ登録する。 3.「登録しました」と返す。 4.LIFFの画面を閉じる。 登録画面 登録済画面 参考資料 LIFFアプリを開発する LIFFアプリを開く 以下、ソースコードはこちら index.php <?php header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' ); header( 'Last-Modified: '.gmdate( 'D, d M Y H:i:s' ).' GMT' ); ?> <!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <title>ユーザー登録</title> <style> *{ margin: 0; padding: 0; -webkit-box-sizing: border-box; box-sizing: border-box; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; font-size:120%; } :focus { outline: none; } a{ text-decoration: none; } #container{ width:80%; margin:0 auto; } #title{ position:fixed; height:10%; left:0; right:0; top:0; text-align:center; } #user_id{ position:fixed; height:10%; width:80%; left:10%; right:10%; top:20%; } #message{ position:fixed; bottom:20%; left:10%; right:10%; width:80%; top:40%; height:30%; color:#f00; } #submit{ position: fixed; bottom: 10%; height:10%; width:80%; left:10%; right:10%; } #loading{ position: fixed; height:100%; width:100%; top:0; bottom: 0%; left:0%; right:0%; z-index:999; background-color:#fff; text-align:center; display: flex; justify-content: center; align-items: center; } </style> <!-- jQuery読み込み --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2.1/sdk.js"></script> <script> $(function() { // LIFFの初期化を行う $('#log').append('START<br>'); liff.init({ liffId: "自分のLIFF ID(URLから『https://liff.line.me/』を除いた文字列)を入力する" }).then(() => { // 初期化完了. 以降はLIFF SDKの各種メソッドを利用できる $('#log').append('GET<br>'); // 利用者のLINEアカウントのプロフィール名を取得 liff.getProfile().then(function(profile) { // ユーザーID const line_id = profile.userId; // プロフィール名 const name = profile.displayName; // HTMLに挿入 $("#line_id").val(line_id); $('#log').append('liff.getProfile()=' + JSON.stringify(profile) + '<br>'); get_profile(line_id); $('#log').append('END<br>'); }).catch(function(error) { $('#log').append('ERROR<br>'); }); }) function get_profile(line_id){ $('#log').append('get_profile START<br>'); try { $.ajax({ type : 'POST' ,url : 'ajax_line.php' ,dataType : 'json' ,data : { mode : 'get' ,line_id : line_id } ,cache : false }).done(function(data, textStatus, jqXHR){ //エラーメッセージが存在しない場合は再描画 if(data['error']==""){ if(data['status']=="NA"){ $("#loading").hide(); }else{ $("#load_error").text("すでに登録されています"); setTimeout(function(){ liff.closeWindow(); },2000); } }else{ $("#load_error").text(data['error']); } }).fail(function(XMLHttpRequest, textStatus, errorThrown){ $('#log').append('ERROR<br>'); $("#load_error").text("データを取得できません"); }); }catch(e){ $('#log').append('ERROR<br>'); $("#load_error").text(e.message); } $('#log').append('get_profile END<br>'); } function set_profile(){ var user_id = $("#user_id").val(); var line_id = $("#line_id").val(); $('#log').append('set_profile START<br>'); try { $.ajax({ type : 'POST' ,url : 'ajax_line.php' ,dataType : 'json' ,data : { mode : 'set' ,user_id : user_id ,line_id : line_id } ,cache : false }).done(function(data, textStatus, jqXHR){ //エラーメッセージが存在しない場合は再描画 if(data['error']==""){ $("#message").text("登録しました"); setTimeout(function(){ liff.closeWindow(); },2000); }else{ $("#message").text(data['error']); } }).fail(function(XMLHttpRequest, textStatus, errorThrown){ $("#message").text("データを取得できません"); }); }catch(e){ $("#message").text(e.message); } $('#log').append('set_profile END<br>'); } //登録ボタン押下処理 $("body").on({ "click" : function(){ set_profile(); } }, "#submit") }); </script> </head> <body> <div id="container"> <h1 id="title">連絡を受けたユーザーIDを入力してください。</h1> <input type="text" id="user_id"> <input type="hidden" id="line_id"> <input type="button" id="submit" value="登録"> </div> <div id="message"></div> <div id="log" style="display:none;width:96%;height:100px;"></div> <div id="loading"><p id="load_error">now loading...</p></div> </body> </html> <!-- liff.closeWindow() --> ajax_line.php <?php require_once("./config.php"); //JSからのデータを受け取る $mode = filter_input(INPUT_POST, 'mode'); // $_POST['mode']とも書ける $line_id = filter_input(INPUT_POST, 'line_id'); // $_POST['line_id']とも書ける $user_id = filter_input(INPUT_POST, 'user_id'); // $_POST['user_id']とも書ける $error_message = ""; //DB接続 if($error_message == ""){ try{ $dbh = new PDO(DATABASE_URL, DATABASE_USER, DATABASE_PASS); // 静的プレースホルダを指定 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // エラー発生時に例外を投げる $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); }catch(PDOException $ex){ $error_message = "接続エラー"; } } //ユーザー情報取得 if($error_message == ""){ try{ $SQL = <<<EOM SELECT USER_ID, USER_NAME FROM LINE_USER WHERE LINE_ID = ? EOM; $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->bindParam(1, $line_id, PDO::PARAM_STR); $stmt->execute(); }catch(PDOException $ex){ $error_message = "ユーザー情報取得エラー"; } } //データ取得 if($error_message == ""){ if($stmt->rowCount() > 0){ $row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT); $user_id = $row[0]; $user_name = $row[1]; } } // 更新処理の時はユーザーIDがあるかチェックする if($error_message == "" && $mode == "set"){ if ($user_id==""){ $error_message = "ユーザーIDが入力されていません"; }else{ try{ $SQL = <<<EOM SELECT USER_ID, USER_NAME FROM LINE_USER WHERE USER_ID = ? EOM; $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->bindParam(1, $user_id, PDO::PARAM_STR); $stmt->execute(); }catch(PDOException $ex){ $error_message = "ユーザー情報取得エラー"; } //データ取得 if($error_message == ""){ if($stmt->rowCount()==0){ $error_message = "ユーザーIDが登録されていません"; } } } } //アクション if($error_message == ""){ if($mode == "get"){ if ($user_id==""){ $status = "NA"; } }elseif($mode == "set"){ //トランザクション処理を開始 $dbh->beginTransaction(); try { $SQL = <<<EOM UPDATE LINE_USER SET LAST_ACCESS = NOW() ,LINE_ID = :line_id WHERE USER_ID = :user_id EOM; $stmt = $dbh->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->bindParam(':user_id', $user_id, PDO::PARAM_STR); $stmt->bindParam(':line_id', $line_id, PDO::PARAM_STR); $stmt->execute(); //コミット $dbh->commit(); }catch(Exception $ex){ //ロールバック $dbh->rollback(); $error_message = "登録に失敗しました"; } }else{ $error_message = "予期しないエラーが発生しました"; } } $list = array( "error" => $error_message, "status" => $status ); //JSONデータを出力 header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。 echo json_encode($list); exit; //処理の終了 ?> config.php <?php define("DATABASE_URL", 'mysql:host=アドレス;dbname=データベース名;charset=utf8'); define("DATABASE_USER", '接続ユーザー名'); define("DATABASE_PASS", '接続パスワード'); ?> コロナ禍だから何かできることをー 自宅療養者連絡ツール ー 【第一回】実装イメージ図と動画 【第二回】LINEからデータを取得して返すまでの流れ 【第三回】LINEからデータベースまでの流れ 【第四回】データベースへの更新までの流れ 【第五回】ユーザー登録の仕組み-LINEbotの設定部分 ->>【第六回】ユーザー登録の仕組みLIFFで表示する画面の開発 【第七回】データベースの構造 【第八回】WEB画面上でできる機能 【第九回】まとめ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【備忘録】CSSとJavaScriptライブラリで3Dのフリップカードを作った

はじめに 初投稿です。現在フロントエンジニアを目指して学習中です。アウトプット及び備忘録としてQiita始めました。 本記事の目的は自分が忘れないように記録しておくためです。間違っている箇所等ありましたら、ご指摘頂けると助かります。 流れ CSS で 3D アニメーションを実装し、Swiper.jsを使って 3D のフリップカードを実装する。 Swiper.js とはスライダーが作れる JavaScript のライブラリのこと。レスポンシブにも対応。 結果 作れたもの。 手順 HTML を書く(カード 1 枚分のみ。wrapper などは省略。) (index.html) <!-- 5枚のカード全体のラッパー --> <div class="packages-wrapper swiper-wrapper"> <!-- カード単体のラッパー --> <div class="package swiper-slide"> <!-- カードの表面 --> <div class="package-face package-front"> <div class="img-wrapper"> <img src="img/package-1.jpg" alt="" /> </div> <div class="package-text"> <h4 class="package-name">Discover Japan</h4> <p class="package-paragraph"> in-depth cultural experience </p> </div> </div> <!-- カードの裏側 --> <div class="package-face package-back"> <p class="package-tags"> <span class="tag place">Kyoto, Tokyo</span> <span class="tag culture">Culture</span> <span class="tag food">Food</span> </p> <h5 class="price">$3,900</h5> <p class="term">10 days</p> <button class="btn primary-btn">Check More</button> </div> </div> ..... </div> カードの表面と裏面を CSS でスタイリング+ 3D のスタイリング (style.css) /* カード全体のラッパー */ .packages-wrapper { width: 100%; height: 70%; padding: 3rem 0 4rem 0; display: flex; flex-direction: row; /* Perspectiveを指定することで、このラッパーを3Dで使うよう指定。値はユーザーからの距離を表していると考える */ perspective: 1000rem; -webkit-perspective: 1000rem; -moz-perspective: 1000rem; -ms-perspective: 1000rem; } /* カード単体の大きさなどスライリング */ .package { width: 300px !important; height: 400px !important; /* perserveを指定することで、これのラッパーから3D環境を受け継ぐ*/ transform-style: preserve-3d; -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; position: relative; margin: 0 0.5rem; box-shadow: 0.1rem 0.1rem 0.1rem rgba(0, 0, 0, 0.3); } /* カード表面と裏面共通クラスのスタイリング */ .package-face { width: 100%; height: 100%; position: absolute; top: 0; left: 0; } /* カード表面 */ .package-front { display: flex; flex-direction: column; justify-content: flex-end; text-align: end; transform: rotateY(0deg); -webkit-transform: rotateY(0deg); -ms-transform: rotateY(0deg); position: relative; /* この面が表にある時裏側を隠す */ backface-visibility: hidden; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; } .package-text { position: absolute; bottom: 3rem; right: 2rem; } .package-text > *, .package-back > * { color: var(--white-color); text-shadow: 0.1rem 0.1rem 1rem var(--secondary-color); font-family: var(--main-font-family); } .package .package-name { font-size: 2rem; padding-bottom: 1rem; } .package-paragraph { font-size: 1rem; } /* カード表面 */ .package-back { background-color: var(--secondary-color); display: flex; flex-direction: column; justify-content: center; align-items: center; /* 裏側になるので、rotateしてスタイリング */ transform: rotateY(180deg); -webkit-transform: rotateY(180deg); -ms-transform: rotateY(180deg); backface-visibility: hidden; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; } .package-tags { font-size: 1rem; } .price { font-size: 1.8rem; font-weight: 400; padding: 2.2rem 0; } .term { font-size: 1rem; margin-bottom: 4rem; } .package .img-wrapper img { opacity: 1; } キーワード ⭐︎Perspective -> 親要素に 3D 環境設定。 ⭐︎Transform-style: preserve-3d -> 子要素にも引き継ぐ。 ⭐︎表面、裏面共通クラスでポジションをスタイリング、rotate にて表裏に配置。 3 . Swiper.js のインポート 自分のScript.jsファイルで、Swiperオブジェクトのカスタムをするので、必ず、そのあとでインポートすること!    ドキュメンテーションを見ながら、 HTMLのタグ内にSwiperクラス名を追記(上記のHTML参照)、 CSSでSwiperオブジェクトのスタイリングをすること。 私はcoverflowのエフェクトを使用しました。 (index.html) <script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script> <script src="script.js"></script> (script.js) var swiper = new Swiper(".mySwiper", { effect: "coverflow", grabCursor: true, centeredSlides: true, slidesPerView: "auto", coverflowEffect: { rotate: 100, stretch: 0, depth: 100, modifier: 1, slideShadows: true, }, pagination: { el: ".swiper-pagination", }, }); 感想 最初はCSSでスタイリングするときに、3Dにするためのプロパティなどベンダープリフィックスは意識しないでやってました。 開発中はChromeでやっていて、特に問題はなかったのですが、Safariで確認した時に、一部transformプロパティが効いておらず、ベンダープリフィックスを追加したところ、正常に動作しました。   今回はポートフォリオに乗せるプロジェクトの開発の一環で、ウェブデザインから開発まで行いました。 最終的にできたものはこちらになります。 参考 3DのTransformプロパティについてはこちらを参考にしました。 Intro to CSS 3D transforms 使ったライブラリ: Swiper.js
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む