【问题标题】:Problem with sizing CSS, and positioning elements, also how to use aspect ratio, for all resolutions调整 CSS 大小和定位元素的问题,以及如何为所有分辨率使用纵横比
【发布时间】:2023-01-29 21:28:37
【问题描述】:

对于我面临的几个问题的任何建议/支持,我将不胜感激。提前感谢您的建议。

我一直在尝试在 CSS 的网格中为我的网站制作这个游戏浏览部分,但我似乎无法找到如何修复这个错误,例如我的代码结果会这样:

它适用于单个当前数量的字符,就像我在那里所做的那样,但是当我更改 HTML 中的文本以获取其中的一个新字符时,它会执行如下操作:

图像的图标不断变化和移动,当我更改游戏类别中的内容时,我意识到会发生这种情况。

我也想知道如何保持我创建的相同基本形状,我希望它在所有分辨率下保持相同,但找不到方法。

这应该制作一个包含游戏图像、播放按钮、标题和游戏类别的 div

.Games {
  display: grid;
  grid-template-columns: repeat(4, 25.7%);
  grid-template-rows: repeat:(auto, auto);
  grid-gap: auto;
  margin: auto;
  max-width: 1200px;
}

#GameFrame {
  background: #0f101e;
  border-radius: 25px;
  width: 99%;
  max-height: 80%;
  display: inline-block;
  transition: all 0.3s ease-in-out;
}

#GameImage {
  width: 95%;
  height: 150px;
  border-radius: 25px;
  margin-left: 2.5%;
  margin-top: 2.5%;
  transition: all 0.3s ease-in-out;
}

#GameText {
  color: white;
  font-size: 100%;
  font-family: "Gotham", sans-serif;
  text-shadow: 5px 5px 10px black;
  margin-left: 60px;
  position: relative;
  z-index: 1;
}

button {
  background-image: linear-gradient(#e23c03, #fa4e12);
  border: none;
  border-radius: 10px;
  height: 18.5%;
  width: 13%;
  transition: all 0.3s ease-in-out;
  position: relative;
  top: -86px;
  margin-left: 84%;
}

#play {
  color: white;
  font-size: 100%;
}

button:hover {
  transform: scale(1.1);
  filter: drop-shadow(4px 2px 4px black);
}

#category {
  background: #27211d;
  border-radius: 10px;
  font-size: 70%;
  font-family: "Gotham", sans-serif;
  color: #ffc400;
  position: relative;
  z-index: 3;
  padding: 1.2%;
  padding-left: 1.5%;
  padding-right: 1.5%;
  display: inline-block;
  margin-left: 20%;
  top: -37px;
}

#GameIcon {
  width: 45px;
  height 45px;
  border-radius: 100%;
  filter: drop-shadow(4px 2px 4px #08080f);
  position: relative;
  z-index: 2;
  top: -30px;
  margin-left: -125px;
}
<link href="https://fonts.cdnfonts.com/css/gotham" rel="stylesheet">
<script src="https://kit.fontawesome.com/faea65eadf.js" crossorigin="anonymous"></script>

<div class="Games">
  <div id="GameFrame">
    <img src="https://img.redbull.com/images/c_fill,w_1200,h_600,g_auto,f_auto,q_auto/redbullcom/2020/4/28/bjoyslzjb3uxqyg82uz2/minecraft" id="GameImage"></img>
    <!--Game Image Above-->
    <h1 id="GameText">Minecraft</h1>
    <!--Game Name Above-->
    <h1 id="category">Adventure</h1>
    <!--Game Category Above-->
    <img src="https://mojang-studios.gallerycdn.vsassets.io/extensions/mojang-studios/minecraft-debugger/0.6.1/1672951467139/Microsoft.VisualStudio.Services.Icons.Default" id="GameIcon"></img>
    <!--Game Circle Image Above-->
    <button>
      <i id="play" class="fa-solid fa-play"></i>
    </button>
  </div>

  <div id="GameFrame">
    <img src="https://pikuma.com/images/blog/game-console-history-for-programmers/thumbnail-990x540.jpg" id="GameImage"></img>
    <!--Game Image Above-->
    <h1 id="GameText">Example</h1>
    <!--Game Name Above-->
    <h1 id="category">Casual</h1>
    <!--Game Category Above-->
    <img src="https://i.pinimg.com/564x/47/aa/1f/47aa1fe9ca114cce1558e1e46a59bdf2.jpg" id="GameIcon"></img>
    <!--Game Circle Image Above-->
    <button>
      <i id="play" class="fa-solid fa-play"></i>
    </button>
  </div>
