纯css实现鼠标过去显示字_我如何构建纯CSS填字游戏

纯css实现鼠标过去显示字

CSS Crossword Puzzle

Recently I created a pure CSS crossword puzzle implemented using CSS grid that does not need JavaScript in order to work. It gained heavy interest pretty quickly on CodePen. As of this writing, it has more than 350 hearts and 24,000+ page views!

最近,我创建了一个纯CSS填字游戏 ,它使用CSS网格实现,不需要JavaScript即可工作。 它很快对CodePen引起了极大的兴趣。 截至撰写本文时,它拥有超过350个心形和24,000多个页面浏览量!

The great CSS Grid Garden tutorial inspired me to build something with Grid Layout features. I wondered if these features could be put to good use in building a crossword puzzle — then I thought, let’s try to create the whole thing without using JavaScript.

出色的CSS Grid Garden教程启发了我使用Grid Layout功能进行构建。 我想知道是否可以在构建填字游戏中很好地利用这些功能-然后我想,让我们尝试在不使用JavaScript的情况下创建整个游戏。

构建板/网格 (Building the Board/Grid)

So, first thing’s first, let’s create the board itself!

因此,首先是第一件事,让我们创建董事会!

I ended up with the following basic structure, with HTML comments included to show what the different sections will accomplish:

我最终得到了以下基本结构,其中包括HTML注释,以显示不同部分将完成的工作:

<div class="crossword-board-container">

  <div class="crossword-board">

    <!-- input elements go here. Uses CSS Grid as its layout -->

    <div class="crossword-board crossword-board--highlight crossword-board--highlight--across">
      <!-- highlights for valid 'across' answers go here. Uses CSS Grid as its layout -->
    </div>

    <div class="crossword-board crossword-board--highlight crossword-board--highlight-down">
      <!-- highlights for valid 'down' answers go here. Uses CSS Grid as its layout -->
    </div>

    <div class="crossword-board crossword-board--labels">
      <!-- row and column number labels go here. Uses CSS Grid as its layout -->
    </div>

    <div class="crossword-clues">

      <dl class="crossword-clues__list crossword-clues__list--across">
        <!-- clues for all the 'across' words go here -->
      </dl>

      <dl class="crossword-clues__list crossword-clues__list--down">
        <!-- clues for all the 'down' words go here -->
      </dl>

    </div>

  </div>

</div>

That puts our basic skeleton in place so we can add more elements and start styling things.

这样就可以放置基本骨架,以便我们可以添加更多元素并开始设计样式。

对正方形使用形状元素 (Using Form Elements for the Squares)

The crossword puzzle I’m creating is a 13×13 grid with 44 blank spaces so I need to create 125 input elements each with its own ID in the format item{row number}-{column number}, i.e. item4-12. Here’s what the grid will look like:

我正在创建的填字游戏是一个13×13的网格,带有44个空格,因此我需要创建125个input元素,每个input元素都具有自己的ID,格式为item{row number}-{column number} ,即item4-12 。 网格如下所示:

Empty crossword

Each of the inputs will get have a minlength and maxlength of “1” to emulate the behaviour of a crossword puzzle (i.e. one letter per square). Each input will also have the required attribute so that HTML5 form validation will be used. I take advantage of all of these HTML5 attributes using CSS.

每个输入端将得到有minlengthmaxlength的“1”,以模拟填字游戏(每平方即一个字母)的行为。 每个输入还将具有required属性,以便将使用HTML5表单验证。 我使用CSS来利用所有这些HTML5属性。

使用通用兄弟选择器 (Using the General Sibling Selector)

The input elements are visually laid out in groups (exactly how a crossword puzzle is). Each group of input elements represents a word in the crossword. If each of the elements in that group is valid (which can be verified using the :valid pseudo selector), then we can use CSS to style an element that appears later in the DOM (using an advanced CSS selector called the general sibling selector) that will indicate that the word is correct.

输入元素在视觉上成组排列(确切地说是填字游戏的样子)。 每组输入元素代表填字游戏中的一个单词。 如果该组中的每个元素都是有效的(可以使用:valid伪选择器进行验证),那么我们可以使用CSS设置稍后出现在DOM中的元素的样式(使用称为通用同级选择器的高级CSS选择器)这将表明该词是正确的。

Due to how sibling selectors work, and how CSS works in general, this element has to appear later in the DOM. CSS can only style elements that are after the currently selected element. It cannot look backwards in the DOM (or up the DOM tree) and style something before the current element (at the moment at least anyway).

