preface

Recently, I have been catching up on the knowledge of CSS, and I have read the book “CSS Revealed”. The following is an excerpt from the notes.

First, expand the click range of the button

For smaller, hard-to-aim controls, expanding their clickable area outward can greatly improve the user experience, if not directly enlarging their visual size. Because a button that can’t be clicked is not a favorite.

As long as addcursor: pointerThis simple onecssProperties, which visually indicate how to interact with it and how far it can interact with it.

Solution 1

The easiest way to do this is to set a transparent border around the element, because mouse interaction with the border will also trigger mouse events.

border: 10px solid transparent;
Copy the code

The above code expands the border of the element10px“, but it doesn’t work well because it also makes the button bigger.

Using border makes the button larger because the background spreads to the bottom of the border by default. Use the background-clip property to restrict the background to the lower level of the original region.

border: 10px solid transparent;
background-clip: padding-box;
Copy the code

And when the button really needs a border, you can use box-shadow to simulate the border

border: 10px solid transparent;
box-shadow: 0 0 0 2px red inset;
background-clip: padding-box;
Copy the code

perfect

Solution 2

Instead of borders, pseudo-elements represent host elements to influence mouse interactions.

The top layer of the button can be covered with a transparent pseudo-element 10px larger than the button.

btn: {
	position: relative;
}
.btn::before{
	content: ' ';
  	position: absolute;
  	top: -10px;
  	right: -10px;
  	botttom: -10px;
  	left: -10px;
}
Copy the code

The advantage of this approach is that as long as one pseudo-element is available, it works without interfering with other CSS attributes.

Codepen give it a try

Second, mask layer

Many times, a translucent mask layer is needed to hide everything behind it to highlight a particular UI element and draw the user’s attention. Popovers and so on.

The most common scenario for this effect is to add an extra HTML element to mask the background

.overlay{
	position: fixed;
  	top: 0;
  	right: 0;
  	bottom: 0;
  	left: 0;
  	background: rgba(0.0.0.8);
}
.dialog{
	position: absolute;
   	z-index: 1;
}
Copy the code

.overlayTo cover everything behind this key element,.dialogA higher one needs to be specifiedz-index.While this method is good, you need an extra oneHTMLElements.

Solution 1

You can use pseudo-elements instead of additional HTML elements

body.overlay::before{
	position: fixed;
  	top: 0;
  	right: 0;
  	bottom: 0;
  	left: 0;
  	z-index: 1;
  	background: rgba(0.0.0.8);
}
Copy the code

This solution can achieve the effect of mask layer directly in THE CSS layer, but there are some disadvantages:

  • ifbodyElements already occupied by other effects::beforePseudo elements
  • And often needJavaScripttobodyaddoverlayThe name of the class

Solution 2

Pseudo-elements can satisfy most mask layer needs, but for some simple application scenarios, box-shadow can be used to achieve this effect.

box-shadow: 0 0 0 999px rgab(0.0.0.8);
Copy the code

The expansion parameter of box-shadow can enlarge the projection of an element in all directions. Simply create a large projection to achieve the effect of the mask layer.

One problem is that it doesn’t work well with larger screen resolutions (the above Settings won’t work well with screens above 2000px). Either increase the number or switch to viewport units.

box-shadow: 0 0 0 50vmax rgab(0.0.0.8);
Copy the code

Since the projection expands in all four directions at the same time, setting it to 50vmax will suffice.

But the drawbacks are obvious:

  • Due to the viewport unit, the edges of the mask layer are shown as the page scrolls. Unless plusfixedLocation or no scrolling
  • The mask layer also prevents the user from interacting with other elements of the page when implemented as a separate element, butbox-shadowIt doesn’t have that ability.

Solution 3

If you want to highlight a popover element


and implement a mask layer,

will come with a mask layer. This acoustic mask layer can also be set with the :: Backdrop pseudo element
\>
\>

dialog::backdrop{
	background: rgba(0.0 ,0.8)}Copy the code

3. Customize underscores

Although CSS has an underline property, text-decoration: underline, this property is very crude and cannot modify the effect.

Solution 1

Use the border attribute

{
	border-bottom: 1px solid gray;
   	text-decoration: none;
}
Copy the code

