2

I'm trying to make a menu with tabs. The style of the tabs is like so:

enter image description here

I need the background to be transparent and have a border, on hover, it will fill the background with another color.

I have tried to do this with pure CSS, I can get the shape correct using :before and :after, however as I'm using borders to do this, I cannot add a border on both sides and end up with this:

enter image description here

#pointer {
  width: 200px;
  height: 40px;
  position: relative;
  background: red;
  text-align: centre;
  border: 1px solid white;
}

#pointer:after {
  content: "";
  position: absolute;
  left: -20px;
  bottom: 0;
  width: 0;
  margin-bottom: 20px;
  height: 0;
  border-right: 20px solid red;
  border-top: 0px solid red;
  border-bottom: 20px solid transparent;
}

#pointer:before {
  content: "";
  position: absolute;
  right: -20px;
  bottom: 0;
  width: 0;
  height: 0;
  border-left: 20px solid red;
  border-top: 20px solid transparent;
  border-bottom: 20px solid red;
}
<div id="pointer">Tab 1</div>

I have also tried to do this with SVG, I can get the shape and border correct, but the hover area is a lot larger then the border.

    <svg
      class="test"
      xmlns='http://www.w3.org/2000/svg'
      viewBox='0 0 64 64'
      width='150' height='150'
      stroke='white'
      fill='red'>
      <path d='M8 30 L62 30 L62 22 L56 16 L2 16 L8 22 Z' />
    </svg>

How can I either, complete the borders with CSS attempt, or make the hover area of the SVG match the border exactly?

2 Answers 2

2

Here is a simple idea considering skew transformation:

.box {
  width: 200px;
  height: 80px;
  margin: 20px;
  color:#fff;
  z-index:0;
  position: relative;
  --c: black;
  --b: red;
}

.box:hover {
  --b: blue;
  --c:green;
}

.box:before,
.box:after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  height: 50%;
  border: 3px solid var(--c);
  background: var(--b);
  box-sizing:border-box;
}

.box:before {
  top: 0;
  transform: skewX(30deg);
  transform-origin: bottom right;
  border-bottom: none;
}

.box:after {
  bottom: 0;
  border-top: none;
}
<div class="box">
  some text
</div>

And for your SVG shape you simply need to reduce the viewBox to cover only your shape:

svg {
  border:1px solid
}
svg:hover path{
 stroke:red;
 fill:blue;
}
 <svg
      class="test"
      xmlns='http://www.w3.org/2000/svg'
      viewBox='0 14 64 18'
      width="150"
      stroke='blue'
      stroke-width=2
      fill='red'>
      <path d='M8 30 L62 30 L62 22 L56 16 L2 16 L8 22 Z' />
    </svg>

Sign up to request clarification or add additional context in comments.

Comments

1

For complex shpaes, it is allways better to use svg.

What I get from your problem, is that the svg area/ hover area is bigger than the figgure. And this is true. But you can solve this by targeting the path inside the svg to make your style whet path:hover.

I made a small snippet so you can see how it works.

Hope this helps :>

svg {
  background: red;
}

svg:hover {
  background: orange;
}

path:hover {
  fill: blue;
}
<svg
  class="test"
  xmlns='http://www.w3.org/2000/svg'
  viewBox='0 0 64 64'
  width='150' height='150'
  stroke='white'
  fill='green'>
  <path d='M8 30 L62 30 L62 22 L56 16 L2 16 L8 22 Z' />
</svg>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.