由于同级选择器的工作方式以及CSS的一般工作方式,因此该元素必须稍后出现在DOM中。 CSS只能设置当前所选元素之后的元素的样式。 它不能在DOM(或DOM树)中向后看,也不能在当前元素之前设置样式(至少现在是这样)。

This means I can use the :valid pseudo-class to style valid elements:

这意味着我可以使用:valid伪类来设置有效元素的样式:

.input:valid {
  border: 2px solid green;
}
.input:invalid {
  border: 2px solid red;
}

See the Pen Valid Pseudo Selector Example by SitePoint (@SitePoint) on CodePen.

请参阅CodePen上的SitePoint ( @SitePoint )的笔有效伪选择器示例

To style an element later on in the DOM that is a sibling of another element, I can use the ~ (tilde/general sibling) selector, e.g. A ~ B. This selector will select all elements that match B, that are a sibling of A and appear after A in the DOM. For example:

到一个元件以后的是另一个元件的兄弟姐妹,我可以使用〜(波浪号/普通兄弟姐妹)选择器,例如,DOM样式A ~ B 。 该选择器将选择与B匹配的所有元素,它们是A的同级元素,并出现在DOM中的A之后。 例如:

#input1:valid ~ #input2:valid ~ #input3:valid ~ #input4:valid ~ #input5:valid ~ .valid-message {
  display: block;
}

With this code, if all these input elements are valid, the valid-message element will be displayed.

使用此代码,如果所有这些输入元素均有效,则将显示valid-message元素。

See the Pen Using Sibling Selector to Display a Message by SitePoint (@SitePoint) on CodePen.

请参阅使用同级选择器的笔在CodePen上通过SitePoint( @SitePoint ) 显示消息

The general sibling selector is extremely useful here. To make the crossword work, I needed to make sure that everything was laid out in a way that allowed me to take advantage of the general sibling selector.

通用的同级选择器在这里非常有用。 为了使填字游戏起作用,我需要确保所有内容的布局方式都使我能够利用通用的同级选择器。

The finished crossword example is using the above technique, starting at line 285. I’ve separated it out in the code block below:

完整的填字游戏示例使用上述技术,从285行开始。我在下面的代码块中将其分离出来:

#item1-1:valid ~ #item1-2:valid ~ #item1-3:valid ~ 
#item1-4:valid ~ #item1-5:valid ~ #item1-6:valid ~ 
.crossword-board--highlight .crossword-board__item-highlight--across-1 {
  opacity: 1;
}

This part of the CSS ensures that if all these input elements are valid, then the opacity of the .crossword-board__item-highlight--across-1 element will be changed. .crossword-board--highlight is a sibling of all the input elements, and .crossword-board__item-highlight--across-1 is a child of .crossword-board--highlight so it’s selectable with CSS!

CSS的这一部分确保如果所有这些输入元素均有效,则.crossword-board__item-highlight--across-1元素的不透明度将被更改。 .crossword-board--highlight是所有输入元素的同级, .crossword-board__item-highlight--across-1.crossword-board--highlight的子级,因此可以在CSS中选择!

指示正确答案 (Indicating Correct Answers)

Each crossword answer (i.e. group of input elements) has a corresponding “correct answer indicator” (.crossword-board__item-highlight--across-{{clue number}}) grid item. These grid items are placed behind the input elements on the z-axis, and are hidden using opacity: 0. When a correct word is entered, then the correct answer indicator grid item is displayed by changing the opacity to 1, as the pseudo-class selector snippet above demonstrates.

每个填字游戏答案(即输入元素组)都有一个相应的“正确答案指示符”( .crossword-board__item-highlight--across-{{clue number}} )网格项。 这些网格项位于z轴上的输入元素的后面,并使用opacity: 0隐藏。 输入正确的单词后,通过将opacity更改为1可以显示正确的答案指示符网格项,如上面的伪类选择器代码段所示。

Crossword with incomplete word
Crossword with completed word

This technique is repeated for each “word” group of input elements. So this means manually creating each CSS rule for each of the input elements in the word group and then selecting the corresponding correct answer indicator grid item. As you can imagine, this makes the CSS get big fast!

对输入元素的每个“单词”组重复此技术。 因此,这意味着为单词组中的每个输入元素手动创建每个CSS规则,然后选择相应的正确答案指示符网格项。 可以想象,这使CSS快速变大!