</div>

此外,我真的希望按钮保持正方形,一旦放大很多,它就会变成一个矩形。

这是它针对不同的分辨率放大很多时的情况:

我尝试了很多,阅读了很多文章,但找不到原因,我还在每个尺寸值中进行了很多编辑,但也没有用。有人请帮助我,谢谢。

另外,链接到代码笔:https://codepen.io/FreeGames/pen/PoBpamV

【问题讨论】:

  • 请修改您的帖子标题以提出明确、具体的问题。参见How to Ask
  • 当你做类似top: -86px; 的事情时,你就知道你在现代网络中误入歧途了。关键是为您的内容建立一个框架,并使您的内容适合框架的一部分。你永远不应该对元素进行像素完美定位。我现在没有时间为您提供解决方案,但这是您应该采取的方向。

标签: html css visual-web-developer


【解决方案1】:

有几种方法可以解决这个问题,我将在下面展示几个选项,我们将逐步进行(尽可能在 Stack Overflow 答案的范围内)。

第一步是以某种有意义的语义方式将 HTML 放在一起。为此,我提出了以下 HTML:

<!-- you want to show a list of games in your "game browsing section,"
     to that end I'm using an unordered list (you may prefer to use an
     <ol> if you'd consider it to be ordered): -->
<ul class="library">
  <!-- the <li> elements each wrap one game from the library: -->
  <li>
    <!-- you want to show an <img> with associated text; the <figure>
         element - along with its <figcaption> - seems to fit this
         use-case: -->
    <figure>
      <!-- the <img> to show the game image asset: -->
      <img src="https://i.stack.imgur.com/ZeeKUm.jpg" alt="" class="gameTitleScene">
      <figcaption>
        <!-- the icon/smaller game-image: -->
        <img src="https://i.stack.imgur.com/4GZ51s.png" alt="" class="gameIcon">
        <!-- game title, I've used an <h3> as there should be only one <h1> in
             a page, and the <h2> elements seem a likely choice for section titles;
             obviously adjust to whichever element you prefer: -->
        <h3 class="gameTitle">Minecraft</h3>
        <!-- I wasn't sure if there would only be one, or multiple, categories; so I
             wrapped the categories (as <a> elements to allow for easier browsing to
             all games of a given category), within <li> elements again within an
             unordered-list: -->
        <ul class="categories">
          <li><a href="#" class="category">Adventure</a></li>
        </ul>
        <!-- the 'play' button, with a type of "button" so that if you choose to nest
             this within a <form> it won't submit that <form> by default: -->
        <button type="button" class="play"></button>
      </figcaption>
    </figure>
  </li>
</ul>

按照您在问题中显示的方式设置上述 HTML 的样式:

https://i.stack.imgur.com/nDY75.png

我们可以使用以下 CSS:

/* a couple of custom CSS properties to allow for consistent theming,
   allowing for theme changes in one place that updates all uses at
   once: */
:root {
  --categoryColor: #f90;
  --spacing: 1em;
}

/* a simple reset, to cause the browser to include paddings and border-
   sizes within the declared size of the element: */
*,
::before,
::after {
  box-sizing: border-box;
  /* removing browser default margin and padding:  */
  margin: 0;
  padding: 0;
}

body {
  /* setting the font defaults for the page; which will over-write
     browser default styles (though user-agent styles will likely
     take precedence over these styles if they're set; that's a
     feature and not a bug): */
  font-family: "Roboto", "Poppins", system-ui;
  font-size: 16px;
  font-weight: 500;
}

/* setting some basic styles for users that use keyboard navigation, to
   show an obvious outline around focused elements: */
:focus-visible {
  outline: 0.25em solid currentColor;
  outline-offset: 0.25em;
}

/* removing the default list-markers from the listed elements; this
   also removes the accessibility feature in which screen-readers
   announce the contents as a list; so while we're removing the
   list-markers here (and thereby removing that functionality from
   the associated elements), we have used an aria-role="list" attribute
   on the <ul>, and aria-role="listitem" on the child <li> elements in
   order to preserve/restore that functionality; since we only wish to
   hide the content from the visual theme: */
ul,
li {
  list-style-type: none;
}