useborder-bottomThe simulated underline can be customized with color, line width, and line shape. But the space between the lines and the words is very large

If you set a small line-height, such as line-height:.9, the distance does shrink, but there is another problem: it prevents normal text wrapping.

Solution 2

Use the background-image attribute

background: linear-gradient(gray, gray) no-repeat;
background-size: 100% 1px;
background-position: 0 1.115 em;
text-shadow:.05em 0 white, -0.05 em  0 white;
Copy the code

The effect is fantastic. You can also implement different line types: dashed lines and underscores, for example

background: linear-gradient(90deg, gray 66%, transparent 0) repeat-x;
background-size:.2em 2px;
backgrond-position: 0 1em;
Copy the code

The percentage position value of the color standard can be used to fine-tune the proportion of the dotted line and background-size can be used to change the density of the dotted line.

Codepen give it a try

Fourth, adaptive internal elements

If you don’t give an element a specific height, it automatically ADAPTS to the height of its content. Can width be set to behave like this? For example, the following HTML code

<p>Some text</p>
<figure>
	<img src='adacatlace.jgp'>
    <figcaption>
    	The great Sir Adam Catlace was named after
        Countess Ada Lovelace, the first programmer
    </figcaption>
</figure>
Copy the code

By default, this is shown above, but this is requiredfigureThe element can be as wide as the image it contains (the size is usually not fixed) and horizontally centered.

Let’s say we float the figure element so that we get the correct width, but this has the obvious side effect of changing the layout mode.

The solution

Use the min-content attribute

figure{
	width: min-content;
   	margin: auto;
}
Copy the code

Two linescssThe code is done.

The min-content keyword is resolved to the width of the largest unbreakable element inside the container ———— the widest word, picture, or box element with a fixed width.

Codepen give it a try

Five, close to the bottom footer

With a block-level footer, how do I make it fit underneath the content?

Assume the HTML structure of the page is as follows:

<header>
	<h1></h1>
</header>
<main>.</main>
<footer>.</footer>
Copy the code

The solution

To use the Flexbox layout, first set display: flex to the body element, because it is the parent of the three elements, and then set Flex-flow: column, otherwise the child elements will be horizontally placed on a row. Set the height to 100vh to cover the height of the viewport.

The height of the header and footer is determined by main, so give the Flex property of Main a value greater than 0.

body{
	height: 100vh;
	display: flex;
	flex-flow: column;
}
main{
	flex: 1;
}
Copy the code

Set styles according to the number of sibling elements

In some scenarios, you need to style sibling elements based on their total number. The most common scenario is when a list gets longer and longer, to save screen space by hiding controls or compressing controls to improve the user experience.

The solution

1. For special scenarios with only one list item, use the :only- Child pseudo-class selector.

To hide the delete button when the list has only one item, the :only- Child selector is required

li:only-child{
	background: red;
}
Copy the code

:only-chilD equivalent:first-child:last-childBecause the first term is also the last term, then it’s unique.

:last-child is also a syntactic sugar equivalent to :nth-last-child(1).

2. If a list contains exactly four items, hit each of them

li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li{
	background: red;
}
Copy the code

Of course, this part of the code is very tedious, you can usescssPreprocessor to avoid this problem

@mixin n-item($n) {
	&:first-child:nth-last-child(#{$n}),
	&:first-child:nth-last-child(#{$n}) ~ & {
    	@content
    }
}

li {
	@include n-item(4) {// Write the style here}}Copy the code

3. If the total number of list items is 4 or more, select all list items

li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li{
	background: gray;
}
Copy the code

Less than fourliElements:

More than fourliElements:

4. Similarly, select all list items only when there are four or fewer in the list

li:first-child:nth-last-child(-n+4),
li:first-child:nth-last-child(-n+4) ~ li{
	background: yellow;
}
Copy the code

5. Match all list items when the list contains 2 to 6 items

li:first-child:nth-last-child(n+2):nth-last-child(-n+6),
li:first-child:nth-last-child(n+2):nth-last-child(-n+6) ~ li{
	background: # 456789;
}
Copy the code

More than 6:

More than or equal to 2, less than or equal to 6:

Less than 2:

Codepen give it a try

Reference:

CSS Revealed

At the end

For more articles, please go to Github, if you like, please click star, which is also a kind of encouragement to the author.