So the logical approach would be to create all the CSS rules that show/hide the correct answer indicator grid items for all the horizontal (across) clue answers. Then you would do the same for the vertical clue answers.

因此,逻辑方法是创建所有CSS规则,以显示/隐藏所有水平(跨)线索答案的正确答案指示符网格项。 然后,您将对垂直线索答案执行相同的操作。

网格系统的挑战 (Challenges of the Grid System)

If, like me, you are trying to use as little CSS as possible, you will quickly realise that you cannot have overlapping grid areas within the same grid system without having to explicitely declare it. They can only sit next to each other (1 across, and 1 down share a square at the top right of the board and this is not possible when using one CSS grid to layout all the correct answer indicator items).

如果像我一样,尝试使用尽可能少CSS,您将很快意识到,在同一个网格系统中,不必显式声明就不能有重叠的网格区域。 他们只能彼此相邻坐着(1个对开,1个向下共享一个在板右上方的正方形,使用一个CSS网格布置所有正确的答案指示符项时,这是不可能的)。

The solution is to wrap each horizontal (across) correct answer indicator grid item in its own grid system, and each vertical (down) correct answer indicator grid item in another. This way I can still use CSS to select them (using the general sibling selector), and they will not interfere with each other and ruin the layout of the grids.

解决方案是将每个水平(跨)正确答案指示器网格项目包装在其自己的网格系统中,并将每个垂直(向下)正确答案指示器网格项目包装在另一个网格系统中。 这样,我仍然可以使用CSS来选择它们(使用通用的同级选择器),并且它们不会互相干扰,也不会破坏网格的布局。

CSS Grid Layout items act similarly to inline-block elements. This basically means that if you specify two grid items to occupy the same space, then the second item will flow around the first item and appear after it in the grid.

CSS网格布局项目的行为类似于内联块元素。 这基本上意味着,如果您指定两个网格项目占用相同的空间,则第二个项目将围绕第一个项目流动,并出现在网格之后。

See the Pen Grid Layout Module Example by SitePoint (@SitePoint) on CodePen.

请参阅CodePenSitePoint ( @SitePoint )的笔网格布局模块示例

In the above example, the first grid item is seven columns wide and spans from the first column to the seventh column. The second grid item is meant to start at the 4th column and span to the 9th column. CSS grid doesn’t like this so it wraps it to the next row. Even if you specify grid-row: 1/1 in the second item, that will take priority and then move the first grid item to the second row.

在上面的示例中,第一个网格项目的宽度为七列,从第一列到第七列跨越。 第二个网格项应从第4列开始,一直到第9列。 CSS网格不喜欢这样,因此将其包装到下一行。 即使您在第二个项目中指定grid-row: 1/1 ,也将具有优先级,然后将第一个网格项目移至第二行。

As explained above, I avoided this by having multiple grids for horizontal and vertical items. This situation can be avoided by specifying the row and column span for each element, but I used the above method to reduce the amount of CSS, and also to have a more maintainable HTML structure.

如上所述,我通过为水平和垂直项目设置多个网格来避免了这种情况。 通过为每个元素指定行跨度和列跨度可以避免这种情况,但是我使用上述方法来减少CSS的数量,并具有更易于维护HTML结构。

检查有效的字母输入 (Checking for Valid Letter Input)

Each input element has a pattern attribute with a regular expression as its value. The regular expression matches an uppercase or lowercase letter for that square:

每个输入元素都有一个pattern属性,其值以正则表达式表示。 正则表达式匹配该正方形的大写或小写字母:

<input id="item1-1" class="crossword-board__item"
       type="text" minlength="1" maxlength="1"
       pattern="^[sS]{1}$" required value="">

This was not ideal because the answers are in the HTML. I wanted to hide the answers in the CSS, but I could not find a way of doing this successfully. I attempted the following technique:

这不是理想的,因为答案在HTML中。 我想在CSS中隐藏答案,但找不到成功完成此操作的方法。 我尝试了以下技术:

.input#item1-1[value="s"],
.input#item1-1[value="S"] {
  /* do something... */
}

But this won’t work. The attribute selector will select the element based on what is actually inside the HTML, and doesn’t consider live changes. So I had to resort to the :valid pseudo-class approach detailed above, and consequently (and annoyingly) exposing the answers in the HTML itself.

但这行不通。 属性选择器将根据HTML内部实际内容选择元素,而不考虑实时更改。 因此,我不得不求助于上面详述的:valid伪类方法,因此(烦人地)在HTML本身中公开了答案。