main {
  /* setting up a grid-display on the <main> element that wraps all
     content (in this demo): */
  display: grid;
  /* making use of the var() function, and the --spacing custom
     property to apply a consistent gap: */
  gap: var(--spacing);
  /* using CSS logical properties to size the element on its inline
     axis (the axis on which inline content flows, such as words
     in a sentence, equivalent to 'width' in the English language).
     We're using the clamp() function to determine the size of the
     eleemnt; with a preferred size of 80% of its own parent
     containing element's inline size, with a minimum size of 20rem
     and a maximum size of 1200px: */
  inline-size: clamp(20rem, 80%, 1200px);
  /* setting margins on the block axis; this is perpendicular to the
     inline axis and equivalent to 'height' in the English language: */
  margin-block: var(--spacing);
  /* setting inline margins of auto, in order that the content will
     be centered within its parent (if enough space exists): */
  margin-inline: auto;
}

.library {
  /* I left the border in place in order to allow the sizing to be
     easily visualised, but it's not necessary for the demo: */
  border: 1px solid currentColor;
  /* I chose to use display: flex here: */
  display: flex;
  /* and used the flex-flow shorthand to set:
    flex-direction: row;
    flex-wrap: wrap;
  */
  flex-flow: row wrap;
  /* applying the gap between items (again): */
  gap: var(--spacing);
  /* spreading the elements out across the inline-axis; adjust to
     your preferences though: */
  justify-content: space-between;
  /* assigning a padding, to move the child element(s) away from
     the <li> element's boundaries:: */
  padding: var(--spacing);
}

.library > li {
  background-color: hsl(0deg 0% 0% / 1);
  /* using the calc() function to set a border-radius on the
     element, based on the theme's --spacing property: */
  border-radius: calc(var(--spacing) / 2);
  border: 1px solid currentColor;
  padding: var(--spacing);
}

/* selecting the descendant elements of the <figure> element that
   match the supplied CSS selectors, so here we select all
   <img> and <button> elements that are within the <figure> ancestor: */
figure :is(img, button) {
  /* setting the border-radius as above, based on the --spacing custom
     property: */
  border-radius: calc(var(--spacing) / 2);
}

figcaption {
  /* setting the color to white using CSS colors 4 syntax and the
     hsl() function: */
  color: hsl(0deg 100% 100% / 1);
  /* using display: grid: */
  display: grid;
  /* setting the gap between the grid-columns: */
  grid-column-gap: calc(var(--spacing)/2);
  /* defining 3 columns, the first and last taking a size of 2rem,
     with the central taking 1 fraction of the remaining space: */
  grid-template-columns: 2rem 1fr 2rem;
  /* using CSS logical properties to place a margin (again using the
     custom property, and var() function) to the start-edge of the
     element's block-axis (in English, equivalent to margin-top): */
  margin-block-start: var(--spacing);
}

/* using the :is() pseudo-class to select elements matching the supplied
   CSS selectors (.gameTitle, .categories) within a figcaption ancestor: */
figcaption :is(.gameTitle, .categories) {
  /* positioning those elements in grid-column 2: */
  grid-column: 2;
}

figcaption :is(.gameIcon, .play) {
  /* putting these elements in grid-row 1: */
  grid-row: 1;
  /* with a maximum inline size ('width,' in the English language) of
     100%, so the element can't/won't extend beyond the assigned space: */
  max-inline-size: 100%;
  /* using object-fit to scale the element(s) in a way that they'll fill
     their available space in a manner which preserves their aspect-ratio: */
  object-fit: cover;
}

.gameTitle {
  font-size: 1.5em;
}

.gameIcon {
  /* we could use border-radius: 50%, but clip-path() is well-supported and
     actually clips the element as described, to a circle - centered by
     default - of radius 50%: */
  clip-path: circle(50%);
  /* and positioning it within the grid, into grid-column 1: */
  grid-column: 1;
}

.play {
  background-color: hsl(0deg 95% 50% / 1);
  border: 1px solid transparent;
  /* inherits from its ancestor: */
  color: inherit;
  grid-column: 3;
  /* I'm using position: absolute on the (following) pseudo-element, so
     we're specifying a non-static position on this element, so that it
     acts as the containing block: */
  position: relative;
}

.play::before {
  /* the Unicode right-pointing triangle: */
  content: "B6";
  font-size: 1rem;
  /* to allow for the element to be positioned absolutely, with reference
     to its containing block (the first element with 'position' set to
     something other than 'static' (the default): */
  position: absolute;
  /* positioning the element's top-left corner with reference to its
     ancestor's top-left corner: */
  top: 50%;
  left: 50%;
  /* translating the element -50% of its own size on both the horizontal
     and vertical axes, in order to have it centered: */
  translate: -50% -50%;
}

