How to create alligator (or sawtooth) border using

2019-02-13 01:53发布

alligator might not be the right word; I welcome a correction to the title.

I'd like container to have alligator border like in the picture bellow.

alligator title

If the element in question had solid background, then pseudo-element trickery or CSS3 border-image could be used. However, in this case, the content of the container is a non repeating pattern.

Alternatively, it is possible for the image itself to have the border. However, because of the way image expands (animation used to reveal the image), that's not possible.

The only alternative I can think is SVG.

标签: css3 svg
6条回答
淡お忘
2楼-- · 2019-02-13 02:32

Depending on your backwards compatibility requirements, CSS3 border-image property might be suitable.

See: http://www.w3.org/TR/css3-background/#border-images

They work in the latest versions of all browsers: http://caniuse.com/#search=border-image

Finally, here's a tool for playing with them: http://border-image.com/

Update:

As long as the background behind the image has a solid background, border-image can work. Just include an inner <div> with the sawtooth border.

HTML

<div class="image">
    <div class="sawtooth"></div>
</div>

CSS

BODY {
   background: black;
}

DIV.image {
   width: 480px;
   height: 325px;
   background: url(http://i.imgur.com/ux7a7pi.jpg);
}

DIV.sawtooth {
   width: 426px;
   height: 271px;
}

.sawtooth {
   border-style: solid;
   border-width: 27px;
   border-image: url(http://i.imgur.com/Usmr9yF.png) 27 round;
}

Demo here

查看更多
何必那么认真
3楼-- · 2019-02-13 02:32

Here is a possible solution. Use a diamond-shaped PNG and set it as multiple backgrounds within the container. You will have to figure out a way to scale the diamond so that it fills the edges properly (Perhaps use SASS?).

Set the diamond to repeat along the edges.

Here is a quick example: http://codepen.io/KurtWM/pen/tnzwj

enter image description here

And here is the SASS code for it. The #container is just a DIV:

$diamondImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNrs2MtNxDAQBuD82wCtQAfcKWEvUBlcKIH7drC0sh2QSOHAksSveXnGv2RZ9vHTyB57mgzl6ev8sIzJWGAJaJ4u6/L5+vJ5G0jbQI/r1rclKBgEmqxBwSiQKSgYBjIDBeNAJqDQAZA6FDoBUoVCR0BqUOgMSAUKHQKJQ6FTIFEodAwkBoXOgUSg4ACIHQpOgFih4AiIDQrOgFig4BCIHApOgUih4BiIDArOgUigEACoGQpBgJqgEAioGgrBgKqgEBCoGApBgYqgEBgoGwrBgbKgMIDSUBhAaSgMoDQUBlAaCgMoDXUaQLtZTC5LEZ1WsZGdaloq6fdMep+n12HyJx8z0Nv97TagNoC2+qQBdQe013FHhvoHdPR2iwi1CZT6BYgEtQt0iBQI6hAoiRQAKgmUheQYKgsoG8khVDZQEZIjqCKgYiQHUMVAVUgdQ1UBVSN1CFUN1ITUEVQTUDNSB1DNQCRIhqFIgMiQDEKRAZEiGYIiBSJHMgBFDsSCpAjFAsSGpADFBsSKJAjFCsSOJADFDiSCxAglAiSGxAAlBiSKRAglCiSORAAlDqSC1AClAqSGVAGlBqSKVAClCqSOlAGlDmQC6QDKBJAZpA0oM0DmskCtWKbyI8AAeriJOZujgcgAAAAASUVORK5CYII=);

#container {
  width: 400px;
  height: 300px;
  border: 8px solid #31b55b; // border matches the diamond color.
  background: 
    $diamondImage repeat-x -15px -15px, 
    $diamondImage repeat-x -15px 285px,  
    $diamondImage repeat-y 385px -15px,  
    $diamondImage repeat-y -15px -15px,
  url(http://placekitten.com/g/400/300) no-repeat;
  // Had to play with these numbers a bit to get a nice fit.
  background-size: 31px 31px, 31px 31px, 30px 30px, 30px 30px, 100% 100%;
}

// It may be possible to use calculations within SASS to set the diamond size, based on the picture dimensions. For example: if you know the size of the image, or the percentage that the image is to its parent, you should be able to calculate a balanced size for the diamonds so that they will fit the edges nicely.

In case you are not familiar with the way multiple backgrounds work; you separate the parameters by a comma. This is easiest if you use the background shorthand property. In the case of the background-size property, there is no place in the shorthand for those values, so we just need to make sure we also put in the multiple values separated by commas, making sure they are in the same order as the shorthand properties.

查看更多
迷人小祖宗
4楼-- · 2019-02-13 02:42

One can use mask-box-image in webkit browsers, which works similarly to border-image as following:

example of sawtooth border using SVG masks

Apply this to your desired element (see syntax):

-webkit-mask-box-image: url('./sawtooth.svg') 20 0 20 0 repeat;

Example SVG (could be smaller):

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   width="500"
   height="500"
   viewBox="0 0 500 500"
   preserveAspectRatio="none"
   version="1.1">
  <defs />
  <mask id="mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
  <path
         fill="#fff"
         d="M 0,0 0.02,0.02 0.04,0 0.06,0.02 0.08,0 0.1,0.02 0.12,0 0.14,0.02 0.16,0 0.18,0.02 0.2,0 l 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0.02,0.02 0.02,-0.02 0,1 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 -0.02,-0.02 -0.02,0.02 L 0.18,0.98 0.16,1 0.14,0.98 0.12,1 0.1,0.98 0.08,1 0.06,0.98 0.04,1 0.02,0.98 0,1 z" />
  </mask>
  <g>
    <path
       fill="#000"
       d="M 0,0 10,10 20,0 30,10 40,0 50,10 60,0 70,10 80,0 90,10 100,0 l 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 10,10 10,-10 0,500 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 -10,-10 -10,10 L 90,490 80,500 70,490 60,500 50,490 40,500 30,490 20,500 10,490 0,500 z" />
  </g>
</svg>

The following also works for Firefox with the provided SVG:

mask: url('./sawtooth.svg#mask'

Keep in mind however, that the mask path must be converted to relative values (0 to 1) and the mask must have “maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"” set. In my example, I divided all values in the path by 500, which is the original width of the path. It scales a bit and doesn't look as good as the webkit bit, but works well enough.

查看更多
Rolldiameter
5楼-- · 2019-02-13 02:47

You can do this in SVG with a mask, a clip-path or a filter. Here is an example using a Clip-path with relative sizing so it will work on content of any size.

enter image description here

<svg width="900" height="600" viewBox="0 0 900 600"
     xmlns="http://www.w3.org/2000/svg" version="1.1"
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <clipPath id="sawtoothClip" clipPathUnits="objectBoundingBox">
        <path d="M .00 0.025         
         l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  l -0.025 0.025   l 0.025 0.025  
         l 0.025 -0.025 l 0.025 0.025    l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025   l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025 l 0.025 0.025  l 0.025 -0.025   
         l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025  l -0.025 -0.025 l 0.025 -0.025              
         l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025  l -0.025 -0.025 l -0.025 0.025 
         z"
        />
      </clipPath>
    </defs>

   <image x="0" y="0" width="900" height="600"  preserveAspectRatio="none" clip-path="url(#sawtoothClip)"
     xlink:href="http://4hdwallpapers.com/wp-content/uploads/2013/05/Nature-Blue-Sky-Wallpaper.jpg"/>

</svg>

This works cross browser (IE9+): http://codepen.io/mullany/pen/eylzt

查看更多
叛逆
6楼-- · 2019-02-13 02:50

This is an old thread but if someone else needs to use a zigzag border I've a made a sass mixin for it.

// always use even numbers for size (or else you will get half pixel for height). Without 'px'. Only works with pixels
// don't add hash # for color

@mixin jagged($color: 000, $size: 16, $location: bottom, $type: fill, $side: outside, $animate: false) {
  $width: $size;
  $height: $width / 2;
  $scale: $width / 16;
  $rotate: '0';
  $pseudo: if($location == top or $location == left, before, after);

  @if $side == inside {
    @if $location == bottom {
      $rotate: "180 8 4";
    } @else if $location == left {
      $rotate: "270 8 8";
      $height: $size;
      $width: $size / 2;
    } @else if $location == right {
      $rotate: "90 4 4";
      $height: $size;
      $width: $size / 2;
    }
  } @else {
    @if $location == top {
      $rotate: "180 8 4";
    } @else if $location == right {
      $rotate: "270 8 8";
      $height: $size;
      $width: $size / 2;
    } @else if $location == left {
      $rotate: "90 4 4";
      $height: $size;
      $width: $size / 2;
    }
  }
  $arrow: "data:image/svg+xml,%3Csvg%20width%3D%22#{$width}px%22%20height%3D%22#{$height}px%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpolygon%20points%3D%220%2C%200%208%2C%208%2016%2C0%22%20fill%3D%22%23#{$color}%22%20transform%3D%22scale%28#{$scale}%29%20rotate%28#{$rotate}%29%22%3E%3C%2Fpolygon%3E%3C%2Fsvg%3E";
  $wave: "data:image/svg+xml,%3Csvg%20width%3D%22#{$width}px%22%20height%3D%22#{$height}px%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M8.00025863%2C0%20L0%2C6.59417725%20L0%2C8%20L8.00025885%2C1.40509033%20L16%2C8%20L16%2C6.59417725%20L8.00025863%2C0%20Z%22%20fill%3D%22%23#{$color}%22%20transform%3D%22scale%28#{$scale}%29%20rotate%28#{$rotate}%29%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E";
  position: relative;

  &:#{$pseudo} {
    content: '';
    position: absolute;
    z-index: 10;

    @if $animate {
      animation-duration: $animate;
      animation-name: if($location == bottom or $location == top, slide-hoz, slide-vet);
      animation-iteration-count: 1;
    }

    @if $location == top {
      height: #{$height}px;
      left: 0;
      right: 0;
      @if $side == inside {
        top: 0;
      } @else {
        top: -#{$height}px;
      }
    } @else if $location == right {
      width: #{$width}px;
      top: 0;
      bottom: 0;
      @if $side == inside {
        right: 0;
      } @else {
        right: -#{$width}px;
      }
    } @else if $location == bottom {
      height: #{$height}px;
      left: 0;
      right: 0;
      @if $side == inside {
        bottom: 0;
      } @else {
        bottom: -#{$height}px;
      }
    } @else if $location == left {
      width: #{$width}px;
      top: 0;
      bottom: 0;
      @if $side == inside {
        left: 0;
      } @else {
        left: -#{$width}px;
      }
    }

    @if $location == top {
      @if $side == inside {
        background-image: url($arrow);
      } @else {
        @if $type == fill {
          background-image: url($arrow);
        } @else {
          background-image: url($wave);
        }
      }

    } @else {
      @if $side == inside {
        background-image: url($arrow);
      } @else {
        @if $type == fill {
          background-image: url($arrow);
        } @else {
          background-image: url($wave);
        }
      }
    }
  }

  @keyframes slide-hoz {
    from {
      width: 0;
    }
    to {
      width: 100%;
    }
  }

  @keyframes slide-vet {
    from {
      height: 0;
    }
    to {
      height: 100%;
    }
  }
}

Working example: http://codepen.io/gilbarbara/pen/pvwmEb

查看更多
Root(大扎)
7楼-- · 2019-02-13 02:56

Here is one more, though imperfect, solution.

HTML

<div id="aux-container">
    <div id="test-area"></div>
</div>

CSS

#aux-container {
  background: -webkit-linear-gradient(top, #fd7465 0%,#cf0404 100%); width: 200px; height: 200px; overflow: hidden;
}

#test-area {
  background: -webkit-linear-gradient(top, #2d3576 0%,#818cdf 100%); width: 160px; height: 160px; margin: 20px;

  -webkit-clip-path: polygon(0 100%, 0px 0px, 20px 20px, 40px 0, 60px 20px, 80px 0, 100px 20px, 120px 0, 140px 20px, 160px 0, 160px 100%);
}

http://jsbin.com/emOKIgU/1/

The downside to this solution is that you need to know element height if it is a bottom border. Combined with JavaScript (to calculate element dimensions and update CSS), this works.

查看更多
登录 后发表回答