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

2画面折りたたみデバイスに対応したCSSメディアクエリ

Galaxy foldシリーズやSurface Duoシリーズなどが登場し、今後2画面折りたたみデバイス向けにWebサイト、Webアプリの対応が求められるようになるかもしれません。 ブラウザの対応も少しずつ進んでいるようなので、調べたことをまとめます。 2画面デバイスを検出するための CSS メディアクエリ 最新のMicrosoft Edge(バージョン96)で試験的な実装ではありますが、二画面デバイスを検出するビューポートセグメントメディアクエリが提供されています。 CSS @media (horizontal-viewport-segments: <count>) { } @media (vertical-viewport-segments: <count>) { } <count>は水平(横長)、または垂直(縦長)の画面デバイス数を設定します。 例えば Surface Duo の2画面デバイス表示では以下の値になります。 水平の場合 horizontal-viewport-segments: 2 垂直の場合 vertical-viewport-segments: 2 CSS環境変数 各ビューポートのプロパティは、次の環境変数定義で取得できます。 env(viewport-segment-width <x> <y>); env(viewport-segment-height <x> <y>); env(viewport-segment-top <x> <y>); env(viewport-segment-left <x> <y>); env(viewport-segment-bottom <x> <y>); env(viewport-segment-right <x> <y>); x座標とy座標は、左上の画面デバイスを00とした画面デバイスの座標です。 Surface Duoの場合、次の値を使用して、各画面デバイスの座標を使用します。 これらの値を利用して、各画面デバイスの四隅の座標や幅、高さを取得できます。 ヒンジの寸法を計算することもできます。 /* 水平(横長)の時のヒンジの幅 */ calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0)) /* 垂直(縦長)の時のヒンジの高さ */ calc(env(viewport-segment-top 0 1) - env(viewport-segment-bottom 0 0)) 使用例 携帯電話は画像とテキストが縦並び、2画面デバイスでは左側のデバイスにテキスト、右側のデバイスに画像を表示するようなレイアウトの場合 HTML <body> <figure class="image"> <img src="/image.jpg"alt="My image"> </figure> <article class="article"> ・・・ </article> </body> CSS /* 最大幅が 420px の一画面デバイスの時 */ @media (max-width: 420px) { ・・・ } /* 二画面デバイスの水平(横長)の時 */ @media (horizontal-viewport-segments: 2) { .article { position: absolute; left: env(viewport-segment-left 0 0); /* 左側のデバイスに表示する */ top: env(viewport-segment-top 0 0); } .image { width: env(viewport-segment-width 1 0); /* 右側のデバイスの幅の大きさで表示 */ position: absolute; left: env(viewport-segment-left 1 0); /* 右側のデバイスに表示する*/ top: env(viewport-segment-top 1 0); } } テスト 二画面デバイス表示に対応したCSSをWebブラウザ上でテストするには、最新バージョンのデスクトップバージョンのEdgeまたはChrome(devtoolsシミュレーターの場合)をダウンロードし、edge://flags(またはchrome://flags)を介して機能フラグを有効にします。 [参考] https://docs.microsoft.com/ja-jp/dual-screen/web/desktop-developer-tools まとめ 想定していたよりも簡単に二画面デバイスに対応したレイアウトを組めそうです。 正式リリースに期待ですね。 Aplleが折り畳み式のiPhoneを開発中との噂もあるので、一足先に触れておくのもありかなという印象です。 参考サイト https://docs.microsoft.com/ja-jp/dual-screen/web/css-viewport-segments https://devblogs.microsoft.com/surface-duo/foldable-css-javascript-edge-96/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

styled-componentsで条件付きmixinをする方法

