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

谁说胖子不能爱 提交于 2020-02-09 04:41:52

问题


Problem

My navbar looks like this:

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 :

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.


回答1:


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>



回答2:


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>



回答3:


Yes, it's quite possible:

#a{
    margin-top: 25px;
    position: relative;
    overflow: visible;
    white-space: nowrap;
    text-align: center;
    border: 3px solid black;
    border-top: none;
    border-radius: 0 0 25px 25px;
    margin-left: 25px;
    height: 50px;
}
#a, #a:after, #a:before{
    box-sizing: border-box;
    display: inline-block;
}
#a:after, #a:before{
    position: absolute;
    width: 25px;
    height: 25px;
    content: ".";
    color: transparent;
    border: 3px solid black;
    border-bottom: none;
    top: -25px;
}
#a:before{
    border-left: none;
    border-top-right-radius: 25px;
    left: -25px;
}
#a:after{
    border-right: none;
    border-top-left-radius: 25px;
    right: -25px;
}
<div id="a">Hello</div>

Or simplifying the style sheet with LESS:

#a {
    @round-width: 25px;
    @border-style: 3px solid black;

    @offset: -@round-width;

    &, &:after, &:before {
        box-sizing: border-box;
        display: inline-block;
    }

    position: relative;
    overflow: visible;
    white-space: nowrap;
    text-align: center;
    border: @border-style;
    border-top: none;
    border-radius: 0 0 @round-width @round-width;
    margin-left: @round-width;
    height: 50px;

    &:after, &:before {
        position: absolute;
        width: @round-width;
        height: @round-width;
        color: transparent;
        content: ".";
        border: @border-style;
        border-bottom: none;
        top: @offset;
    }

    &:before {
        border-left: none;
        border-top-right-radius: @round-width;
        left: @offset;
    }
    &:after {
        border-right: none;
        border-top-left-radius: @round-width;
        right: @offset;
    }
}

Nice thing of LESS is that you only mention the base selector (#a) once, and so for the widths.



来源:https://stackoverflow.com/questions/27676867/add-outward-curving-border-to-elements-like-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!