0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Web作ってる(html,css,js,php)

Last updated at Posted at 2024-12-22

はじめに

初めまして、ひつじです。
初投稿がこんなのでいいのか不安ですが、最後までお付き合いいただけると幸いです。

さて、巷では○○jsが流行っていますが、そんなの使いません。php,html,css,jsでやります。
今回はこのサイトを作っていくうえで思ったこと、使ったことなどなどを、php,html/css,jsについて一つずつコメントします。

本編

どんなサイトを作ってる?

ブルーアーカイブの二次創作ページを構築中です。(ファンページと言っていいのかは微妙。)
コンセプトはキヴォトス教育委員会。いろいろ言うより見た方が早いということで、現状のサイトがこちら

作ってる途中なのでまだまだ未完成で不完全です。許してください。

addEventLinsterで困った(js)

困ったポイント1

jsで要素の幅を取得すると、その値がnullになっちゃうこと。
要素が読み込まれる前に要素幅を取得しようとするからnullになっちゃう。解決方法は簡単でした。'DOMContentLoaded'を使って読み込まれたときに発火するようにすればいいです。

document.addEventListener('DOMContentLoaded', () =>  {
    // ここに処理を入れる
}

ってすればOKです。

困ったポイント2

画面幅に応じて可変的に要素幅を変更したい...ので、こんな感じにしてみました。

window.addEventListener('resize', () => {
    const dt = document.querySelectorAll('.news-child-img > a time');
    const du = document.querySelectorAll('.news-child-img > a h4');
    const dtH = dt[0].getBoundingClientRect().width;
    dt.forEach(elm => elm.style.fontSize = `${dtH*0.9}px`);
    du.forEach(elm => elm.style.fontSize = `${dtH*0.15}px`);
    // 続く
}

が、うまくいかないときがある。
基本的に要素のサイズを変えてくれましたが、ブラウザの最大化をすると発火していなそう...はて、どうしたものか...
解決法思いつかず...どなたかよい方法あれば教えてください...!
今現状はとりあえず何とかしてます()。

共通するものは流用しよう(php)

タイトルの通り。react/○○jsでやるやつです。コンポーネント化しようのphp番的な感じ。(react/○○jsの方が...) phpのfunctionで共通するやつをまとめて作っちゃって、functionを読ませることでコードを書かずに済む、と。
headerやfooterがいい例ですね。header.php/footer.phpをincludeやrequireして読み込ませること、多いと思います。あるいはWordPressみたく関数で定義して読み込んだり(今回はこちらでやりました。)

それを共通して使うところ全部でやる。

例えば画像を表示させる関数:

php
function img($src,$alt,$addInfo=null){
    global $root;
    if(preg_match('/^https?:\/\//', $src) === 1){
        return'<img src="'.$src.'" alt="'.$alt.'"'.$addInfo.'>';
    }else{
        $extension = pathinfo($src)['extension'];
        $src = preg_replace('/\.([a-zA-Z0-9]+)$/', '', $src);
        $avif = (file_exists($root.$src.'.avif')) ? $src.'.avif': false;
        $webp = (file_exists($root.$src.'.webp')) ? $src.'.webp': false;
        $plane = (file_exists($root.$src.'.'.$extension)) ? $src.'.'.$extension: '/com/assets/img/noimg.png';
        $img = '<img src="'.htmlspecialchars($plane).'" alt="'.htmlspecialchars($alt).'"'.htmlspecialchars($addInfo).'>';
        if($webp !== false || $avif !== false){
            $add1 = ($avif !== false) ? '<source type="image/avif" srcset="'.htmlspecialchars($avif).'">': '';
            $add2 = ($webp !== false) ? '<source type="image/webp" srcset="'.htmlspecialchars($webp).'">': '';
            return '<picture>'.$add1.$add2.$img.'</picture>';
        }else{
            return $img;
        }
    }
}
これは画像のリンクとaltを渡したらいい感じにしてhtmlを返します。webp,avifがあるかないかでコードを変えなきゃいけないのは面倒なので、phpでファイルの存在確認をして、あるなら表示、ないなら非表示、何もないなら別画像を表示させるようにしただけです。 webp,avifなどがあればそちらを優先して、なければそのまま指定された画像を表示させます。もし、指定した画像すらなければnoimg.pngを表示させます。覚えるのも書くのも面倒なのが、関数にすればすごく楽に書けますね。

と、実はここで一つ悩んだことがあります。
それはコンテンツをreturnで返すかechoで表示させるか、です。
それぞれで関数を作って表示させるには次のようにします。

function hoge(){
    return 'content1';
}
function nya(){
    echo 'content2';
}

echo hoge();
// content1
nya();
// content2

結論から言うと使い分けをすることにしました。
headerやfooterのように基本的にそれを表示させるだけ、の場合はechoで、そうでない場合はreturnで返すことにしました。returnで返せば関数の中に関数をぶち込めるので楽なんですよね。でもheaderみたいなのはいちいちechoって書くのが面倒で...
なのでその関数の機能によって使い分けしました。

悩んだらreturnでいいと思います。

このサイトでは基本的にこの関数を使って画像を表示させています。

image.png

clip-path, ::before, ::after は神!だけど...(html,css)

cssを扱ったことがある人ならそう思いますよね(圧)

::before, ::afterは疑似要素です。文字通りそれがついた要素の前/後にコンテンツを追加します。
こいつらを使うときは必ず指定しなきゃいけないものがあります。
これです

.hogehoge::before{
    content:''; /* これ必須 */
}

何も入れる必要がなくても、contentを指定しないと表示されません!(これ忘れてて何時間無駄にしたか...)
もちろん文字を入れたらその文字が入ります。

.hoge::before{
    content: '〇+×△;
}

これで指定したのが下の画像の左上のところになります。

image.png

before/afterのメリットとしてはhtmlがすごい深くならないこと、同じ要素に関連付けして配置できることがあるかな。デメリットはぱっと見で分かりづらいこと。
例えば上の画像の折り返しているように見えるところ(灰色の三角形)は::afterで配置しています。折り返すところまでセットで一つの要素ですよね。〇+×△も::beforeで配置しています。これも要素の一部になりますもんね。(要素を分けないときに使うといいかも)
逆に、要素を分けた方がいい時にbefore/afterは使わない方がいいです。そりゃそうだ。

clip-pathは要素を切り抜いてくれるやつです。
今回はクリップや折り返し、一番外枠の形作りをclip-pathで作りました。svgでもいいじゃん...その通り。だけど使ってみたかったんです。
あとこいつ癖がある。clip-pathで切り抜いた要素にbox-shadowがうまくつきません。borderもうまくつきません。そして書きにくい/読みにくい。 使うメリットねぇじゃん!
こいつのうれしいところは要素から子要素がはみ出したとき、clip-pathで切り抜いたところで切れること。つまり、clip-pathの外側に子要素が出ないことですね。(overflow:hiddenしてね)
複雑な図形の中に文字を収めたいときとか、役に立つかもしれないです!

html
<div class="section">
    <div class="section-in">
        <div class="section-cont-out">
            <h2><span>This is タイトル</span></h2>
            <div class="section-cont">コンテンツ</div>
        </div>
    </div>
</div>
css
.section{
    position: relative;
    box-sizing: border-box;
    width: 100%;
    height:  auto;
    margin: 2rem 0;
    padding: calc(20px + 3rem) 20px 20px;
    border-right: 1px #888 solid;
    border-bottom: 1px #888 solid;
    background-color: #fff;

    clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 2rem, 8rem 2rem, 7rem 0);
}
.section-in{
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    padding: calc(20px + 3rem) 20px 20px;
    border: 1px solid #000;
    background-color: #fff;

    clip-path: polygon(0 0, 0 100%, calc(100% - 3rem - 2px) 100% ,100% calc(100% - 3rem - 2px), 100% 0);
}
.section::before,.section::after,.section-in::before,.section-in::after{
    position: absolute;
    z-index: 0;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    content: '';
}
.section::before{
    padding: 0.5rem 1rem;
    content: "〇+×△";
    color: #08f;
    background-image: linear-gradient(-50deg, #00000000 3rem, #0088ff33 3rem 8rem, #00000000 5rem, calc(100% - 8rem), #0088ff33 calc(100% - 8rem) calc(100% - 3rem), #00000000 calc(100% - 3rem));
    font-size: 1.2rem;
}
.section::after{
    z-index: 1;
    width: 3.5rem;
    height: 1rem;
    transform: translate(2rem,4rem) rotateZ(60deg);
    border: 0.3rem solid #08f;
    border-radius: 1rem;

    clip-path: polygon(0 0,0 100%,0.99rem 100%,1.16rem 80%,1.5rem 80%,1.5rem 100%,100% 100%,100% 0);
}
.section-in::before{
    box-sizing: border-box;
    padding: calc(30px + 3rem) 30px 30px;
    content: '';
}
.section-in::after{
    background-color: #888;

    clip-path: polygon(calc(100% - 3rem) 100%, 100% calc(100% - 3rem), calc(100% - 3rem) calc(100% - 3rem));
}
.section-cont-out > h2 {
    position: relative;
    width: fit-content;
    margin: 0 auto;
    transform: rotateZ(-5deg);
    white-space: nowrap;
    font-size: 3rem;
}
.section-cont-out > h2 span {
    position: relative;
    padding: 1rem;
    background-color: #ffe300;
}
.section-cont-out > h2 span::before{
    position: absolute;
    z-index: -1;
    right: 0.5rem;
    bottom: -0.2rem;
    width: 80%;
    height: 50%;
    content: "";
    transform: rotateZ(5deg);
    background-color: #888;

    filter: blur(4px);
}
.section-cont-out{
    position: relative;
    width: 100%;
    height: 100%;
    box-shadow: 0 0 5px #00000033;
}
.section-cont{
    box-sizing: border-box;
    height: calc(100% - 6rem);
    margin-top: 2rem;
    padding: 1rem;
}

まとめ

最後まで見てくれてありがとうございます!
アドベントカレンダーに参加したくて書いたけど、結局gdgdになっちゃいました。ごめんなさい。
なんだかんだでreactとか楽やなぁ...って思いました。
何かあれば都度updateしていきます。

次はファイルサイズを小さくしよう!って記事を書きたいなって思いました。はい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?