Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all 8771 articles
Browse latest View live

同じ行に中央寄せと右寄せを混在させたい…!(CSS)

$
0
0

はじめに

エンジニアならHTMLとCSSは出来て当たり前だと言われてますが、意外と奥が深く、調べないと分からない場面って結構ありますよね!
今回は、私が先日遭遇した、調べないと分からなかったCSSについてご紹介します!

今回やりたかった事

Image from Gyazo
こんな感じで、ヘッダー内にロゴを中央寄せ、メニューアイコンを右寄せに配置しようとしました。

flexbox を使えば、
Image from Gyazo
Image from Gyazo
2つの要素を片側に寄せたりとか、端と端に寄せたりとかは簡単なのですが、

1つを中央、もう1つを右端(もしくは左端)に配置したい場合は、どうしたら良いのでしょか?

さっそく見ていきましょう!

方法

今回は、以下の状態から説明スタートです。
Image from Gyazo

<divclass="header-item"><h3>Goutfit</h3><iclass="fas fa-bars"></i></div>
.header-item{display:flex;}h3{margin:0;line-height:50px;}i{line-height:50px;font-size:20px;}

line-heightとかサイズとか調整して、display flex で横並びにしてある状態です。

上記のCSSにjustify-contentを追加します。

.header-item{display:flex;justify-content:center;//追記}h3{margin:0;line-height:50px;}i{line-height:50px;font-size:20px;}

Image from Gyazo
justify-content: center; で、取り敢えず要素を中央寄せにしました。

ここから、さらにアイコンだけを動かしていきます!

.header-item{display:flex;justify-content:center;position:relative;//追記}h3{margin:0;line-height:50px;}i{line-height:50px;font-size:20px;position:absolute;//追記right:0;//追記}

親要素に position: relative; を追加。
アイコンに position: absolute; を追加し、
親要素を機転に right: 0; とします。

すると、
Image from Gyazo

求めていた配置にする事ができました!!

まとめ

flexbox だけでは出来なかった配置も、
position を組み合わせる事で可能となります!

今回の記事が少しでも参考になれば嬉しいです!


marginなどの指定方法、ショートハンド(省略方法)

$
0
0

上、右、下、左の順に指定する方法

.block{margin:50px20px50px20px;}

四方同じ数値で指定する方法

.block{margin:50px;}

上下、左右の順に指定する方法

.block{magin:50px20px;}

上、左右、下の順に指定する方法

.block{margin:50px20px80px;}

Power Apps Component FrameworkでGitHubAPIを使ったコントロールを作成する

$
0
0

Power Apps Component Framework でコントロールを作成する

この記事はこちらの動画をもとに作成してあります。

Power Apps Component Frameworkとは

キャンバスアプリやモデル駆動型アプリのUIを作成するフレームワークのことです。
例えば数値を入力するスライダーや、日付を入力する際にカレンダーなどUIの部品を作成できます。
詳細はPower Apps Component Frameworkの概要で説明してあります。

環境構築

まずはMicrosoft Power Apps CLIをインストールする必要があります。
Microsoft Power Apps CLIはカスタマイズの作成、構築、デバッグ、公開を行うコマンドのことです。
Microsoft Power Apps CLIインストールとコマンド一覧に詳細が書かれています。
不足しているものをインストールしておいてください。

component framework プロジェクト作成

プロジェクトを作成したいディレクトリに移動しておきます。
以下のコマンドを実行します。

> pac pcf init --namespace [specify your namespace here] --name [Name of the code component] --template [component type]

今回はコンポーネントのタイプをフィールドに設定します。

>pac pcf init -ns fic -n GitControl -t field
PowerApps component framework プロジェクトが 'C:\Microsoft\GitControl' 内に正常に作成されました。
プロジェクトの依存関係をインストールするために、このディレクトリで 'npm install' を実行してください。

Node.jsのパッケージをインストールします。

>npm i

作成したプロジェクトをVisual Studio Codeで開きます。

>cd GitControl

>code .
(Visual Studio Codeが起動)

作成したプロジェクトのファイルに以下が用意されているか確認します。

  • PCF コントロールフォルダ
    • マニフェスト(ControlManifest.Input.xml)
      • control metadata
      • configuration propaties
      • resources
    • コントローラ(index.ts)
      • init()
      • updateView()
      • getOutputs()
      • destroy()

コントローラにデフォルトで用意されているメソッドについて軽く説明します。

  • init()
    • indexが呼び出されたときに最初に1度だけ処理される
  • updateView()
    • スクリーンサイズが変わったときやイベントが走った時などに呼び出される
  • getOutputs()
    • UIに送るreturn値の定義
  • destroy()
    • 全てのイベントハンドラのClean up用

画面にテキストボックスを表示/valueの取得

マニフェスト修正

namespaceは大文字始まりが良いようです。
ControlManifest.Input.xmlを修正します。

<?xml version="1.0" encoding="utf-8" ?><manifest><controlnamespace="Fic"constructor="GitControl"version="0.0.1"display-name-key="GitControl"description-key="GitControl description"control-type="standard"><!-- property node identifies a specific, configurable piece of data that the control expects from CDS --><propertyname="gitUsername"display-name-key="Property_Display_Key"description-key="Property_Desc_Key"of-type="SingleLine.Text"usage="bound"required="true"/>

 ...

エレメントの追加

画面にテキストボックスとイメージを追加します。
init()に以下を追記します。

publicinit(context:ComponentFramework.Context<IInputs>,notifyOutputChanged:()=>void,state:ComponentFramework.Dictionary,container:HTMLDivElement){lettextbox=document.createElement("input");letimage=document.createElement("img");container.appendChild(textbox);container.appendChild(image);}

ここでビルドを走らせ、ファイルが更新する度に自動でビルドを行うようにします。

> npm run build

実際に追加したテキストボックスを見てみたいと思います。

> npm start watch

画面が切り替わり、テキストボックスが表示されていたら成功です。
イメージをまだセットしていないため、画像は表示されません。

image.png

valueの取得

init()に以下を追加します。

letusername=context.parameters.gitUsername.raw||"";lettextbox=document.createElement("input");textbox.value=username;

これでgitUsernameをセットした状態で画面を更新するとテキストボックスにデフォルト値が入ります。

GitHubAPIを使ってみる

テキストボックスに入力されたユーザネームからアバターを表示してみます。
まずは、ユーザネームからアバターを取り出すメソッドをindex.tsに追加します。

privateasyncsetAvatarImage(imageContainer:HTMLImageElement,username:string){constresponse=awaitfetch("https://api.github.com/users/"+username);constbody=awaitresponse.json();imageContainer.src=body.avatar_url;}

                                
次に、テキストボックス内のテキストが変更された時に呼び出されるイベントハンドラをindex.tsに追加します。

publictextboxOnChange():void{this._value=this._textbox.value||"";this.setAvatarImage(this._image,this._value);this._notifyOutputChanged();}

このままだと変数未定義のエラーが出てしまうので、必要な変数を定義していきます。

exportclassGitControlimplementsComponentFramework.StandardControl<IInputs,IOutputs>{private_notifyOutputChanged:()=>void;private_textbox:HTMLInputElement;private_image:HTMLImageElement;private_value:string;private_textboxOnChange:EventListenerOrEventListenerObject;

init()が呼び出されたタイミングでこれらの変数に値を入れていきます。

publicinit(context:ComponentFramework.Context<IInputs>,notifyOutputChanged:()=>void,state:ComponentFramework.Dictionary,container:HTMLDivElement){this._notifyOutputChanged=notifyOutputChanged;this._textboxOnChange=this.textboxOnChange.bind(this);letusername=context.parameters.gitUsername.raw||"";// Add control initialization codelettextbox=document.createElement("input");textbox.addEventListener('input',this._textboxOnChange);textbox.value=username;this._textbox=textbox;letimage=document.createElement("img");this._image=image;container.appendChild(textbox);container.appendChild(image);}

最後に、変更されたusernameをgitUsernameプロパティにセットするためにgetOutputs()を使って定義します。

publicgetOutputs():IOutputs{return{gitUsername:this._value};}

これでテキストボックス内を変更するたびにAPIが呼び出されアバターが更新されます。
また、画面右側のデータの出力の値もテキストボックスが変更される度に更新されます。

image.png

アバターの枠を変更する

ドロップダウンでアバターの枠を変更できるように設定してみます。
まずはプロパティを追加します。

<propertyname="gitUsername"display-name-key="Property_Display_Key"description-key="Property_Desc_Key"of-type="SingleLine.Text"usage="bound"required="true"/><propertyname="imageShape"display-name-key="Property_Display_Key"description-key="Property_Desc_Key"of-type="Enum"usage="input"required="true"><valuename="square"display-name-key="square"description-key="Square">Square</value><valuename="circle"display-name-key="circle"description-key="Circle">Circle</value></property>

次にinit()から追加したプロパティを受け取ります。
gitUsernameを受け取るタイミングでshapeも受け取ります。

letusername=context.parameters.gitUsername.raw||"";letshape=context.parameters.imageShape.raw;

次に、cssファイルを追加します。
GitControlフォルダにcssフォルダを追加し、GitControl.cssファイルを作成します。

GitControl\css\GitControl.css
.Fic\.GitControlimg{border-style:solid;border-width:5px;border-color:#742774;height:150px;width:150px;}.Fic\.GitControlinput{width:-webkit-fill-available;}.Fic\.GitControl.circle{border-radius:50%;}

これで実行すると、アバターに枠がついています。

しかし、この状態でimageShapeをcircleに変更してもアバターの枠を変えることはできません。
initializaは文字通り1度しか呼ばれないからです。
ここからは枠を丸く変化させる実装をしていきます。

publicinit(context:ComponentFramework.Context<IInputs>,notifyOutputChanged:()=>void,state:ComponentFramework.Dictionary,container:HTMLDivElement){this._notifyOutputChanged=notifyOutputChanged;this._textboxOnChange=this.textboxOnChange.bind(this);letusername=context.parameters.gitUsername.raw||"";// Add control initialization codelettextbox=document.createElement("input");textbox.addEventListener('input',this._textboxOnChange);textbox.value=username;this._textbox=textbox;letimage=document.createElement("img");if(shape=="Circle"){image.classList.add("circle")}this._image=image;container.appendChild(textbox);container.appendChild(image);}

これで「circle」に設定してからリロードすると
アバターの枠が丸くなったかと思います。

image.png

しかし、代わりにアバターがクリアされてしまいます。
アバターをセットするタイミングは、テキストボックスを変更したときしか用意されていないためです。
ここでinit()に、枠と同時にアバターをセットするコードを追加します。

letimage=document.createElement("img");if(shape=="Circle"){image.classList.add("circle")}this.setAvatarImage(image,username);this._image=image;

これでリロードしてもセットしていたusernameからアバターを表示することができます。

フィールドレベルのセキュリティ実装

ここからはフィールドレベルのセキュリティを実装します。
初めに、読み取り専用の際は変更無効のロジックをupdateView()に追加します。

publicupdateView(context:ComponentFramework.Context<IInputs>):void{// Add code to update control viewthis._textbox.disabled=context.mode.isControlDisabled;}

次にページを離れた時のイベントの破棄をdestroy()に実装します。

publicdestroy():void{// Add code to cleanup control if necessarythis._textbox.removeEventListener('input',this.textboxOnChange);}

デプロイ

ここまでできたらデプロイしていきます。

まずは埋め込むアプリを認証する必要があります。
認証プロファイルの作成から行いましょう

使用法: pac auth [create] [list] [select] [delete] [clear]

    create                      認証プロファイルを作成してこのコンピューターに保存します
    list                        このコンピューターに保存されている認証プロファイルをリストします
    select                      アクティブにする認証プロファイルを選択します
    delete                      特定の認証プロファイルを削除
    clear                       このコンピューターに保存された認証プロファイルをすべてクリア

こちらに従って

> pac auth create -u [環境URL]

環境URLはDynamics 365 Administration Centerから確認することができます。

サインインを求められますので、アカウント名とパスワードを入力してください。

認証が正常に作成されました。
接続の検証中...
接続先...[環境名]

こちらが表示されたら成功です。
コンポーネントをプッシュしていきます。

--publisher-prefix          CDS ソリューション発行者を表すカスタマイズの接頭辞の値 (エイリアス: -pp)
--verbosity                 一時的なソリューション ラッパーをビルドする際の MSBuild の詳細レベル。 (エイリアス: -v)
                            値: minimal, normal, detailed, diagnostic
--force-import              Force a full update of the control (エイリアス: -f                 テレメトリ設定の管理

-pp で接頭語を入れます。

> pac pcf push -pp fic

初回のプッシュは3分ほどかかります。

現在の組織に一時的なソリューション ラッパーをインポート: 完了。
Updating the control in the current org: done.

プッシュが完了しました。
今後のプッシュは修正箇所のみがプッシュされる為、より早くなります。

作成したソリューションを使う

それではソリューションを確認します。
ブラウザでPowerAppsの左メニューからSolutionsを開くとPowerAppsTools_ficが追加されていることがわかります。

image.png

ここでGitHub_usernameを格納するフィールドを、任意のエンティティに用意します。
データの型はsingle line textとしておいてください。
フィールドのプロパティを開き、コントロールを追加します。
Controlsタブを選択し「Add Control...」から作成したコントロールを選びます。
Web, Phone, Tablet全てにチェックを入れます。
下のプロパティをcircleに設定しておきます。

image.png

フォームに作成したフィールドを挿入し、実際にアプリを動かして見ると、アバターが表示されます。

image.png

これでGitHubのユーザ名を登録する際に、正しく入力することができているかアバターを使って確認できるようになりました。

なるほどメモ_1

$
0
0
ひとつの親要素の中で子要素をそれぞれ左寄せと右寄せにするには...

親要素に対して
display: flex;
justify-content: space-between;


太字じゃなくするのは

font-weight: normal;


行の高さを指定するのは

line-height:px;


スクロールしても固定させるのは

position: fixed;

固定部分と画像が重なるときは、

z-index: 9999;


背景画像を指定するのは

background-image: url();

背景画像を領域いっぱいに広げるのは

background-size: cover;


padding:上 右 下 左;


liの中にaタグ使ってるときのテキストスタイルを変更するときはaタグに対して指定する

a{
text-decoration: none;
color:white;
}


SCSSの環境構築方法いろいろ

$
0
0

SCSSとは?

SCSSは、CSSに演算機能や変数、ネストなどを用いることで、より効率的に書けるようにした、Sassの記法の1種です。
Sassには、SASS記法とSCSS記法があります。
SASS記法では中かっこを使用しないので、可読性やCSSとの互換性と引き換えに、より短く書くことができます。
SCSS記法ではCSSと同様に中括弧{}を使用するため、SASS記法と比べて見た目がCSSに近くなり、可読性が高まったりCSSを混ぜて記述することができるといったメリットがありますが、少しだけコードが長くなります。

コンパイルの方法

ブラウザはHTML、CSS、JavaScript以外の言語を読み込むことができないので、拡張子が.scssのSCSSは事前にCSSに変換してあげる必要があります。このSCSSからCSSに変換する作業のことをコンパイルと言います。
コンパイルの仕方はいくつかありますが、ここでは4つの方法を紹介します。

①専用のサイトを使用する方法

SassをCSSに変換してくれる、Sass Meisterというサイトがあります。
このサイトでは、下の写真のようにSassで書いたコードを自動でCSSにコンパイルしてくれるので環境構築も必要なく、とりあえず試してみたい学習者に適しています。
SassMeister _ The Sass Playground! - Google Chrome 2020_03_30 1_58_24.png

②Rubyを使う方法

この方法は、自身のパソコンにRubyをインストールしている必要があります。
Macを使用している方はデフォルトでRubyが入っているので問題ありませんが、Windowsを使用している方はセットアップが必要です。
Windowsを使用している方はこちらからダウンロードした後、画面に従ってインストールを行ってください。
----------------ここからはMac、Windows共通で行う必要があります。-------------------------
ターミナル(コマンドプロンプト)を起動して、以下のコマンドを打ち込んでください。

$geminstall sass

これでインストールに成功すれば準備完了です。
SCSSを記述しているファイルがあるディレクトリに移動して以下のコマンドを実行してください。

$sass qiita.scss:qiita.css

ファイル名は適宜変更してください。
コロンの前が元のSCSSファイル名、後が生成されるCSSファイルの名前になります。
これだけです。
これを実行すると、SCSSがあったディレクトリにCSSファイルが新たに生成されます。
このコマンドには実行時にオプションを付けることができます。

①圧縮オプション

$sass qiita.scss:qiita.css --style compressed

これを実行すると改行がない圧縮された状態で出力されるので、可読性の低下と引き換えにサイトの表示を早めることができます。
基本的にスタイルシートはSCSSを使って管理することになると思うので、CSSファイルの可読性の低さはあまり問題にはならないと思います。

②監視オプション

$sass--watch qiita.scss:qiita.css

開発途中で毎回コマンドを実行するのはあまりにも効率が悪いです。
このコマンドを実行すると、SCSSファイルの変更を検知して、その部分をCSSファイルに自動で反映してくれます。
開発中は基本的にこれを使うことになると思います。

GUIソフトを使用する方法

Sassには、コンパイルするためのGUIソフトが用意されています。
よく使われるのは、PreprosKoalaです。

Prepros

Prepros 2020_03_30 2_30_30.png

Koala

Koala - a cool tool for web developers 2020_03_30 2_33_30.png
PreprosもKoalaも使い方はほとんど同じです。
ファイルをドラッグして、コンパイルしたいファイルを選択、Preprosなら右下のProcess Fileを、KoalaならConpileをクリックすれば終わりです。

VSCodeを使用する方法

エディタであるVSCodeでも、拡張機能を使用することでコンパイルが可能です。
Live Sass Compilerという拡張機能をインストールして有効化すると画面の右下にWatch Sassというボタンが表示されます。
これをクリックすると、自動でSassのコンパイルが始まり、変更があればその都度CSSファイルに反映してくれます。

まとめ

長くなりましたが、これでSCSS(正確にはSASSも)を使う準備ができました。
実際にSCSSを書く時の記法はこちらをご覧ください。

SCSS記法まとめ

$
0
0

この記事はSCSS環境構築まとめの続きという位置づけで書いています。

子孫セレクタのネスト

SCSSでは子孫セレクタをネストして書くことができます。
CSSの場合

style.css
navul{background-color:#f00;}navli{color:#ff0;}

SCSSの場合

style.scss
nav{ul{background-color:#f00;}li{color:#ff0;}}

このようにネストしてまとめて書くことができるので、親子関係がわかりやすくなります。

子セレクタ、隣接セレクタのネスト

子セレクタや隣接セレクタのみをネストしたい場合もあります。
CSSの場合

style.css
ul{background-color:#ff0;}ul>li{color:#f00;}

SCSSの場合

style.scss
ul{background-color:#ff0;>li{color:#f00;}}

このように、子セレクタの頭に>を付けるだけで、子セレクタ扱いになります。
隣接セレクタの場合は、>の代わりに+です。

疑似クラス、疑似要素のネスト

疑似クラスや疑似要素もSCSSではネストして書くことができます。
CSSの場合

style.css
.save-btn{background-color:#000;}.save-btn:hover{background-color:#f00;}

SCSSの場合

style.scss
.save-btn{background-color:#000;&:hover{background-color:#f00;}}

上のように、ホバー時やクリック時、:beforeや:afterなどもすべてネストして記述することができます。

プロパティのネスト

一部のプロパティもネストすることができます。
CSSの場合

style.css
.box{font-color:#000;font-weight:"bold";}

SCSSの場合

style.scss
.box{font:{color:#000;weight:"bold";}}

このように、font-colorとfont-weight、background-colorとbackground-imageなどの初めの単語が同じプロパティはネストして書くことができます。

メディアクエリのネスト

メディアクエリもネストすることができます。
CSSの場合

style.css
div{margin:010px;}@media(max-width:670px){div{margin:0;}}

SCSSの場合

style.scss
div{margin:010px;@media(max-width:670px){margin:0;}}

このように、メディアクエリをネストすることで一目で画面幅とその時に適用させたいCSSを見比べることができます。

変数

SCSSでは色などを変数に格納して開発を効率化できます(CSSでも似たようなことはできますが)
CSSの場合

style.css
.style1{background-color:#f00;}.style2{background-color:#f00;}.style3{background-color:#f00;}

#f00がメインカラーであるとします。
もしメインカラーが#ff0に変更になると、#f00と指定してある場所はすべて変更することになります。
これを解決するのが変数です。

SCSSの場合

style.scss
$main-color:#f00;.style1{background-color:$main-color;}.style2{background-color:$main-color;}.style3{background-color:$main-color;}

値を変数に格納するには、上のように$変数名: 値;のように書きます。
変数を使う利点は、値に変更が生じたときに変数を定義している部分だけ書き換えればすべての値を変更できる点です。

演算

Sassでは値の演算もできます。(これもCSSでも似たようなことが可能です)
CSSの場合
横1920px,縦1042pxの画像を使用している想定です。

style.css
.main-img{width:100vw;height:54vw;/*≒1042÷1920×100vw*/}

このように自分の手で計算してからサイズを指定する必要があります。
SCSSの場合

style.scss
.main-img{width:100vw;height:1042/1920*100vw;}

このように直接計算記号を使うことができるので、計算する手間を省くことができます。
単位の違う値でも計算することができるので、かなり便利です。

関数

SCSSには関数も用意されています。

lighten、darken

style.scss
color:lighten(#fff000,30%);/*#fff000を30%明るくする*/color:darken(#fff000,40%);/*#fff000を40%暗くする*/

↓ これが

style.css
color:#fff999;color:#333000;

こうなる。
このように、lighten関数やdarken関数に色と割合を渡すと、渡した色を渡した割合だけ明るくしたり暗くしたりすることができます。

round

style.scss
height:round(1042/1920*100vw);

↓これが

style.css
height:54vw;

こうなる。

round関数は、入力した値を四捨五入してくれます。

他にも様々な関数がありますが、長くなるうえ、頻繁に使うものでもないのでここでは省略します。

コンポーネント

SCSSでは、ファイルをコンポーネントごとなどで分割して管理することで、保守性を高めることができます。
コンポーネントで分けたファイルを読み込むには、

style.scss
@import"button";
_button.scss
button{width:20px;height:10px;}.blue-btn{background-color:blue;}

この時、"button"を定義するファイル名の頭にはアンダースコア_を入れる必要があります。

継承

SCSSでは、スタイルを継承してコードを短くする仕組みもあります。
CSSの場合

style.css
.btn{width:50px;height:20px;}.blue-btn{width:50px;height:20px;background-color:blue;}

CSSで書くと、このように同じスタイルを何度も書く必要が出てくる時があります。

SCSSの場合

style.scss
.btn{width:50px;height:20px;}.blue-btn{@extend.btn;background-color:blue;}

SCSSを使うと、このように共通のスタイルは@extendを使うことで省略することができます。

まとめ

ミックスインなどの機能もありますが、一部の機能は記事の長さと私自身がいまいち理解できていないという面から省略しています。
もし興味があったらリファレンス等で調べてみてください。
SCSSを使うと、コードの省略や分割の面でかなり有利になります。
SCSS便利なのでどんどん使っていきましょう!!

【Vue + vue-mq】レスポンシブ対応でのVue実装について

$
0
0

目次

レスポンシブ対応での課題
レスポンシブ対応での課題解決方法
vue-mqとは
vue-mqの実装方法
vue-mqでのデメリット
vue-mqのseo要件が満たされない可能性とは
vue-mq実装時の動き

レスポンシブ対応での課題

一般的な実装方法としては、PCやスマホなど各デバイス毎に各HTMLファイルを複数用意し最適化する手法を取っています。
レスポンシブ対応では、1つのHTMLファイルを、CSS3(Media Queries)で制御し、異なる画面サイズに応じてページのレイアウト・デザインを調整します。
その際、ここで問題となるのが「1つのHTMLファイル」。
一般的な実装方法を先ほど記載しましたが、基本PC・SPでHTMLが分かれている。
つまり、PC用のデザイン、SPの用のデザインとなっているため、それに合わせてHTML構造も異なります。

レスポンシブ対応する際は、デザイナーがPC・SPでの表示を考慮してデザインしたものを対応する場合はそこまで困らないですが、
今まであったものをそのままレスポンシブで対応するとなると、
デザイン的に考慮されていなかった表示をレスポンシブで対応しなければいけません。

そのため、「1つのHTMLファイル」とCSS3(Media Queries)での制御では実装的に苦しい部分が出てきます。

今回は、まさにこの内容で、
「今まであったものをそのままレスポンシブで対応」という要件があり、
HTML構造がPC、SPを「1つのHTMLファイル」で対応するとCSS側がごちゃごちゃするので、
こういった部分にだけ、vue側もレスポンシブ対応させようと思いました。

レスポンシブ対応での課題解決方法

上記、課題解決の方法として、
vue実装であれば、「vue-mq」plugin を使用することで、課題解決ができそうだったので、
「vue-mq」plugin を試してみることにしました。

vue-mqとは

vue-mqは、Vueを使用してレスポンシブのブレークポイントを定義できるライブラリです。
セマンティックおよび宣言的にモバイルファーストの構築が行えます。

簡単にお伝えするとCSSのMedia QueriesのHTML版と考えてもらえるとわかりやすいかと思います。

vue-mqの実装方法

基本的にはドキュメントを参考に実施してもらえれば問題なくできるかと思います。

ドキュメント:https://www.npmjs.com/package/vue-mq

一応、こちらにも実施手順を記載します。

1.Installation

Using NPM

npm install vue-mq

Using Yarn

yarn add vue-mq

2.ファイル作成

touch src/plugins/vue-mq.js

3.vue-mq.jsにブレイクポイントを記載

importVuefrom'vue'importVueMqfrom'vue-mq'Vue.use(VueMq,{breakpoints:{sp:959,pc:960},defaultBreakpoint:'sp'})

4.nuxt.config.ts(nuxt.config.js)にのplugins内にvue-mqを登録

plugins:['~/plugins/vue-mq'],

or

module.exports={plugins:['~/plugins/vue-mq',...],}

5.vue側での実装

<template><div><div>{{$mq}}です</div><divv-if="$mq === 'sp'">
      SPのtemplateです。
    </div><divv-if="$mq === 'pc'">
      PCのtemplateです。
    </div></div></template>

これにより、レスポンシブの対応で実装したMedia Queries同様に
vue側も表示領域に合わせたDOMに切り替わるため、
vueファイルは1つのままで、表示を切り替えることが可能となります。

vue-mqでのデメリット

基本的にレスポンシブ対応には重宝すると思われる「vue-mq」ですが、いくつかデメリットも考えられます。

1、レスポンシブ対応と言いつつ、PC・SPでvue実装を分けているため、負債が多少残る可能性がある。(テンプレートを分けているのと似ているため)
2、SEO要件が満たされない可能性がゼロではない。(ここは最後に少しお話しします。)

大きなデメリットは無いと思われるものの、
よく考えてみると見えていなかったデメリットも見えてくるので実施に使用するか否かの判断は
慎重に決める必要があるかなと思います。

vue-mqのSEO要件が満たされない可能性とは

vue-mqは実際のHTMLにはソースとして入っていないため、googleBotが正確に認識できているかという点が挙げられます。
よくSPAはSEO上はよくないとか、そういう話が昔あったと思います。
vue-mqの特徴として「画面サイズに応じてクライアントサイドで再レンダリング」されます。
そのためSSRとはまた違った動きになります。

注目すべき点は1つで、
「クライアントサイドで再レンダリングされる」、これがSEO的に問題ないか?という点になります。

私もここは気になったので少し調べてみたところ、そちらの内容を検証されている方の記事がありました。
https://logmi.jp/tech/articles/321993

内容的には以下になります。

・2019年5月にGooglebotが急にアップデートを発表
・アップデートにより「Webブラウザでユーザーが表示するのとまったく同様に」Googlebotがクローリングしてくれるようになった
・検証結果としてPC、SPでの表示内容をGooglebotが認識している

上記内容から、
クライアントレンダリングがSEO的に問題と思われる節がありましたが、
そのような内容が解決してきている状況と見えそうですね。

vue-mq実装時の動き

vue-mqを実際に実装した際の動きをcodepenに入れてみました。
下記のようにサイズが変化することで表示される内容が切り替わります。

See the Pen vue-mq sample by miyawash (@miyawash) on CodePen.

コードの写経したけど、動かない件

$
0
0

コードの写経したけど、動かねぇ...

そんなことは、初心者あるあるかと思います。

いちいち、自力で違いをチェックするのも面倒でしょう。

そんな時は、diffコマンドがおすすめ。(完成品ファイルがある時に限る。)

diffコマンドの使い方

diff [オプション] オリジナルファイル 新しいファイル

が基本です。

結果としては、例えば

1c1
< a
---
> b

などと返ります。

これは、オリジナルファイルの1行目がaから、新しいファイルの1行目がbに変わったという意味ですね。

ちなみに、変更が複数行にわたる時は、数字の部分が1,2とかなります。

コマンドの返りの意味

cは変更の意味ですが、dは削除、aは追加という意味ですね。


【0円ipadプログラミングの限界に挑む】iPad mini 5だけで本格的なweb開発出来るのかやってみたwwwww

$
0
0

qiita初投稿です。この記事ではipad一台だけでお金かけずにweb開発できるか検証したらどうなったのかを記したものであります。
スクショ及びgif画像多めです。
結果的にはこちら

チョット何言ってるの??

もうちょっと詳しく説明すると、HTMLやCSS、JavaScript更にはJqueryを使って、フロントエンドのweb開発をするということです。Githubも使います。

7.9インチのipadで


勿論、macやwindowsなどのパソコン使用禁止
なんでmini 5なのかというと、手元にあるapple端末がそれしか無いからです。
そんなこと出来るの!?と思った方もいれば、何とは言いませんが過去によく似た記事を見た人はそういえば!と思った方もいるかもしれません。
ですがその記事で紹介されたアプリは一部お金がかかってたのでこの記事で紹介するアプリは全て0円です。

検証

1 用意するもの

  • iPad
  • Bluetoothキーボード(これがないと辛い)

以上!!

2 githubにてRepositoryを作成する

Repositoryがある方は3にスキップ。
iPad版chromeかsafariでGitHubにログインします。
アカウントを持っていない方は「サインアップ」から作ってください。
7003BB5C-683C-4A13-BFCB-4949002B270B.jpeg
083A6CF3-03DD-433D-A281-F7CCB84859AC.png
Repositoryを作成します。
66A5D514-645B-42DF-BECD-07363C8D1700.jpeg
E3E84B11-1DC2-45CC-AEA4-03C0E3A67BDD.png
馴染みのある画面で安心しました。
Repository nameの所は必ず入れてください。僕は「ipadonly」という名前にしました。
create Repositoryを押すとRepositoryの作成が完了しました。
ただ、ここからかなり苦労したので出来るだけ詳しく説明していきます。

3 working copyをインストール~Repositoryの入手(?)

appstoreからworking copyというアプリを入手します。このアプリがあるからこその検証なのです!
8572CFEB-03ED-44E9-911D-35DAB371912B.png
開くとこんな感じ
9228D80E-5883-4ED1-8707-8B77AD903FD8.png
画面の青い文字のCreate(もしくは「Repositories」の右の+)を押すと吹き出しが出てきます。
「Clone repository」を選択します。するとウィンドウが出てくるので
1440AFE8-984E-4279-80D2-6207AAC940D7.jpeg
Sign Inをタップ。すると以下のようなウィンドウが開くので、
FAC5F482-2D21-4BB0-BBDB-40D51D662EC3.jpeg
メアドとパスワードを入力してサインイン!
すると~?
E005E2CC-B001-4259-9868-306E960A5324.jpeg
さっき作ったRepositoryが…出てきた!!!
もうこの時点で感動してきたのは僕だけじゃないはず...
1. Repositoryをタップ
2. URLがニョキっと上に移動するのかわいいすき
3. ウィンドウ右上の「Clone」が「Clone」になるのでタップ
するとッ!!?
82C2C487-FA97-435C-85BA-7D69BF0CBFE4.png
どうやらRepositoryを開けたようです!!!
ステップ3終わり!

4 いよいよweb開発

それでは早速、コードを書きたいと思います!!その前にフォルダを作成しましょう!
1. 「+」をタップ
2. Create directoryをタップ(何でdirectoryなんすかね)
3. 任意の名前を入力。僕は「tekito」にしました。
Enterを押すとフォルダの作成が完了し、勝手にフォルダが開きます。
ezgif-7-96cf3c9fb800.gif
ここから皆さんを驚かせます!

  1. 作成したフォルダを開き、+をタップ。
  2. 「Create text file」をタップします。
  3. 名前を「index」にしてみてください。 するとファイル名の隣に緑色の紙のアイコンが出てきました。画面右上が「plain text」になっているのが分かります。普通のテキストファイルですね。 4B778DEE-0E04-4ECD-911C-9F6EAD1FC95F.pngそれではもう一度、1と2の手順をしてファイルを作成し、 今度は名前を「index.html」にしてみてください。するとどうでしょう? khk.gif

VScodeやん!!!!!!???
なんと!?ファイル名の横のアイコンが紙ではなく「</>」になってる!
しかも画面右上の「plain text」が「HTML」に変化したの、分かりますか!?
これは間違いなくッ!!今僕が作成したファイルはHTML形式!!!
今度こそプログラムが書けるので、

index.html
<html><head><title></title></head><body></body></html>

とりあえずこれだけ書いてみます。するとどうでしょう?
78274A79-3050-456D-A9F0-8909C260B668.png
シンタックスハイライトが付いてるだと!!!?
待ってくださいこれ書いたっていうかコピペして張り付けただけなんすけど!?
これってもしかして...
oh.gif
あっ( ^ω^)・・・
いえ、ただVScodeでお馴染みインテリセンスのような自動補完システムが搭載されているのではと思っただけなんです...なかった...

やっぱりインテリセンスがないとVScode使ってる身としては致命的ですねー...どうすれば

そうだ!appstoreで探すんだ!!!VScodeに負けない無料エディタアプリを!!!
「editor code」で検索っと…
ん?なんだこのアプリは?評価高いやんけ・・・(インスコする音)

!!!!!?!?!???!?

57AB9161-B4E2-457F-BB4D-2657458B2C07.png

キタああああああああああああああああんあんあんあんア”ンッ!!!!!!!


これを…これを求めてたんや!!!!!
今から全力で解説します!!!
まず、以下のアプリをインスコしてください。
FEFB1533-34C1-4AE4-9258-61CE1489410E.png
開きます。
FAD3F9C7-89C6-47CA-9A86-3E50EE8824D2.png
Open Koderをタップ。

ちなみにその上のFollow us nowをタップすると公式のツイッターに飛びます。ツイートの頻度少な過ぎたのでフォローはしませんでした。

52A1D263-B243-47E1-80C1-746467EF6897.png
画面左下の「+」をタップ。
98546165-414B-4551-8C4B-74C9A4DE76A4.jpeg
アイコン好き…
Open Other App’s fileをタップ
ブラウズ➡︎Working copy➡︎ipadonly➡︎tekito➡︎アイコンが「HTML」と書いてある紙の方のindex
の順番にタップします。すると先程開いたindex.htmlが開くかと思います。
66531398-4A92-4B49-804D-55FAEEFEAED3.gif
そしてカーソルを <diの後に持っていくだけでインテリセンスが表示されます!
いや〜これでようやく本格的なプログラミングが出来るわけですよ!
手始めに、色んなタグを使ってHello Worldの出力でもしてみましょう!!

index.html
<html><head><title></title></head><body><div><h1>Hello World!</h1><h2>Hello World!</h2><p>Hello World!</p></div></body></html>

なんと自動的に保存されるのでctrl+sを押さなくていい!!
よし。じゃあクローム開いてindex.htmlをドラッグアンドドロッ
そういやプレビューってどうやるんや。。。
プレビューがないと話になりません。そんな時はworking copyを開いて下のgifの通りにします。
ezgif-7-3cdc30b3b7e1.gif
はい!これでプレビューが表示されました!!
え?何?クロームで表示したい!?
えっと!頑張って表示できるようにはしましたがお勧めできません。割と手間がかかりますし、バグが起きるリスクがあります(起きた)
なによりipadじゃないと無理です。
1. Koder code editorを再び開きます。
2. index.htmlは開いた状態にして、画面上部の歯車アイコンをタップ。
3. Local File Accessをタップ
4. Enable Local File AccessがONになっているか確認します。
5. 太字で「http://...」と書いてあるのが確認できます。その太字で書いてあるリンクをクロームの検索ボックスに貼り付け検索します。
この時、クロームとKoderを分割画面表示してください。
hah.gif
gif、見難いですがよく見るとindex.htmlの7行目が<h1>Hello!あsdhfjkl</h1>になっています。なのにクロームの方のプレビューをよく見るといまだにHello World!になっているのでやめたほうがいいです。
working copyに戻って、今度はindex.cssとindex.jsを作成します。
97B7ADAE-7656-4385-B15D-890EFDDF83AB.png
分割画面に対応してて偉い!
ちゃんとcssとjsのファイルになっていますねー
今度はhtmlとcssがちゃんと動くのか、index.htmlとindex.cssをいじってヘッダーを作りたいと思います。それぞれのファイルはこちらからどうぞ。(開きますかね?)
パソコンだとこんな感じ
an.png
簡単すぎたかな?
じゃあ次!ipadだとどうなるのか!?
7028AAB3-2DC4-4094-A4BA-374942192656.png
明朝体になってて草
それ以外は特に何も変わってなさそうですね!

jqueryは動くのか!?

jqueryはJavaScriptの書き方などを簡単にすることが出来ることで有名ですし、僕もjavascriptそっちのけで勉強してますw
ですが、ipadで書けるのでしょうか...?とりあえず、CDNでやってみたいと思います。
まず、index.html、.css、.jsをこちらの通りとします。
対照実験。パソコンだとjqueryでこんな感じで動いてます。
rd.gif
ではipadではどうんなふうに動くのか!?そもそも動くのか!!?
ene.gif
めっちゃ理想通りに動いてるやんけ…(´;ω;`)
いや~ここまできたらもう感無量です!無事にjquery動いてよかったです!ステップ4大成功!!

5 githubで色んな動作する

commitしてみる

まずcommitをしてみます。windowsではVScodeのターミナルを開いて色々コードを書いてローカルリポジトリにcommitしてpushをしました。
ターミナルの存在しないipadはどうなの?何かあったらやばいのでipadonlyとは別にsampleというリポジトリを作成。適当にhtmlファイルを作成。
画面上部を見る、と
283C9DF7-A647-4D64-8601-603982F2DC63.jpeg
色んなアイコンがありますね...
それらの中で左から3番目の指紋みたいなマークをタップ。
D147F061-0348-4379-8A82-C9C710CF68CE.jpeg
commitをタップ。
7408A66B-C6F6-4220-B21A-183E1660F03F.jpeg
上のテキストボックスにsummaryを、その次にdescriptionを入れる感じかな?
htmlファイルの隣のチェックボックスにチェックを入れてCommitを押せばローカルリポジトリへのcommitが完了します。

pushしてみる

ではリポジトリをプッシュしまsy...
題.png

うっそだろおおおおおおおおお:sob::sob::sob::sob:

どうやらリポジトリやファイルをgithubにpushする動作は有料だそうです。。。
ていうか、commit,revert,pull以外(多分)のgithubの全ての動作が有料でした。パソコンだと何気なく無料で出来るのにipadだと2440円するのはさすがにないと思いました。
ここまでか...いやまだ諦めてない...!!これはあくまでもworking copyなんや...
他のアプリで試すんや...
appstoreで探すんや...gitが使えるツールを...
これはどうかな?IMG_0327[1].PNG
アプリ開いて、サインインして、、、
真面目に説明します。(意味深)
1. サインインしたらヘッダーにNEWSとあります(なんだこれ)。左上の三本線のマークをタップ。
2. RepositoriesのOWNEDをタップ。
3. ipadonlyをタップ。
4. 一番下のSourceをタップ。
5. 編集したいファイルをタップ。(僕はsono2.mdのindex.htmlにしました。)
6. ファイルが開く。
7. 画面右上の共有マークをタップ。からのEditをタップ。
8. ファイルが編集できるようになるので適当に書く。(僕は37行目の「スマホアプリ」を「何か」に変えました。)
9. 編集し終わったら画面右上のsaveをタップ。
10. Upload...と書いてありますが、ここではプッシュのタイトルを記述します。記述し終わったらcommitをタップして完了。
lol.gif
さて、ホントにpushされているのか、windows版githubで確認しようかと思います。
へ.png
されてたああああああああああああああああ
やっときた...ここまできたら

pullもいけるやろ!

今度はpullが出来るかどうか試したいと思います。PCのVScodeでindex.htmlの22行目の「login」を「brain」にしてコードでプッシュ。そしてipadで
ezgi.gif
このアプリで開いたファイルをKoderで編集できるようにします。まず、上の5番の手順まで進めてindex.htmlが開いた状態にしておきます。
1. 画面右上の共有マークをタップ。からの「Open In」をタップ。
2. 横にスクロールして「その他」をタップ
3. Suggestionsの「Koderにコピー」をタップ
4. Koderが開く。Documentsの右下の+マークをタップ
5. New Folderをタップするとファイルを作成できるので、任意のファイル名を入力
6. Createをタップ。作成したファイルを開き、「Done」をタップすると、
初回はそのファイルにindex.htmlをコピーしたやつがインポートされる。
2回目以降は恐らく「ファイルが既に存在しますので上書きしますか?」みたいなことが聞かれるのでyesをタップして上書き。
99.gif

pushしてみる(2回目)

Koderで色々編集した後、command+Aで全選択してコピーしてCode hubでedit modeにしてまた全選択してペースト。するしか方法がないみたいです。効率悪いですね...。
22.gif
この記事もめっちゃ長くなったのでここで検証を終えたいと思います。

検証結果及び感想

今回紹介したアプリは3つ。

  • Working copy:以下、WKと略す。git連携ツール。ここでhtmlファイルなどを作成したり、プレビューを確認できる。2440円課金すればgitの全ての動作が可能。
  • Koder Code Editor:以下、Koder。ここでプログラムを書くことをお勧めする。
  • Code Hub:以下、CH。ここでgitの動作を行うことを勧める。
項目(?)使ったアプリ可能か
htmlファイルなどの作成WK可能
シンタックスハイライトWK、Koder、CH可能
インテリセンスKoder、WK、CHKoderは可能 WKは✖
HtmlCssJsのプレビューWK可能
jqueryWK,Koder可能だがシンタックスハイライトが微妙
github commitWK,CHWK:ローカルリポジトリへのcommitは可能 CH:可能
pushWK,CHWK:課金しないと無理 CH:なんか違う気がするが可能
pullWK,CHWK:課金しないと無理 CH:ゴリ押しでいける

正直ipadのみで、無課金でここまで出来るとは思っておりませんでした。最後にこの記事を書いた本当の目的なんですが、すべてここに書きました。文下手くそかもしれませんがお読みくだされば幸いです。

修正しやすいCSSプリプロセッサの書き方を考える

$
0
0

最近はcssを直接修正することがほぼなく、scssやstylusなどを使って修正をすることがほとんどで、色々なCSSプリプロセッサの機能を使って書くことがほとんどになりました。
その分生のcssを調整する時に感じなかった「こう書かれると困るなー」、「こう書いたけど見にくいなー」というのが色々出てきたので、覚書。

&を使ってのネスト

デベロッパーツールから該当クラスをコピーしてエディターのプロジェクト内検索を行った際、以下のようにネストされると、検索結果に引っかからず目視で該当のクラスを探す必要が出てくるため、&を使用してのネストの多用を避ける。
もしくは使用箇所をmodifireのみに限定する。

// 検索に引っかからない。.block{width:600px;margin:0auto;&__element{font-size:16px;&--modifier1{color:#ff0000;}&--modifier2{color:#00ff00;}}}// 検索に引っかかる。.block{width:600px;margin:0auto;}.block__element{font-size:16px;}.block__element--modifier1{color:#ff0000;}.block__element--modifier2{color:#00ff00;}

extend

該当の要素の修正を行った際、以下のように他箇所でextendされているのを気づかず対応した場合、他箇所に影響が出てしまう。
気づいたとしても対応する場合に新しいクラスを作成する必要が出てくるため、使用する場合は、mixinかプレースホルダセレクタ※を使用する。

// 修正箇所.block1{width:600px;margin:0auto;}// 間に色々な記載// 気づかず影響を受ける箇所.block2{@extend.block;backgroud:#000;}.block3{@extend.block2;margin-bottom:60px;}

※プレースホルダーセレクタの書き方

// プレースホルダーセレクタ、cssにはコンパイルされない%extend-block{width:600px;margin:0auto;}// 他箇所の影響を考えずここだけ修正出来る。.block1{@extend%extend-block;}.block2{@extend%extend-block;backgroud:#000;}.block3{@extend%extend-block;backgroud:#000;margin-bottom:60px;}

演算

式だけ見ると、どういう風に計算されているか分からない場合があるため避ける。
使用する場合は、コメントアウトで補足を入れる。

// 式が不明.block1{width:(690/750*100)vw;}// 式が分かる.block1{// デザイン上の要素の横幅 - デザイン幅 * 100 width:(690/750*100)vw;}

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

$
0
0

100日チャレンジの277日目

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

CSSプロパティの記述順

$
0
0

CSSのプロパティの順番わからない!!

滅茶苦茶分かります。

ということで簡単な調査をしてみました。
結論、

明確なルールは存在しない

ようです。

しかしながら、各企業の提唱する順番はあるようです。

①役割順

firefoxでお馴染みのMozillaさんが提唱しており、サイバーエージェントさんも似た形式を取っているとか。元リンクが削除されていたので、こちらから引用致しました。大まかには、

1.display
2.配置場所
3.ボックスモデル
4.背景
5.テキストなど中身関連

という順番のようです。

②アルファベット順

語る必要もないですが、アルファベット順にプロパティを並べる方法。Google社はこちらを提唱しているようです。

とはいえ面倒...

そんな怠惰なあなたにオススメが「CSScomb」。
VScodeの拡張ツール、プラグインになります。
勝手に順番変えてくれる楽ちんツール。

「gulp-CSScomb」などは、自分好みに設定もカスタマイズできるようです。

静的サイト(HTML/CSSのみ)をherokuでデプロイする方法

$
0
0

HTML/CSSのみでサイト模写したものをherokuでデプロイする方法をまとめています。

ruby on railsでの簡単なWEBアプリケーションのデプロイ経験がありましたが、
HTML/CSSのみの模写サイトのデプロイの仕方が分からずに苦労しました。

静的サイト(HTML/CSS)のデプロイの仕方がまとめられているものが少なかったので、
以下に備忘録として手順をまとめてみました。

1.composer.jsonを作る。

composer.jsonファイルを作成する。中身は{}のみ

composer.json
{}

2.index.phpを作る

index.phpファイルを作成する。中身は↓

index.php
<?phpinclude_once("index.html");?>

ここまでのディレクトリ階層

app
 ├ index.html
 ├ style.css
 ├ composer.json
 └ index.php

ここまでの作業はHTML・CSSだけではアプリケーションとして認識されないようなので、
PHPアプリケーションとしてデプロイする準備。
色々調べてみるとrailsアプリケーションとしてもデプロイできそうだったが、
phpでのこの手順が一番簡単そうでした。

3 herokuでデプロイ

該当のアプリケーションで↓

ターミナル
$ heroku login

アプリを命名する↓

ターミナル
$ heroku create <アプリケーション名>

githubと、作成したレポジトリを紐付けたら
git remoteでherokuが含まれているか確認↓

ターミナル
$ git remote
heroku
origin

リモートに命名したアプリケーションのディレクトリでを設定する↓

ターミナル
$ git remote add heroku https://git.heroku.com/<アプリケーション名>.git
ターミナル
$ vim .git/config

上記コマンドを実行し
[remote "origin"]のurlに、githubの該当リポジトリが当てはまっていればOK
[remote "heroku"]のurlに、先ほど命名したアプリケーションのurl
(https://git.heroku.com/<アプリケーション名>.git)が入っていればOK

または、下記のコマンドでherokuとgithubのレポジトリが一致していればOK

ターミナル
$ git remote -v
heroku  https://git.heroku.com/<アプリケーション名>.git (fetch)
heroku  https://git.heroku.com/<アプリケーション名>.git (push)
origin  https://github.com/hoge/<gitのアプリケーション名>.git (fetch)
origin  https://github.com/hoge/<gitのアプリケーション名>.git (push)

これでpushする↓

ターミナル
$ git push heroku master

以上で、実際に起動すれば完了。

bootstrapでプラスからマイナスへ変化するアイコンを作る

$
0
0

最近

最近はコロナのせいで引きこもっています。楽しみがパンケーキを作ることしかないです。何かちょうど良い趣味教えてください。

bootstrapでプラスからマイナスに変化するアイコンを作る

まずはHTML

index.html
<divclass=""id="collapseListGroupHeading"><ahref="#switch"class="collapsed"data-toggle="collapse"></a><divclass="collapse"id="switch"aria-expanded="false"></div></div>

そしてCSS

style.css
#collapseListGroupHeadinga[data-toggle="collapse"]{padding:10px;text-decoration:none;position:relative;}#collapseListGroupHeadinga[data-toggle="collapse"]::before,#collapseListGroupHeadinga[data-toggle="collapse"]::after{content:"";width:8px;height:0;border-top:#0000001pxsolid;border-bottom:#0000001pxsolid;position:absolute;right:15px;top:12px;bottom:12px;margin:auto;}#collapseListGroupHeadinga[aria-expanded=false]::after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);transition-duration:0.3s;}#collapseListGroupHeadinga[aria-expanded=true]::after{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);transition-duration:0.3s;}

中央寄せの使い分けについて

$
0
0
text-align:centerはインライン要素担当!

ただし、親はブロック要素じゃないと効かない
そして親要素にtext-alignをかく


margin 0 auto;はブロック要素担当!

親要素と同じ大きさだったらwidthで横幅を指定しないと中央寄せにならない

※autoは余白を自動で調整してくれるやつ
左右にautoを指定すると左右中央寄せになる


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

$
0
0

100日チャレンジの278日目

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

position:relative・absoluteの使い方

$
0
0

position→要素の位置を決めるためのもの

:shamrock:relative:

現在の位置を基準に相対的な位置を決める

:shamrock:absolute:

親要素を基準に絶対的な位置を決める
:arrow_forward:絶対的というのは他の要素や余白の有無など他のものに影響されることなく、
その位置に絶対に配置されるということ

<使い方>

①親要素をposition:relativeにして、現在の位置に堂々といてもらう

②動かしたいやつをposition:absolute;にして、親要素基準の位置をtopとかできめる

横スクロールメニュー

$
0
0

ヌルヌルした横スクロールメニュー。

<style>

    .navigation-content {
        position: relative;
        max-width: 800px;
        min-width: 300px;
        width: 100%;
        -webkit-overflow-scrolling: touch;
    }

    .navigation {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        list-style: none;
        overflow-x: auto;
        background: #fff;
    }

    .navigation li {
        padding: 5px 15px;
        color: #b7b7b7;
        word-break: keep-all;
        text-decoration: none;
        border-bottom: 1px solid #e5e5e5;
    }

    .navigation li:hover {
        color: #666;
        font-weight: bold;
        border-bottom: 1px solid black;
    }

</style>


<div class="navigation-content">
    <nav class="navigation">
        <li>
            <a>タイムライン</a>
        </li>
        <li>
            <a>いいね!が多い順</a>
        </li>

        <li>
            <a>ログイン順</a>
        </li>

        <li>
            <a>おすすめ順</a>
        </li>

        <li>
            <a>新メンバー</a>
        </li>

        <li>
            <a>キーワード</a>
        </li>
    </nav>
</div>

コピペで動くよ。

Google Apps Scriptで快適にWEBスクレイピングするためのライブラリを作ったら、重すぎて動かなかったお話。

$
0
0

efgrhj.png
ウガアッ!

作るに至った経緯

GASでのWEBスクレイピングといえば、送られてきたhtmlソースをただの文字列として受け取り、正規表現やmatch、split、indexOfなどで無理矢理目的の要素・テキストを削り出してくるもの。一応スクレイピング用のライブラリもあるが、やっていることは対して変わらない。

「我々が求めるものはPythonのbs4のような、CSSセレクタなどで簡単に要素を見つけ出し、情報を抽出するものではなかろうか?」

そんなこんなで火が付いた。作ったプロトタイプもGoogle Chromeの開発者ツール上では、少々レスポンスが遅いもののキチンと想定道理に動いていたから、やれる自信はあった。再帰呼び出しの回数が多すぎて、どうやってもGASでは動かないと気付いた時、私は燃え尽きた。

どういうライブラリだったか

CSSセレクタベースで要素を見つけるもの。最初は親・子孫要素や属性([attr="hogehoge"])などにも対応させていたが、少しでも再帰呼び出しを減らすため、どんどんオプションを削られ、しまいには親要素からの検索も露と消えた。まあ結局動かなかったけど。というわけでこのライブラリ(笑)は、Google Chromeの開発者ツール上でしか、筆者は正常に動かしたことがない。悲しい。せっかく作ったのに。

呼び出し

varh=HTMLparser(`
<html>
<head></head>
<body>
<p class="cls">htmlソーステキスト</p>
...
</body>
</html>
`);vartag_p=h.search("p.cls");//[{tagname: "p", attr: {…}, innerText: "htmlソーステキスト", tree: Array(1), parent: {…}}]

呼び出し元のコード

functionHTMLparser(html_str){if(!(thisinstanceofHTMLparser)){returnnewHTMLparser(html_str);}else{this.html=[];this.attr={};this.tags={};varhtml_obj={tree:[]};//str: htmlソース, ary: htmlのツリー, parent: 親要素, self: HTMLparserのthisの参照用functionper(str,ary,parent,self){varobj={tagname:"_Node",attr:null,innerText:"",tree:[],parent:null};obj.parent=parent;//開始タグを見つけるvarmatchTag=str.match(/<([a-zA-Z][^\t\n\r\f\/>\x00]*?)(| [a-zA-Z][^\t\n\r\f>\x00]*?[^\/])>([\s\S]*?)$/);//[0]: 全体, [1]: タグ名, [2]: 属性, [3]: その開始タグ以降のテキストfunctionsameTagBothReg(tagname){returnnewRegExp("(<"+tagname+">|<"+tagname+" [a-zA-Z][^\t\n\r\f>\x00]*?[^\/]>|<\\/"+tagname+">)");}functionsameTagStartReg(tagname){returnnewRegExp("(<"+tagname+">|<"+tagname+" [a-zA-Z][^\t\n\r\f>\x00]*?[^\/]>)");}functionsameTagEndReg(tagname,count){returnnewRegExp("(<\\/"+tagname+">)");}varattrReg=/([a-zA-Z][^\t\n\r\f>\x00]*=\".*?\")/g;varattrReg_g=/([a-zA-Z][^\t\n\r\f>\x00]*)=\"(.*?)\"/g;if(matchTag){varattr_obj={};varattr_node_list=matchTag[2].split(attrReg).filter(function(r){returnr.match(attrReg);})attr_node_list.forEach(function(r){//タグの属性を収集vara=r.split(attrReg_g);if(!self.attr[a[1]]){self.attr[a[1]]={};}varv;//クラスのみリスト化if(a[1]=="class"){v=a[2].split("");v.forEach(function(r){if(!self.attr[a[1]][r]){self.attr[a[1]][r]=[];}self.attr[a[1]][r].push(obj);});}else{v=a[2];if(!self.attr[a[1]][v]){self.attr[a[1]][v]=[];}self.attr[a[1]][v].push(obj);}attr_obj[a[1]]=v;});obj.attr=attr_obj;obj.tagname=matchTag[1];//その開始タグの対となる終了タグを見つける//もし開始タグがspanだった場合、その開始タグ以降のテキストから、//spanの開始タグと終了タグをまとめて探索するvarst_cnt=1;//開始タグの数(開始タグはすでに一個あるので、初期値は1)vared_cnt=0;//終了タグの数varsp_idx=0;//目的の終了タグのインデックスvarsplitted_same_tag=matchTag[3].split(sameTagBothReg(matchTag[1]));splitted_same_tag.forEach(function(v,i){if(sp_idx){return;}//開始タグがマッチしたら+1elseif(v.match(sameTagStartReg(matchTag[1]))){st_cnt++;return;}//終了タグがマッチしたら+1elseif(v.match(sameTagEndReg(matchTag[1]))){ed_cnt++;//開始タグ数と終了タグ数が一致したら、インデックスを記録if(st_cnt==ed_cnt){sp_idx=i;}else{return;}}});//始点からインデックスまでが、そのタグの子要素varchild=splitted_same_tag.slice(0,sp_idx).join("");if(matchTag[1]=="title"){self.title=child;}//scriptタグの中には稀にhtmlのタグが紛れ込んでいるので、//誤マッチ回避のため、scriptタグの中身は切り捨てif(matchTag[1]!=="script"){//子要素をターゲットにして自身(obj)を親とし、perを再帰的に呼び出しper(child,obj.tree,obj,self);}//インデックスから終点までが、そのタグの兄弟要素varbro=splitted_same_tag.slice(sp_idx+1).join("");if(bro!==""){//兄弟要素をターゲットにして自身と同じ親要素(parent)//を親とし、perを再帰的に呼び出しper(bro,ary,parent,self);}}else{obj.tree=[str];}ary.unshift(obj);//もしタグ名が見つからなかったら(_Nodeのままなら)、//自身と親・先祖のinnerTextに中身の文字列を追加if(obj.tagname=="_Node"){Text(obj,obj.tree.join(""));functionText(o,txt){o.innerText+=txt;if(o.parent){Text(o.parent,txt);}}}else{if(!self.tags[obj.tagname]){self.tags[obj.tagname]=[];}self.tags[obj.tagname].push(obj);}}per(html_str.replace(/<!--[\s\S]*?-->/g,""),this.html,null,this);}}//検索機能(最も削り取られた部分)HTMLparser.prototype.search=function(selector){varsel=sel_parse(selector);//終端の1要素のみ読み取る//CSSセレクタは「右から」読み取るのが効率的returncheck_tree(sel[0],this);functioncheck_tree(s,self){varr=[];var_tag=s.tag;if(_tag){if(self.tags[_tag]){for(vartofself.tags[_tag]){var_atr=t.attr;if(s.class.length){if(_atr.class){var_chk=false;for(varclsofs.class){if(_atr.class.indexOf(cls)<0){_chk=true;break;}}if(_chk){continue;}}else{continue;}}if(s.id.length){if(s.id[0]!==_atr.id){continue;}}r.push(t);}}}else{varc_ary=[];vari_ary=[];vara_ary=[];//削り取られた残滓if(s.class.length){var_chk=true;varclsList=Object.keys(self.attr.class);for(varclsofs.class){if(clsList.indexOf(cls)<0){break;}else{if(!c_ary.length){c_ary=self.attr.class[cls];}else{c_ary=c_ary.concat(self.attr.class[cls]).filter(function(x,i,self){returnself.indexOf(x)===i&&i!==self.lastIndexOf(x);});}}}}if(s.id.length){varidList=Object.keys(self.attr.id);if(-1<idList.indexOf(s.id[0])){i_ary=self.attr.id[s.id[0]];}}if(s.attr.length){var_chk=false;for(varaofs.attr){var_k=a.atr;var_m=false;if(_k.match(/(\*|\^|\$)$/)){_m=_k.match(/(\*|\^|\$)$/)[1];_k=_k.replace(/(\*|\^|\$)$/,"");}}}varfull_cnt=0;if(c_ary.length){full_cnt++;r=r.concat(c_ary);}if(i_ary.length){full_cnt++;r=r.concat(i_ary);}if(a_ary.length){full_cnt++;r=r.concat(a_ary);}if(1<full_cnt){r=r.filter(function(x,i,self){returnself.indexOf(x)===i&&i!==self.lastIndexOf(x);});}}returnr;}//CSSセレクタの解析用functionsel_parse(sel){if(sel.match(/ ?[\+\~]?/g)){throwError('You cannot use Adjacent sibling combinator "+/~".');}elseif(sel.match(/\:(nth-child\(|nth-of-type\(|not\(|first-child|first-of-type|last-child|last-of-type)/g)){throwError('You cannot use Pseudo-elements like ":nth-of-type()"');}varsp=sel.split(/(?> ?|(?<=[a-zA-Z0-9\]\_\-])(?=[a-zA-Z\[\.\#\_]))/g);vara=[],nxt=false;sp.forEach(function(s,idx){if(s.match(/^ $/g)){return;}elseif(s.match(/^ ?> ?$/g)){nxt=true;return;}var_o={"tag":null,"class":[],"id":[],"attr":[],"next":false};if(nxt){_o.next=true;nxt=false;}var_s=s.split(/(\[.*?\]|(?<=(?:[a-zA-Z\]]|^))(?:\.|\#)[a-zA-Z\_][a-zA-Z0-9\_\-]*)/g).filter(function(r){returnr;});_s.forEach(function(p){if(p.match(/^\#/)){_o.id.push(p.replace(/\#/,""));}elseif(p.match(/^\./)){_o.class.push(p.replace(/\./,""));}elseif(p.match(/^[a-zA-Z]/)){_o.tag=p;}elseif(p.match(/^\[(.*?)(?:\=(?:\"(.*?)\"|\'(.*?)\')|)\]/)){var_m=p.match(/^\[(.*?)(?:\=(?:\"(.*?)\"|\'(.*?)\')|)\]/);_o.attr.push({"atr":_m[1],"que":_m[2]?_m[2]:""});}});a.unshift(_o);});returna;}}

ちなみに、HTMLparserオブジェクトの中身は以下の通り。
dfdgfh.png
treeにはその要素の子要素のリストが、parentにはその要素の親要素への参照が渡されている(図では一番外側のタグのため参照が無い)。下のattrとtagsは検索用の参照のリストが詰まっている。

HTML スクロール時に背景画像を遅らせる

$
0
0

後でコピペできるように残しておきます。

↓わかりにくいですが一応GIF

ダウンロード.gif

注意

スクロール時の背景画像の滑らかさはモニターのスペックに依存してしまうので、スペックの低いモニターだと結構カクツキます。
ゲーミングモニターだと滑らかに動くので良きですが...

下記のコードではScrollイベントを使って背景画像のポジションを弄っているのですが、カクツキを完全になくすためならrequestAnimationFrameやsetIntervalを使わないとダメかも。

準備

背景に使用する画像を、bg.pngという名前で準備しておきました。

HTML

<divid="bg"class="ly_bg"></div>

CSS

.ly_bg{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:-1;background-image:url('../images/bg.png');background-size:100%auto;background-repeat:repeat-y;background-position-y:0;}

JS

letbg=document.getElementById('bg')constrate=3window.addEventListener('scroll',function(){lety=window.scrollYbg.style.backgroundPositionY=`-${y/rate}px`})
Viewing all 8771 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>