はじめに styled-componentsで条件付きレンダリングをする場合、以下のように、項目ごとに場合分けをする例をよく見ます 基本はこれで問題ないのですが、場合分けの種類が増えて来ると、管理が面倒になります。 この場合、場合分けの条件ごとにclassのようにスタイリングをまとめたいと思うのが自然だと思います。 そこで、複数の項目をclassの有無のように一気に設定した場合についてわからなかったので、調べました。 const Wrapper = styled.div.attrs((props) => ({ ...props, }))` background: ${(props) => (props.hoge ? '#fff' : '#000')}; ` やりたいこと 以下のようにpropsの条件一つでスタイリングが大きく変わる場合を想定します。 上の場合と下の場合で、個別にcssを管理することを目標とします。 まずはデフォルトの状態を準備 まずは、props.typeに何も指定していない、アニメーションのない状態を実装します。 import React, { VFC } from "react"; import styled from "styled-components"; export type ButtonProps = { className?: string; type?: "bgleft" | "bgright"; }; const Button: VFC<ButtonProps> = ({ className, type }: ButtonProps) => { return ( <WrapperButton className={className} type={type}> <span>ボタン</span> </WrapperButton> ); }; const WrapperButton = styled.a.attrs((props) => ({ ...props }))` /* default */ position: relative; overflow: hidden; text-decoration: none; display: inline-block; border: 1px solid #555; padding: 10px 30px; text-align: center; outline: none; transition: ease 0.2s; span { position: relative; z-index: 3; color: #333; } :hover { span { color: #fff; } } `; export default Button; MixInの定義 次に左右から動作するアニメーションをMixInで定義します。 最初に、styled-componenstからcssをインポートします。 import React, { VFC } from "react"; import styled, { css } from "styled-components"; //ここ 次にMixInを定義します。 それぞれ、左右から動作する部分のcssです。 const MixInBgLeft = css` &:before { content: ""; position: absolute; top: 0; left: 0; z-index: 2; background-color: #333; width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.8, 0, 0.2, 1) 0s; transform: scale(0, 1); transform-origin: right top; } &:hover:before { transform-origin: left top; transform: scale(1, 1); } `; const MixInBgRight = css` &:before { content: ""; position: absolute; top: 0; left: 0; z-index: 2; background-color: #333; width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.8, 0, 0.2, 1) 0s; transform: scale(0, 1); transform-origin: left top; } &:hover:before { transform-origin: right top; transform: scale(1, 1); } `; 条件付きでレンダリング 最後にstyledの中にMixInを条件付きで追加します。 const WrapperButton = styled.a.attrs((props) => ({ ...props }))` //....省略 /* typeにbgleftを選択した場合 */ ${(props) => props.type === "bgleft" && MixInBgLeft} /* typeにbgrightを選択した場合 */ ${(props) => props.type === "bgright" && MixInBgRight} `; このbuttonを使う側は以下のようにして使います。 import Button from '***' <Button type="bgleft" /> // or <Button type="bgright" /> 最後に 今回の例だと、最初に紹介した、項目ごとに場合分けする場合でもよかったかも知れませんが、props.typeが増える場合を考えると、このような方ほでの実装も悪くはないかも知れません。 もっと良い方法があればぜひ共有してください。 最後に全部まとめたコードを貼ります。 import React, { VFC } from "react"; import styled, { css } from "styled-components"; export type ButtonProps = { className?: string; type?: "bgleft" | "bgright"; }; const Button: VFC<ButtonProps> = ({ className, type }: ButtonProps) => { return ( <WrapperButton className={className} type={type}> <span>ボタン</span> </WrapperButton> ); }; const MixInBgLeft = css` &:before { content: ""; position: absolute; top: 0; left: 0; z-index: 2; background-color: #333; width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.8, 0, 0.2, 1) 0s; transform: scale(0, 1); transform-origin: right top; } &:hover:before { transform-origin: left top; transform: scale(1, 1); } `; const MixInBgRight = css` &:before { content: ""; position: absolute; top: 0; left: 0; z-index: 2; background-color: #333; width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.8, 0, 0.2, 1) 0s; transform: scale(0, 1); transform-origin: left top; } &:hover:before { transform-origin: right top; transform: scale(1, 1); } `; const WrapperButton = styled.a.attrs((props) => ({ ...props }))` /* default */ position: relative; overflow: hidden; text-decoration: none; display: inline-block; border: 1px solid #555; padding: 10px 30px; text-align: center; outline: none; transition: ease 0.2s; span { position: relative; z-index: 3; color: #333; } :hover { span { color: #fff; } } /* typeにbgleftを選択した場合 */ ${(props) => props.type === "bgleft" && MixInBgLeft} /* typeにbgrightを選択した場合 */ ${(props) => props.type === "bgright" && MixInBgRight} `; export default Button;
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スマホで見るとレスポンシブが効かない。viewport入れてもダメな時は?

viewportを入れてるのに スマホで見るとレスポンシブデザインが効かない。 だけど パソコンで横幅をスマホサイズに小さくすると しっかりレスポンシブデザインが効いている。 こういうケースがあります。 わたしはこの問題にぶつかったのですが、 viewportのタグを入れてからしばらく時間を置いたら 問題が解決しました。 1viewportを入れてる 2パソコンで横幅を小さくしてみるとレスポンシブが効いている この二つをクリアしている場合 しばらく時間をおいてみてください。 おそらく問題が解決すると思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

