简体   繁体   中英

Need to have half width border in one side and full width border in another side

Here is my html and css code:

 .image-box{ max-width: 300px; position: relative; }.image-box img{ max-width: 100%; width: 100%; object-fit: cover; border: 8px solid #000000; border-right: 0; border-bottom: 0; /* border-image: linear-gradient(to right, #000 68%, transparent 32%) 100% 1; */ }
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300" alt=""> </figure> </div>

While running this, I receive this.

在此处输入图像描述

But, I want to have something like this:

在此处输入图像描述

If I uncomment this line

border-image: linear-gradient(to right, #000 68%, transparent 32%) 100% 1; 

在此处输入图像描述

Then it shows half width border on top, but this also make the left border disappear and show like this.

You can do something like this using pseudo classes to make the border at the top like how you want it to be achieved:

What it does is hide the half of the border at the top.

 .box { width: 150px; height: 150px; background-color: black; border-top: 5px solid red; border-left: 5px solid red; position: relative; }.box:after { content: ""; width: 50%; height: 5px; background-color: white; position: absolute; right: 0; top: -5px; }
 <div class="box"></div>

Disclaimer : Not an exhaustive list. Try to come up with yet another solution!

With background-image: linear-gradient()

To make a linear-gradient look like a border, we can add padding to the image and a hard color-stop to the gradient:

 .image-box { --thickness: 8px; }.image-box img { padding-top: var(--thickness); padding-left: var(--thickness); background-image: linear-gradient(to right, black 60%, white 60%); } figure{margin:0;line-height:0}
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div>

A potential problem with this is that only one side of the border may be shorter.

With Pseudo-elements

Pseudo-elements can be used for presentational styling. You can easily identify them in your CSS by their double-colons (eg ::before , ::marker ).

Sidenote : While still supported for legacy reasons, they can also be written with a single-colon (eg :before ). Do yourself a favour and use the double-colons.

We can use pseudo-elements to create the border.

I will use custom properties to make the code easier to change.
Personally, I enjoy the method Placing behind the most, because that way no bleeding through of the parent's background should happen in extreme (zoom) cases.

Composition

Composite the border with ::before for the left and ::after for the top side. Since these are separate elements, we can define their width and height individually:

 .image-box::before, .image-box::after { content: ""; position: absolute; top: 0; left: 0; background-color: black; }.image-box::before { /* Left */ width: var(--thickness); height: 100%; }.image-box::after { /* Top */ width: 60%; height: var(--thickness); }.image-box { --thickness: 8px; position: relative; /* Leave space for border */ padding-top: var(--thickness); padding-left: var(--thickness); max-width: 300px; box-sizing: border-box; }.image-box img {max-width:100%} figure{margin:0;line-height:0}
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div>

Placing behind

Place the image on top of a pseudo-element to make it look like a (partially wide) border:

 .image-box::before, .image-box>figure { grid-area: 1/1 / 1/1; /* Place both on first grid-cell */ }.image-box::before { content: ""; width: 60%; height: 100%; background-color: black; }.image-box { --thickness: 8px; max-width: 300px; display: grid; }.image-box img { /* Leave space for border */ padding-top: var(--thickness); padding-left: var(--thickness); width: 100%; box-sizing: border-box; } figure{margin:0;line-height:0}
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div>

Using clip-path: polygon()

Specify each point of the "top-left corner" shape in polygon() :

 .image-box { position: relative; padding-top: 8px; padding-left: 8px; max-width:300px; }.image-box::before { --thickness: 8px; content: ""; position: absolute; top: 0; left: 0; width: 60%; height: 100%; clip-path: polygon( 0 0, 100% 0, 100% var(--thickness), var(--thickness) var(--thickness), var(--thickness) 100%, 0 100%); background-color: black; } figure {margin:0;line-height:0}
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div>

Why not use border ?

Edit : Apparently border-image is a thing. See an example . Bottom section is therefore outdated.

Unfortunately, each side of a border can only be a single color. This means the black & white top border is not possible by only using the border property.

A solution to this would be to redraw over part of the border that we don't want:

 #example { padding: 1rem; background-color: slateblue; }.image-box { --thickness: 8px; position: relative; border: 0 solid black; border-top-width: var(--thickness); border-left-width: var(--thickness); max-width: 300px; }.image-box::after { content: ""; position: absolute; top: calc(-1 * var(--thickness)); right: 0; /* 100% - <length> + <thickness left-side> */ width: calc(100% - 60% + var(--thickness)); height: var(--thickness); background-color: white; } body { display: flex; flex-direction: column; gap: 1rem; } figure{margin:0;line-height:0}
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div> <div id="example"> <div class="image-box"> <figure> <img src="https://via.placeholder.com/300"> </figure> </div> </div>

But as you can see, this way we will lose the background of the parent. Hard-coding some color only works if the parent's background is a solid color. If the parent's background is an image, this won't work.

Also, having to tell .image-box the color to draw over with is redundant information (because the background already exists) and would only cause more mental overhead for the developer.

you are almost good with border-image. You need to correctly define the slice.

 .image-box { max-width: 300px; position: relative; }.image-box img { max-width: 100%; width: 100%; object-fit: cover; border: 8px solid #000000; border-right: 0; border-bottom: 0; border-image: linear-gradient(to right, #000 68%, transparent 32%) 1; }
 <div class="image-box"> <figure> <img src="https://via.placeholder.com/300" alt=""> </figure> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM