Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add outward curving border to elements like this: ◝◟___◞◜

Problem

My navbar looks like this:

enter image description here

HTML and CSS

nav {
  width: 1040px;
}
nav ul {
  display: block;
  list-style-type: none;
  height: 40px;
  border-top: 3px solid #222;
}
nav ul li {
  width: 130px;
  display: inline-block;
  line-height: 40px;
  text-align: center;
  font-size: 16px;
  font-family: Vollkorn;
  font-weight: 400;
}
nav ul li a {
  display: block;
  text-decoration: none;
  color: #333;
}
nav ul li a:hover,
nav ul li a:focus {
  color: #000;
  box-shadow: 0px 0px 2px black;
  border-radius: 10px;
  border: 2px solid #222;
  border-top: 0px;
  transition: 0.2s ease all;
}
<nav>
  <ul>
    <li><a href="#">Home</a>
    </li>
    <li>
      <a href="#">Random</a>
    </li>
    <li>
      <a href="#">Blog</a>
    </li>
    <li>
      <a href="#">About us</a>
    </li>
    <li>
      <a href="#">Contact Us</a>
    </li>
  </ul>
</nav>

Desired Output

In the above picture, the list item blog is focused or hovered. In hover style, it has a border-radius of 5px. The problem is that I want the top left and right corners, when hovered, to curve outwards like this :

enter image description here

I am able to achieve this result using background image, and also using position styles and z-index. I wanted a CSS border-only solution.

P.S.

The desired output may look undesirable (at least to me), but I just wanted to know if this could be done.

like image 512
The Pragmatick Avatar asked Dec 20 '22 08:12

The Pragmatick


2 Answers

From the top of my head: draw bottom half border on the element and draw top-left and top-right borders on positioned pseudo elements.

/* using 4px border, 1em border radius, 1em padding */
nav ul {
  font: medium sans-serif;
  text-align: center;
  padding: 0;
  list-style-type: none;
  border-top: 4px solid;
}
nav li {
  display: inline-block;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-radius: 0 0 1em 1em;
  padding: 0 1em 1em;
  position: relative;
  top: 1em;
}
nav li:before,
nav li:after {
  display: none;
  content: "";
  position: absolute;
  top: -1em;
  width: 1em;
  height: 1em;
  margin-top: -4px;
}
nav li:before {
  right: 100%;
  border-top: 4px solid;
  border-right: 4px solid;
  border-top-right-radius: 1em;
}
nav li:after {
  left: 100%;
  border-top: 4px solid;
  border-left: 4px solid;
  border-top-left-radius: 1em;
}
nav li:hover {
  border-color: initial;
}
nav li:hover:before,
nav li:hover:after {
  display: block;
}
<nav>
  <ul>
    <li>Home</li>
    <li>Random</li>
    <li>Blog</li>
    <li>About us</li>
    <li>Contact Us</li>
  </ul>
</nav>
like image 100
Salman A Avatar answered Jan 11 '23 01:01

Salman A


I have a rather hacky solution, if you want to call it as such. It is a use of both ::before and ::after pseudo elements to create invisible rectangles on the top left and right corners of the active link (hovered or in focus), with the border radius set at the correct edge.

nav {
  width: 1040px;
}
nav ul {
  display: block;
  list-style-type: none;
  height: 40px;
  border-top: 3px solid #222;
}
nav ul li {
  width: 130px;
  display: inline-block;
  line-height: 30px;
  padding-top: 10px;
  text-align: center;
  font-size: 16px;
  font-family: Vollkorn;
  font-weight: 400;
}
nav ul li a {
  display: block;
  text-decoration: none;
  color: #333;
  position: relative;
}
nav ul li a::before, nav ul li a::after {
  box-sizing: border-box;
  border-top: 2px solid #000;
  content: '';
  opacity: 0;
  position: absolute;
  top: -12px;
  width: 12px;
  height: 12px;
}
nav ul li a::before {
  border-top-right-radius: 10px;
  border-right: 2px solid #000;
  right: 100%;
}
nav ul li a::after {
  border-top-left-radius: 10px;
  border-left: 2px solid #000;
  left: 100%;
}
nav ul li a:hover,
nav ul li a:focus {
  color: #000;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
  border: 2px solid #222;
  border-top: none;
}
nav ul li a:hover::before, nav ul li a:hover::after,
nav ul li a:focus::before, nav ul li a:focus::after {
  opacity: 1;
}
<nav>
  <ul>
    <li><a href="#">Home</a>
    </li>
    <li>
      <a href="#">Random</a>
    </li>
    <li>
      <a href="#">Blog</a>
    </li>
    <li>
      <a href="#">About us</a>
    </li>
    <li>
      <a href="#">Contact Us</a>
    </li>
  </ul>
</nav>
like image 36
Terry Avatar answered Jan 11 '23 00:01

Terry