flex grow, shrink, basis

flex-grow 子要素全ての幅を足しても親要素の幅100%にならない時、その余白を各子要素間でどの程度負担するかを表す。 デフォルト0。余白があってもほったらかし。負担しない = 伸びない 前提 子1にwidth 30% 子2にwidth 30% => 余白は40%。 子要素間の合計が1以上のケース 子1にflexGrow1, 子2にflexGrow3を設定すると、余白を1:3 で負担することになるので子1が10%, 子2が30%広がる 他の全ての子が0(デフォルト)で、子2だけに1以上が設定された時、余白の全てを子2が負担する事になるので、子2が40%広がり合計70%を占める。 子要素間の合計が1未満のケース 余白は40%なので、flexGrow0.5を設定すると、余白を1とした割合である20%伸びる。 子1がflexGrow0.1, 子2がflexGrow0.1だと、それぞれ4%増える。合計それぞれ34%になり余白はまだある状態。 もし、子1と子2にflexGrow0.8設定し合計が1を超える場合、子要素間の合計が1以上の時と同じ挙動になる flex-shrink 子要素全ての幅を足すと親要素を越える時、その越えた分を各子要素間でどの程度負担する = 縮む かを表す デフォルト1。子要素全てが1なので、超えた分を子要素間で均等に負担する。 例えば子1はwidth 80%,子2はwidth80%の時、Flex無しだと合計160%になり60%はみ出してしまうが、親要素にFlexを適用した途端、はみ出した60%を子要素がそれぞれ30%負担し、widthは80%-30%で50%になる 固定widthが設定されていない要素を含む親要素に対してFlexを設定すると想定外に縮むことがありハマることがある。Flexの子要素全てのwidthは固定されていることを確認するべき!!! <div>{ comment }</div> みたいな子要素があると、子要素が伸びて親要素を超えた分を子要素間で均等に負担し縮んでしまう。縮んでほしくないときも縮んでしまうことがある。 flex-shrink: 0は超えても負担しない = 「縮まない」ということ。他の縮むことができる子要素間で超えた分を負担して縮む。もし全部の子要素がflex-shrink0だとどれも縮まず超えた分は超えたままになる。 子要素間のflex-shrinkの合計が1以上の場合は、それらの比率によって負担割合が決まる。 子要素間のflex-shrinkの合計が1以下の場合は、超えた分を1とした時の割合分縮む。 flex-basis これまで、「本来の子要素の幅」を基準に考えてきたが、それをflexのプロパティとして設定できこれを基準にflexの計算がされる。本来のwidthを上書くイメージ。ただflexのdirectionが縦になるとwidthではなくなることがwidthとは違う。 デフォルトはauto。本来の子要素の幅がそのままflexの計算をする基準値になる 子1と2にflex-basis: 40%を設定すると、合わせて80%のため残り20%は余白になる 子1にwidthを80%, 子2にwidth 200%と設定後、それぞれflex-basis: 50%とすると結果のwidthは50%になり上書きされるイメージ pxの絶対値でも設定可能。 flex grow, shrink, basisを一度に設定できるプロパティ。 flex: <grow> <shrink> <basis> flex: 0 1 20% と書く 参考 https://fuuno.net/web02/flex/flex.html https://fuuno.net/web02/flex02/flex02.html https://developer.mozilla.org/ja/docs/Web/CSS/flex
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Angular Video自動再生されない問題について