.categories {
  /* setting the color of text content within the element: */
  color: var(--categoryColor);
}

.categories a {
  /* setting <a> elements to inherit their color: */
  color: inherit;
  text-decoration: none;
}

.categories a:is(:hover, :active, :focus) {
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
<!-- importing fonts from Google Fonts (this is optional, obviously, and only
     included because so many people like to use them)  -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet"> 
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet"> 

<main>
<!-- you want to show a list of games in your "game browsing section,"
     to that end I'm using an unordered list (you may prefer to use an
     <ol> if you'd consider it to be ordered): -->
<ul class="library">
  <!-- the <li> elements each wrap one game from the library: -->
  <li>
    <!-- you want to show an <img> with associated text; the <figure>
         element - along with its <figcaption> - seems to fit this
         use-case: -->
    <figure>
      <!-- the <img> to show the game image asset: -->
      <img src="https://i.stack.imgur.com/ZeeKUm.jpg" alt="" class="gameTitleScene">
      <figcaption>
        <!-- the icon/smaller game-image: -->
        <img src="https://i.stack.imgur.com/4GZ51s.png" alt="" class="gameIcon">
        <!-- game title, I've used an <h3> as there should be only one <h1> in
             a page, and the <h2> elements seem a likely choice for section titles;
             obviously adjust to whichever element you prefer: -->
        <h3 class="gameTitle">Minecraft</h3>
        <!-- I wasn't sure if there would only be one, or multiple, categories; so I
             wrapped the categories (as <a> elements to allow for easier browsing to
             all games of a given category), within <li> elements again within an
             unordered-list: -->
        <ul class="categories">
          <li><a href="#" class="category">Adventure</a></li>
        </ul>
        <!-- the 'play' button, with a type of "button" so that if you choose to nest
             this within a <form> it won't submit that <form> by default: -->
        <button type="button" class="play"></button>
      </figcaption>
    </figure>
  </li>
</ul>
</main>

但是,如果我们采用上面的代码,并添加第二个&lt;li&gt;/card,那么我们将看到第二个元素——因为&lt;img&gt;大小不同——具有不同的大小,这导致“卡片”是不同的尺寸,以及网格行未对齐:

:root {
  --categoryColor: #f90;
  --spacing: 1em;
}

*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Roboto", "Poppins", system-ui;
  font-size: 16px;
  font-weight: 500;
}

:focus-visible {
  outline: 0.25em solid currentColor;
  outline-offset: 0.25em;
}

ul,
li {
  list-style-type: none;
}

main {
  display: grid;
  gap: var(--spacing);
  inline-size: clamp(20rem, 80%, 1200px);
  margin-block: var(--spacing);
  margin-inline: auto;
}

.library {
  border: 1px solid currentColor;
  display: flex;
  flex-flow: row wrap;
  gap: var(--spacing);
  justify-content: space-between;
  padding: var(--spacing);
}

.library>li {
  background-color: hsl(0deg 0% 0% / 1);
  border-radius: calc(var(--spacing) / 2);
  border: 1px solid currentColor;
  padding: var(--spacing);
}

figure :is(img, button) {
  border-radius: calc(var(--spacing) / 2);
}

figcaption {
  color: hsl(0deg 100% 100% / 1);
  display: grid;
  grid-column-gap: calc(var(--spacing)/2);
  grid-template-columns: 2rem 1fr 2rem;
  margin-block-start: var(--spacing);
}

figcaption :is(.gameTitle, .categories) {
  grid-column: 2;
}

figcaption :is(.gameIcon, .play) {
  grid-row: 1;
  max-inline-size: 100%;
  object-fit: cover;
}

.gameTitle {
  font-size: 1.5em;
}

.gameIcon {
  clip-path: circle(50%);
  grid-column: 1;
}

.play {
  background-color: hsl(0deg 95% 50% / 1);
  border: 1px solid transparent;
  color: inherit;
  grid-column: 3;
  position: relative;
}

.play::before {
  content: "B6";
  font-size: 1rem;
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
}

.categories {
  color: var(--categoryColor);
}

.categories a {
  color: inherit;
  text-decoration: none;
}

