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

Time:06-21

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 >
   <figure>
     <img src="https://via.placeholder.com/300"  alt="">
  </figure>
</div>

While running this, I receive this.

enter image description here

But, I want to have something like this:

enter image description here

If I uncomment this line

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

enter image description here

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

CodePudding user response:

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 ></div>

CodePudding user response:

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 >
  <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 (e.g. ::before, ::marker).

Sidenote: While still supported for legacy reasons, they can also be written with a single-colon (e.g. :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 >
  <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 >
  <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 >
 <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 >
  <figure>
    <img src="https://via.placeholder.com/300">
  </figure>
</div>

<div id="example">
  <div >
    <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.

CodePudding user response:

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 >
  <figure>
    <img src="https://via.placeholder.com/300" alt="">
  </figure>
</div>

  • Related