背景 時間が経つのは早いもので、そろそろ年末ですね。年末年始といえば、忘年会や新年会などのイベントが多いです。新型コロナはまだ続くと思いますが、感染者数は少なくなり、ようやく居酒屋で一緒に楽しめるようになりました。懇親会を盛り上げるよう、面白い余興を行いますね。その中でもビンゴゲームは定番です。ビンゴカード配り、番号抽選、当選チェック、景品渡し等、幹事さんは大変ですね。特にオンラインの場合、もっと大変です。最近Angularを勉強し始めて、何か作れるかと思って、幹事さん向けのオンラインビンゴゲーム(bingome.net)を作成しました。一般のビンゴ機能以外、受付終了/再開、参加一覧、ビンゴチェック、参加者削除、景品渡しチェック等の機能もあります。ビンゴをやる場合、オンライン、オフラインに関わらず、ぜひご活用ください。 環境 $ng --version v16.13.0 noriharuishi@rgsis bingo % ng --version _ _ ____ _ ___ / \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _| / △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | | / ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | | /_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___| |___/ Angular CLI: 12.2.13 Node: 16.13.0 (Unsupported) Package Manager: npm 8.1.0 OS: darwin x64 Angular: 12.2.13 ... animations, cdk, cli, common, compiler, compiler-cli, core ... forms, material, platform-browser, platform-browser-dynamic ... router Package Version --------------------------------------------------------- @angular-devkit/architect 0.1202.13 @angular-devkit/build-angular 12.2.13 @angular-devkit/core 12.2.13 @angular-devkit/schematics 12.2.13 @schematics/angular 12.2.13 rxjs 6.6.7 typescript 4.3.5 課題 ホームページには説明動画(mp4)があります、ごく普通のvideoタグを使っていますが、chromeでビデオが自動再生されないです。Angularのソースコードは下記の通りです。 app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'sample'; } app.component.html <video muted autoplay playsinline loop> <source src="/assets/bingome.net.mp4" type="video/mp4"> </video> 対策 色々調べてみましたが、原因がわからず、最終的に下記のように修正しましたら、自動的に再生できました。 app.component.html <video [muted]="true" autoplay playsinline loop> <source src="/assets/bingome.net.mp4" type="video/mp4"> </video>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

動きのあるホームページ アイディア

動きのあるおしゃれなWebページを作るときのアイディアの参考 自分用備忘録です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Swiper.jsの矢印が見えない時の対処法【Shopify】