.categories a:is(:hover, :active, :focus) {
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">

<main>
  <ul class="library">
    <li>
      <figure>
        <img src="https://i.stack.imgur.com/ZeeKUm.jpg" alt="" class="gameTitleScene">
        <figcaption>
          <img src="https://i.stack.imgur.com/4GZ51s.png" alt="" class="gameIcon">
          <h3 class="gameTitle">Minecraft</h3>
          <ul class="categories">
            <li><a href="#" class="category">Adventure</a></li>
          </ul>
          <button type="button" class="play"></button>
        </figcaption>
      </figure>
    </li>
    <li>
      <figure>
        <img src="https://i.stack.imgur.com/Ougoom.jpg" alt="" class="gameTitleScene">
        <figcaption>
          <img src="https://i.stack.imgur.com/w5XDp.jpg" alt="" class="gameIcon">
          <h3 class="gameTitle">Example</h3>
          <ul class="categories">
            <li><a href="#" class="category">Casual</a></li>
          </ul>
          <button type="button" class="play"></button>
        </figcaption>
      </figure>
    </li>
  </ul>
</main>

这可以通过以下方式解决——尽管我希望我能想出更好的方法——

.gameTitleScene {
  /* setting a maximum block-size of 160px for the element: */
  max-block-size: 160px;
}

:root {
  --categoryColor: #f90;
  --spacing: 1em;
}

*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Roboto", "Poppins", system-ui;
  font-size: 16px;
  font-weight: 500;
}

:focus-visible {
  outline: 0.25em solid currentColor;
  outline-offset: 0.25em;
}

ul,
li {
  list-style-type: none;
}

main {
  / display: grid;
  gap: var(--spacing);
  inline-size: clamp(20rem, 80%, 1200px);
  margin-block: var(--spacing);
  margin-inline: auto;
}

.library {
  border: 1px solid currentColor;
  display: flex;
  flex-flow: row wrap;
  gap: var(--spacing);
  justify-content: space-between;
  padding: var(--spacing);
}

.library>li {
  background-color: hsl(0deg 0% 0% / 1);
  border-radius: calc(var(--spacing) / 2);
  border: 1px solid currentColor;
  padding: var(--spacing);
}

figure :is(img, button) {
  border-radius: calc(var(--spacing) / 2);
}

figcaption {
  color: hsl(0deg 100% 100% / 1);
  display: grid;
  grid-column-gap: calc(var(--spacing)/2);
  grid-template-columns: 2rem 1fr 2rem;
  margin-block-start: var(--spacing);
}

figcaption :is(.gameTitle, .categories) {
  grid-column: 2;
}

figcaption :is(.gameIcon, .play) {
  grid-row: 1;
  max-inline-size: 100%;
  object-fit: cover;
}

.gameTitleScene {
  max-block-size: 160px;
}

.gameTitle {
  font-size: 1.5em;
}

.gameIcon {
  clip-path: circle(50%);
  grid-column: 1;
}

.play {
  background-color: hsl(0deg 95% 50% / 1);
  border: 1px solid transparent;
  color: inherit;
  grid-column: 3;
  position: relative;
}

.play::before {
  content: "B6";
  font-size: 1rem;
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
}

.categories {
  color: var(--categoryColor);
}

.categories a {
  color: inherit;
  text-decoration: none;
}

.categories a:is(:hover, :active, :focus) {
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">

<main>
  <ul class="library">
    <li>
      <figure>
        <img src="https://i.stack.imgur.com/ZeeKUm.jpg" alt="" class="gameTitleScene">
        <figcaption>
          <img src="https://i.stack.imgur.com/4GZ51s.png" alt="" class="gameIcon">
          <h3 class="gameTitle">Minecraft</h3>
          <ul class="categories">
            <li><a href="#" class="category">Adventure</a></li>
          </ul>
          <button type="button" class="play"></button>
        </figcaption>
      </figure>
    </li>
    <li>
      <figure>
        <img src="https://i.stack.imgur.com/Ougoom.jpg" alt="" class="gameTitleScene">
        <figcaption>
          <img src="https://i.stack.imgur.com/w5XDp.jpg" alt="" class="gameIcon">
          <h3 class="gameTitle">Example</h3>
          <ul class="categories">
            <li><a href="#" class="category">Casual</a></li>
          </ul>
          <button type="button" class="play"></button>
        </figcaption>
      </figure>
    </li>
  </ul>
</main>

CSS 子网格可能会成为一个选项——一旦有更多的浏览器支持它(目前只有 Firefox,我相信 Safari 已经实现了它)——但不幸的是,我在这个答案中的空间已经用完了。

【讨论】:

    猜你喜欢
    • 2013-01-19
    • 2015-12-03
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 2012-11-09
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多