突出显示悬停线索 (Highlighting the Clues on Hover)

All horizontal (across) clues are wrapped in a div, as are the vertical (down) clues. These wrapping div elements are siblings of the input elements in the crossword grid. This is demonstrated in the HTML structure listed above in a previous code block. This makes it easy to select the correct clue(s) depending on which input element is being focused/hovered.

所有水平(交叉)线索和垂直(向下)线索都包裹在div 。 这些环绕div元素是填字游戏网格中input元素的同级元素。 上面的代码块中上面列出HTML结构中对此进行了演示。 这样可以轻松地根据要聚焦/悬停的输入元素来选择正确的线索。

Crossword hover

For this, each input element needs :active, :focus, and :hover styles to highlight the relevant clue by applying a background color when the user interacts with an input element.

为此,每个input元素都需要:active:focus:hover样式,以便在用户与input元素进行交互时通过应用背景色来突出显示相关线索。

#item1-1:active ~ .crossword-clues .crossword-clues__list-item--across-1,
#item1-1:focus ~ .crossword-clues .crossword-clues__list-item--across-1,
#item1-1:hover ~ .crossword-clues .crossword-clues__list-item--across-1 {
  background: #ffff74;
}

编号线索 (Numbering the Clues)

The numbers for the clues are positioned using a CSS Grid pattern. Here’s an example of the HTML, abbreviated:

线索的编号使用CSS网格模式定位。 这是缩写为HTML的示例:

<div class="crossword-board crossword-board--labels">
  <span id="label-1" class="crossword-board__item-label crossword-board__item-label--1">
  <span class="crossword-board__item-label-text">1</span></span>
  <span id="label-2" class="crossword-board__item-label crossword-board__item-label--2">
  <span class="crossword-board__item-label-text">2</span></span>

  <!-- rest of the items here..... -->

</div>

Then the CSS looks something like this:

然后CSS看起来像这样:

.crossword-board__item-label--1 {
  grid-column: 1/1;
}

.crossword-board__item-label--2 {
  grid-column: 4/4;
}

/* etc... more items here... */

Each number is placed at the start position of its related group of input elements (or word). The number is then made to be the width and height of 1 grid square so that it takes up as little space as possible within the grid. It could take up even less room by implementing CSS Grid differently here, but I opted to do it this way.

每个数字都放置在其相关的输入元素(或单词)组的开始位置。 然后将数字设为1个网格正方形的宽度和高度,以使其在网格内占据的空间尽可能小。 通过在此处不同地实现CSS Grid,它可以占用更少的空间,但是我选择了这种方式。

“检查有效平方”复选框 (The “Check for Valid Squares” Checkbox)

At the top of the crossword, you’ll notice a checkbox labelled “Check for valid squares”. This allows the user to check if certain letters are correct, even if a given word is wrong.

在填字游戏的顶部,您会注意到一个标记为“检查有效正方形”的复选框。 这样,即使给定单词有误,用户也可以检查某些字母是否正确。

Crossword valid squares highlighted

Creating this is rather beautiful as it’s one CSS rule that makes all the valid squares get highlighted. It’s using the checkbox hack to select all valid input elements that are after the checked checkbox in the DOM.

创建它非常漂亮,因为它是一条CSS规则,该规则使所有有效正方形都突出显示。 它使用复选框技巧来选择DOM中选中复选框之后的所有有效输入元素。

Here is the code:

这是代码:

#checkvaliditems:checked ~ .crossword-board-container .crossword-board__item:valid {
  background: #9aff67;
}

结论 (Conclusion)

That covers all the main techniques used in the demo. As an exercise, this shows you how far CSS has come in recent years. There are plenty of features we can get creative with. I for one can’t wait to try and push other new features to the limits!

这涵盖了演示中使用的所有主要技术。 作为练习,这向您展示了CSS在最近几年中的发展。 我们有很多可以发挥创意的功能。 我迫不及待地想尝试将其他新功能推向极限!

If you want to mess around with the CSS from this article, I’ve put all the code examples into a CodePen collection. The full working CSS crossword Puzzle can be found here.

如果您想弄乱本文中CSS,我已将所有代码示例放入CodePen集合中可以在这里找到完整的CSS填字游戏

翻译自: https://www.sitepoint.com/how-built-pure-css-crossword-puzzle/

纯css实现鼠标过去显示字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值