はじめに 株式会社UnReactのレガシーバックエンドこと わだ です。 Swiper.jsを使用する際に Swiper.jsとは jQueryは不要でJavaScriptとCSSでスライドショーを実装することができるとても便利なライブラリです。 npmを利用して実装することができますが、Shopifyではnpmを使用できないのでコードを貼り付ける方法を使用します。 問題点 デモ画像↓ 実際の画像↓ 私の遭遇した問題点は、デモ通りの矢印が現れないという現象です。 正確には、要素は存在するが透明で見えないという状態です。 要素の高さが文字の高さと同じなのは 今回は、私が解決した方法を解説します。 完成物 矢印をFontAwsomeで実装 矢印を外に出す。 永遠ループする。 実装のポイント CodeSandBoxを開く Coreというボタンをクリックすると、CodeSandBoxを開くことができます。 ここで、使用するコードが見られます。 必要なコードの読み込み headタグの末尾に、必要なCSSを読み込みます。 Shopifyではtheme.liquidにheadタグは存在します。 <!-- Link Swiper's CSS --> <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" /> bodyタグの末尾に必要なJavaScriptを読み込みます。 Shopifyではtheme.liquidにbodyタグは存在します。 動きのパラメーターを設定しています。 <!-- Swiper JS --> <script src="//unpkg.com/swiper/swiper-bundle.min.js"></script> <script> var swiper = new Swiper(".mySwiper", { cssMode: true, navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev", }, pagination: { el: ".swiper-pagination", }, mousewheel: true, keyboard: true, }); </script> セクション作成 セクションファイルにhtmlと詳細のCSSを貼り付けます。 swiper.liquid <!-- Demo styles --> <style> html, body { position: relative; height: 100%; } body { background: #eee; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #000; margin: 0; padding: 0; } .swiper { width: 100%; height: 100%; } .swiper-slide { text-align: center; font-size: 18px; background: #fff; /* Center slide text vertically */ display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; } .swiper-slide img { display: block; width: 100%; height: 100%; object-fit: cover; } </style> <!-- Swiper --> <div class="swiper mySwiper"> <div class="swiper-wrapper"> <div class="swiper-slide">Slide 1</div> <div class="swiper-slide">Slide 2</div> <div class="swiper-slide">Slide 3</div> <div class="swiper-slide">Slide 4</div> <div class="swiper-slide">Slide 5</div> <div class="swiper-slide">Slide 6</div> <div class="swiper-slide">Slide 7</div> <div class="swiper-slide">Slide 8</div> <div class="swiper-slide">Slide 9</div> </div> <div class="swiper-button-next"></div> <div class="swiper-button-prev"></div> <div class="swiper-pagination"></div> </div> FontAwsomeの使用 矢印が透明で見えないので、FontAwsomeで矢印を実装します。 headタグにfontawsomeを読み込みもす。 <head> ~略~ <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet" /> </head> 表示したい矢印のfontawsomeのページを探します。 iタグで表示する方法もありますが、swiper.jsのhtml構造を崩したくないので、contentを使用する方法を使います。 .swiper-button-prev::after { font-family: "Font Awesome 5 Free"; font-weight: bold; content: "\f104"; } 設定するCSSは3つです。 font-family font-weight content contentの中にバックスラッシュの後に、fontawsomeのサイトに記載されているコードを入れます。 管理画面から画像を入れるようにする。 blockから画像を呼び出す方法を示します。 swiper.js <div class="swiper mySwiper my-10 md:my-20 max-w-5xl"> <div class="swiper-wrapper mb-10"> {%- for block in section.blocks -%} <div class="swiper-slide"> <img src="{{ block.settings.image | img_url: '800x' }}"> </div> {%- endfor -%} </div> <div class="swiper-button-next"></div> <div class="swiper-button-prev"></div> <div class="swiper-pagination"></div> </div> {% schema %} { "name": "オリジナルスワイパー", "settings": [ { "type": "text", "id": "heading", "label": "Heading" } ], "blocks": [ { "type": "image", "name": "block image", "settings": [ { "type": "image_picker", "id": "image", "label": "Image" } ] } ], "presets": [ { "name": "オリジナルスワイパー" } ] } {% endschema %} 矢印を外に出す。 以下のCSSが画像をいっぱいに広げているので、画像幅の指定を削除します。 .swiper-slide img { width: 100%; height: 100%; } 下記の '800x' で画像サイズを調節できます。 <img src="{{ block.settings.image | img_url: '800x' }}"> あとは、矢印のサイズを大きく、画像の要素の最大幅を指定、マージンを調節してください。 JavaScriptの設定で、loopで最初のスライドに戻ったり、speed でスライドの移動スピードを調節できます。 実装したコード 実装したコードを全て以下に示します。 ※TailwindCSSを使用しています。 swiper.liquid <!-- Demo styles --> <style> html, body { position: relative; height: 100%; } .swiper { margin-left: auto; margin-right: auto; } .swiper-slide { text-align: center; font-size: 18px; background: #fff; /* Center slide text vertically */ display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; } .swiper-slide img { display: block; object-fit: cover; } .sqiper-wrapper { position: relative; } .swiper-button-next::after { font-family: "Font Awesome 5 Free"; font-weight: bold; font-size: 5rem; content: "\f105"; color: #71767e; } .swiper-button-prev::after { font-family: "Font Awesome 5 Free"; font-weight: bold; font-size: 5rem; content: "\f104"; color: #71767e; } .swiper-pagination { color: #71767e; } </style> <!-- Swiper --> <div class="swiper mySwiper my-10 md:my-20 max-w-5xl"> <div class="swiper-wrapper mb-10"> {%- for block in section.blocks -%} <div class="swiper-slide"> <img src="{{ block.settings.image | img_url: '800x' }}"> </div> {%- endfor -%} </div> <div class="swiper-button-next"></div> <div class="swiper-button-prev"></div> <div class="swiper-pagination"></div> </div> <!-- Swiper --> {% schema %} { "name": "オリジナルスワイパー", "settings": [ { "type": "text", "id": "heading", "label": "Heading" } ], "blocks": [ { "type": "image", "name": "block image", "settings": [ { "type": "image_picker", "id": "image", "label": "Image" } ] } ], "presets": [ { "name": "オリジナルスワイパー" } ] } {% endschema %} theme.liquid <!doctype html> ~略~ <head> ~略~ <!-- Link Swiper's CSS --> <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" /> <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet" /> </head> <body> ~略~ <!-- Swiper JS --> <script src="//unpkg.com/swiper/swiper-bundle.min.js"></script> <!-- Initialize Swiper --> <script> var swiper = new Swiper(".mySwiper", { slidesPerView: 1, spaceBetween: 30, loop: true, speed: 1200, pagination: { el: ".swiper-pagination", clickable: true, }, autoplay: { delay: 3000, disableOnInteraction: false, }, navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev", }, }); </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TypeScriptでHTMLElementのstyleプロパティの型を指定する方法

結論 DOMのstyleを動的に変えたい時に let someElementStyle:Partial<CSSStyleDeclaration>; と指定することで、エディタによる補完や型チェックの恩恵を得ることができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む