position:absolute; right: 10px;が効かない
解決したいこと
下記のような、ハンバーガーメニューの位置を右端にずらしたいです。
実際のサイト
PC用 width:800px以上
タブレット用 width:800px以下
スマホ用 width:500px以下
ハンバーガーメニューは、width:800px以下で表示
今回は、スマホ用のハンバーガーメニューを右端に寄せたい
下記のようなコードを設定しましたが、
が効きません。
left:を設定すると動きます。
コード抜粋
pages/index.js
...
return (
<div className={styles.zentai}>
...
<label htmlFor="menu-btn-check" className={styles.openbtn1}>
<span></span>
<span></span>
<span></span>
</label>
...
styles/Home.module.css
.zentai {
position: relative;
}
.openbtn1 {
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
width: 50px;
height: 50px;
}
コード全文
pages/index.js
import Head from "next/head";
import { useState, useEffect } from "react";
import axios from "axios";
import styles from "../styles/Home.module.css";
import Title from "../components/title";
import Form from "../components/form";
import Sidebar from "../components/sidebar";
import Results from "../components/results";
import Paginationtop from "../components/paginationtop";
import Paginationbottom from "../components/paginationbottom";
import Readmore from "../components/readmore";
import Footer from "../components/footer";
export default function Home() {
const defaultKeyword = ["鳥", "犬", "猫"];
const randomKeyword =
defaultKeyword[Math.floor(Math.random() * defaultKeyword.length)];
const [keyword, setKeyword] = useState(randomKeyword); //指定キーワード
const [category, setCategory] = useState(""); //指定カテゴリ
const [page, setPage] = useState(1); //現在のページ
const [resultsPerPage, setResultsPerPage] = useState(10); //1ページあたりのitem数
const [items, setItems] = useState([]); //アイテムの配列
const [pageCount, setPageCount] = useState(""); //総ページ数
const options = {
params: {
keyword: keyword,
category: category,
page: page,
results_per_page: resultsPerPage,
},
};
const getItems = async () => {
const res = await axios.get("/api/items", options);
console.log("options", options);
console.log("res", res);
console.log("items", res.data.users.items);
setItems(res.data.users.items); //アイテム群をセット
scroll_to_top();
setPageCount(res.data.users.pageCount); //総ページ数をセット
};
const getItems_readmore = async () => {
const res = await axios.get("/api/items", options);
console.log("options", options);
console.log("res", res);
console.log("items", res.data.users.items);
if (options.params.page == 1) {
setItems(res.data.users.items); //アイテム群をセット
scroll_to_top();
} else {
setItems((prev) => {
return [...prev, ...res.data.users.items];
});
}
setPageCount(res.data.users.pageCount); //総ページ数をセット
};
// First page
useEffect(() => {
getItems();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Search
const searchItems = (e) => {
e.preventDefault(); // リロードを止める
setPage(1);
options.params.page = 1;
getItems();
// scroll_to_top();
};
// Search
const categoryItems = (categorye) => {
// e.preventDefault(); // リロードを止める
setPage(1);
options.params.page = 1;
setCategory(categorye);
options.params.category = categorye;
getItems();
};
const reload = (e) => {
location.reload();
};
const scroll_to_top = () => {
window.scroll({ top: 0, behavior: "auto" });
};
// Readmore +
const pageReadmore = () => {
if (page < pageCount) {
const newPage = page + 1;
setPage((prevPage) => prevPage + 1);
options.params.page = newPage;
getItems_readmore();
}
};
// Pagination +
const pageIncrement = () => {
if (page < pageCount) {
const newPage = page + 1;
setPage((prevPage) => prevPage + 1);
options.params.page = newPage;
getItems();
}
};
// Pagination -
const pageDecrement = () => {
if (page > 1) {
const newPage = page - 1;
setPage((prevPage) => prevPage - 1);
options.params.page = newPage;
getItems();
scroll_to_top();
}
};
const pageChange = (newPage) => {
setPage(newPage);
options.params.page = newPage;
getItems();
};
return (
<div className={styles.zentai}>
<input id="menu-btn-check" type="checkbox" className={styles.checkbox} />
<label htmlFor="menu-btn-check" className={styles.openbtn1}>
<span></span>
<span></span>
<span></span>
</label>
<label htmlFor="menu-btn-check" className={styles.back}></label>
<div className={styles.container}>
<Head>
<title>総合ショップ</title>
</Head>
<div id="page_top"></div>
<div className={styles.top}>
<Title reload={reload} />
<Form
category={category}
setKeyword={setKeyword}
setCategory={setCategory}
searchItems={searchItems}
keyword={keyword}
/>
</div>
<div className={styles.paginationT}>
{(() => {
if (pageCount > 0) {
let haba = 2;
let startpage = page - haba;
if (startpage < 2) {
startpage = 2;
}
let endpage = page + haba;
if (endpage >= pageCount) {
endpage = pageCount - 1;
}
const items = [];
if (page > 2) {
items.push(
<button
className={styles.pageButton}
onClick={() => pageDecrement()}
>
前へ
</button>
);
}
items.push(
<button
className={page == 1 ? styles.pageButtonC : styles.pageButton}
onClick={() => pageChange(1)}
>
1
</button>
);
if (startpage >= 3) {
items.push(<button className={styles.pageButton}>...</button>);
}
for (let i = startpage; i <= endpage; i++) {
items.push(
<button
className={
i == page ? styles.pageButtonC : styles.pageButton
}
onClick={() => pageChange(i)}
>
{i}
</button>
);
}
if (endpage <= pageCount - 2) {
items.push(<button className={styles.pageButton}>...</button>);
}
if (pageCount > 1) {
items.push(
<button
className={
page == pageCount ? styles.pageButtonC : styles.pageButton
}
onClick={() => pageChange(pageCount)}
>
{pageCount}
</button>
);
}
if (page < pageCount) {
items.push(
<button
className={styles.pageButton}
onClick={() => pageIncrement()}
>
次へ
</button>
);
}
// return <ul>{items}</ul>;
return <div>{items}</div>;
}
})()}
<div className={styles.pagination2}>
{page} / {pageCount} ページ
</div>
</div>
<Paginationtop
pageIncrement={pageIncrement}
pageDecrement={pageDecrement}
page={page}
pageCount={pageCount}
/>
<input
id="menu-btn-check"
type="checkbox"
className={styles.checkbox}
/>
<Sidebar
category={category}
setCategory={setCategory}
categoryItems={categoryItems}
/>
<Results items={items} keyword={keyword} category={category} />
<div className={styles.paginationB}>
{(() => {
if (pageCount > 0) {
let haba = 2;
let startpage = page - haba;
if (startpage < 2) {
startpage = 2;
}
let endpage = page + haba;
if (endpage >= pageCount) {
endpage = pageCount - 1;
}
const items = [];
if (page > 2) {
items.push(
<button
className={styles.pageButton}
onClick={() => pageDecrement()}
>
前へ
</button>
);
}
items.push(
<button
className={page == 1 ? styles.pageButtonC : styles.pageButton}
onClick={() => pageChange(1)}
>
1
</button>
);
if (startpage >= 3) {
items.push(<button className={styles.pageButton}>...</button>);
}
for (let i = startpage; i <= endpage; i++) {
items.push(
<button
className={
i == page ? styles.pageButtonC : styles.pageButton
}
onClick={() => pageChange(i)}
>
{i}
</button>
);
}
if (endpage <= pageCount - 2) {
items.push(<button className={styles.pageButton}>...</button>);
}
if (pageCount > 1) {
items.push(
<button
className={
page == pageCount ? styles.pageButtonC : styles.pageButton
}
onClick={() => pageChange(pageCount)}
>
{pageCount}
</button>
);
}
if (page < pageCount) {
items.push(
<button
className={styles.pageButton}
onClick={() => pageIncrement()}
>
次へ
</button>
);
}
return <div>{items}</div>;
}
})()}
<div className={styles.pagination2}>
{page} / {pageCount} ページ
</div>
</div>
<Paginationbottom
pageIncrement={pageIncrement}
pageDecrement={pageDecrement}
page={page}
pageCount={pageCount}
/>
<Readmore
pageReadmore={pageReadmore}
page={page}
pageCount={pageCount}
resultsPerPage={resultsPerPage}
/>
<Footer />
<a href="#page_top" className={styles.page_top_btn}>
トップへ戻る
</a>
</div>
</div>
);
}
styles/Home.module.css
/* 全体のレイアウト */
.container {
width: 1000px;
margin: 0px auto;
padding: 0px;
min-height: 100vh;
display: grid;
grid-template:
"... ....... ........ ................ ..."
"... top top top ..." 70px
"... ....... ........ ................ ..." 25px
"... sidebar ........ paginationT ..."
"... sidebar ........ ................ ..."
"... sidebar ........ searchkey ..."
"... sidebar ........ ................ ..." 10px
"... sidebar ........ results ..." 1fr
"... sidebar ........ ................ ..." 10px
"... sidebar ........ paginationB ..."
"... ....... ........ ................ ..."
"... footer footer footer ..." 100px
"... ....... ........ ................ ..."
/ auto 270px 10px 1fr auto;
}
.top {
grid-area: top;
}
.paginationT {
grid-area: paginationT;
text-align: left;
}
.paginationB {
grid-area: paginationB;
text-align: left;
}
.paginationtop {
/* grid-area: paginationtop; */
display: none;
}
.paginationbottom {
/* grid-area: paginationbottom; */
display: none;
}
.searchkey {
grid-area: searchkey;
}
.sidebar {
grid-area: sidebar;
}
.results {
grid-area: results;
}
.footer {
grid-area: footer;
font-size: 1rem;
}
.siteTitle {
font-size: 1.8rem;
text-align: center;
}
.readmore {
display: none;
}
.searchForm {
display: grid;
grid-template:
"... .............. ... ........... ... ............ ..." 10px
"... selectCategory ... searchBox ... searchButton ..."
"... .............. ... ........... ... ............ ..." 10px
/ auto 100px 0px 300px 0px 100px auto;
}
.selectCategory {
grid-area: selectCategory;
background-color: rgba(57, 60, 60, 0.171);
}
.searchBox {
grid-area: searchBox;
}
.searchBox {
display: inline-block; /* なくても大丈夫だけど、念の為 */
position: relative; /* 基準値とする */
}
.searchBox::before {
content: ""; /* 疑似要素に必須 */
width: 16px; /* アイコンの横幅 */
height: 16px; /* アイコンの高さ */
background: url(./icon.png) no-repeat center center / auto 100%; /* 背景にアイコン画像を配置 */
display: inline-block; /* 高さを持たせるためにインラインブロック要素にする */
position: absolute; /* 相対位置に指定 */
top: 5px; /* アイコンの位置。微調整してね */
left: 6px; /* アイコンの位置。微調整してね */
}
.searchBox input {
padding: 2px 2px 2px 27px; /* アイコンを設置するため左の余白を多めに指定*/
font-size: 1.2rem;
width: 300px;
}
.searchButton {
grid-area: searchButton;
}
.pageButton {
width: 50px;
height: 33px;
font-size: 1rem;
/* background-color: aqua; */
}
.pageButtonC {
width: 50px;
height: 33px;
font-size: 1rem;
font-weight: bold;
background-color: aqua;
}
.pagination2 {
margin-top: 10px;
text-align: right;
}
.sidebar {
margin: 5px;
}
.sidebarmidashi {
padding: 5px;
font-size: 1.2rem;
font-weight: bold;
margin-top: 5px;
margin-bottom: 5px;
}
.sidebarlist #active {
background-color: aquamarine;
}
.sidebarlist .row:hover {
cursor: pointer;
background-color: aquamarine;
}
.sidebarlist .row {
padding: 5px;
font-size: 1rem;
}
.empty {
text-align: center;
margin-top: 100px;
}
/* itemのレイアウト */
.item {
font-size: 1rem;
border: 1px solid #e2e8f0;
padding: 5px;
margin-top: 8px;
display: grid;
grid-template:
"... ............ ... ... ..." 5px
"... title ... img ..."
"... ............ ... img ..." 5px
"... description ... img ..."
"... ............ ... img ..." 5px
"... price ... img ..."
"... ............ ... img ..." 5px
"... category ... img ..."
"... ............ ... img ..." 5px
"... merchantName ... img ..."
"... ............ ... ... ..." 5px
/ auto 1fr 10px auto auto;
margin-top: 8px;
}
.img {
grid-area: img;
}
.title {
grid-area: title;
font-size: 1.5rem;
}
.title a {
color: #0070f3;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.description {
grid-area: description;
line-height: 1.5;
font-size: 1.2rem;
white-space: pre-wrap;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
overflow: hidden;
}
.price {
grid-area: price;
text-align: center;
font-size: 1.2rem;
}
.category {
grid-area: category;
text-align: right;
word-break: break-all;
}
.merchantName {
grid-area: merchantName;
text-align: right;
}
.openbtn1 {
display: none;
}
/* display: noneすると、idとforの連携が効かなくなるので、下のように画面外に隠す */
.checkbox {
position: absolute;
left: -50vw;
}
/* トップへ戻るボタン */
.page_top_btn {
position: fixed;
bottom: 10px;
right: 10px;
font-weight: bold;
font-size: 0.8rem;
padding: 0.7em;
text-align: center;
/* background: url(./top2.png) no-repeat center center / auto 100%; */
/* background: black; */
background: rgba(5, 5, 5, 0.8);
color: #fff;
transition: 0.3s0;
}
/* マウスオーバー時 */
.page_top_btn:hover {
color: rgb(255, 255, 255, 0.8);
}
/* タブレット設定 */
@media screen and (max-width: 800px) {
.container {
width: 100%;
margin: 0px auto;
padding: 10px;
min-height: 100vh;
display: grid;
grid-template:
"... ................ ..." 0px
"... top ..." 60px
"... ................ ..." 3px
"... results ..." 1fr
"... ................ ..." 3px
"... readmore ..."
"... ................ ..."
"... footer ..." 10px
"... ................ ..." 5px
/ auto auto auto;
}
.paginationT {
display: none;
}
.paginationB {
display: none;
}
.readmore {
display: block;
grid-area: readmore;
text-align: center;
font-size: 1rem;
}
.readmoreButton {
font-size: 1.2rem;
margin-top: 10px;
margin-bottom: 10px;
border-radius: 100vh;
/* width: 500px; */
}
.siteTitle {
font-size: 1.2rem;
text-align: center;
}
/* タブレット設定 */
.searchForm {
display: grid;
grid-template:
"... .............. ... ........... ... ............ ..." 5px
"... selectCategory ... searchBox ... searchButton ..."
"... .............. ... ........... ... ............ ..." 0px
/ auto 100px 0px 300px 0px 100px auto;
}
.selectCategory {
grid-area: selectCategory;
background-color: rgba(57, 60, 60, 0.171);
font-size: 1rem;
}
.searchInput {
grid-area: searchInput;
font-size: 1rem;
}
.searchButton {
grid-area: searchButton;
font-size: 1rem;
}
/* itemのレイアウト */
.item {
padding: 5px;
margin-top: 8px;
line-height: 1;
display: grid;
grid-template:
"... ............ ... ... ..." 5px
"... title ... img ..."
"... ............ ... img ..." 5px
"... description ... img ..."
"... ............ ... img ..." 5px
"... price ... img ..."
"... ............ ... img ..." 5px
"... category ... img ..."
"... ............ ... img ..." 5px
"... merchantName ... img ..."
"... ............ ... ... ..." 5px
/ auto 1fr 10px auto auto;
margin-top: 8px;
}
.title {
font-size: 1.2rem;
}
.description {
/* grid-area: description; */
line-height: 1.5;
font-size: 1rem;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
overflow: hidden;
}
.price {
grid-area: price;
text-align: center;
font-size: 1rem;
}
.category {
grid-area: category;
text-align: right;
word-break: break-all;
font-size: 1rem;
}
.merchantName {
grid-area: merchantName;
text-align: right;
font-size: 1rem;
}
.zentai {
position: relative;
}
/*==================================================
5-2-1 3本線が×に
===================================*/
/*ボタン外側※レイアウトによってpositionや形状は適宜変更してください*/
.openbtn1 {
display: block;
/* position: relative; ボタン内側の基点となるためrelativeを指定 */
position: absolute; /*ボタン内側の基点となるためrelativeを指定*/
top: 10px;
left: 10px;
background: #ffffff;
cursor: pointer;
width: 50px;
height: 50px;
border-radius: 5px;
}
/*ボタン内側*/
.openbtn1 span {
display: inline-block;
transition: all 0.4s; /*アニメーションの設定*/
position: absolute;
left: 14px;
height: 3px;
border-radius: 2px;
background: #000000;
width: 45%;
}
.openbtn1 span:nth-of-type(1) {
top: 15px;
}
.openbtn1 span:nth-of-type(2) {
top: 23px;
}
.openbtn1 span:nth-of-type(3) {
top: 31px;
}
/*activeクラスが付与されると線が回転して×に*/
.checkbox:checked ~ .openbtn1 span:nth-of-type(1) {
/* .openbtn1.active span:nth-of-type(1) { */
top: 18px;
left: 18px;
transform: translateY(6px) rotate(-45deg);
width: 30%;
}
.checkbox:checked ~ .openbtn1 span:nth-of-type(2) {
/* .openbtn1.active span:nth-of-type(2) { */
opacity: 0; /*真ん中の線は透過*/
}
.checkbox:checked ~ .openbtn1 span:nth-of-type(3) {
/* .openbtn1.active span:nth-of-type(3) { */
top: 30px;
left: 18px;
transform: translateY(-6px) rotate(45deg);
width: 30%;
}
.sidebar {
/*position:fixed;にし、z-indexの数値を大きくして前面へ*/
position: fixed;
z-index: 999;
/*ナビのスタート位置と形状*/
top: 70px;
left: -120%;
width: 270px;
height: 80vh; /*ナビの高さ*/
background: #ffffff;
/*動き*/
transition: all 0.2s;
/* 縦方向のスクロールバーを表示 */
overflow-y: scroll;
/* IE などのスクロールバーの色設定 */
scrollbar-face-color: #999;
scrollbar-track-color: #eee;
/* スマホ用の慣性スクロール */
-webkit-overflow-scrolling: touch;
}
.checkbox:checked ~ .container .sidebar {
left: 0;
/* right: 0; */
}
.checkbox:checked ~ .container {
/* left: 0; */
overflow: hidden;
/* right: 0; */
}
.checkbox:checked ~ .back {
position: absolute;
top: 0px;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4) !important;
}
}
/* スマホの設定 */
@media screen and (max-width: 500px) {
.container {
width: 100%;
margin: 0px auto;
padding: 10px;
min-height: 100vh;
display: grid;
position: relative;
grid-template:
"... ................ ..." 0px
"... top ..." 60px
"... ................ ..." 3px
"... results ..." 1fr
"... ................ ..." 3px
"... readmore ..."
"... ................ ..." 3px
"... footer ..." 10px
"... ................ ..." 5px
/ auto 1fr auto;
}
.siteTitle {
text-align: left;
font-size: 1.2rem;
margin-left: 60px;
}
.openbtn1 {
position: static;
}
.zentai {
position: relative;
}
.openbtn1 {
display: block;
/* position: relative; ボタン内側の基点となるためrelativeを指定 */
/* position: static; */
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
background: white;
cursor: pointer;
width: 50px;
height: 50px;
border-radius: 5px;
}
.selectCategory {
display: none;
}
/* スマホの設定 */
.searchForm {
display: grid;
grid-template:
"... ........... ... ............ ..." 3px
"... searchBox ... searchButton ..."
"... ........... ... ............ ..." 0px
/ 60px 250px 0px 50px auto;
}
.searchBox input {
padding: 2px 2px 2px 27px; /* アイコンを設置するため左の余白を多めに指定*/
font-size: 1.2rem;
width: 250px;
}
.item {
border: 1px solid #e2e8f0;
padding: 3px;
margin-top: 5px;
display: grid;
grid-template:
"... ............ ... ... ..." 5px
"... title ... img ..."
"... ............ ... img ..." 5px
"... description ... img ..."
"... ............ ... img ..." 5px
"... price ... img ..."
"... ............ ... img ..." 5px
"... category ... img ..."
"... ............ ... img ..." 5px
"... merchantName ... img ..."
"... ............ ... ... ..." 5px
/ auto 1fr 10px auto auto;
margin-top: 3px;
}
.img {
width: 100%;
height: auto;
}
.title {
font-size: 1rem;
}
.description {
line-height: 1.5;
font-size: 1rem;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
overflow: hidden;
}
.price {
font-size: 1rem;
}
.category {
font-size: 1rem;
}
.merchantName {
font-size: 1rem;
}
}
0