简体   繁体   中英

Custom shaped block

I need to create such element for the webpage:

在此输入图像描述

As you see, 3 corners are rounded and 1 corner is slanted. The border will need to change during different states of the block. There also will be a photo background underneath this element.

All the CSS and JS solutions out there for this are ugly and cumbersome.

My idea is: Can we use an svg element to draw this shape and then be able to manipulate border colors as needed later on with js?

There is this svg element with rounded corners:

<svg width="400" height="180">
  <rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5">
  Sorry, your browser does not support inline SVG.
</svg>

That draws this:

在此输入图像描述

My question is: Can we make one of the corners slanted in this svg and then place content in it? Maybe via feeding this svg as background of the element.

I tried recreating the shape in css. As you said it's somewhat unsatisfying and fiddly but i'll share it anyway.

This will only work on modern browsers though.

 .box{ border:5px solid orange; background-color:#eee; width:100px; height:100px; padding:30px; border-radius:20px; position:relative; } .box::after{ content:''; position:absolute; top: -23px; left: -25px; width:40px; height:40px; border-right:5px solid orange; background:#fff; transform:rotate(45deg); } 
 <div class="box">Content</div> 

You can manipulate an SVG with JavaScript, but it will also respond to CSS changes.

If you have an SVG with id mysvg and a path element with id myborder , you can define a style for the border path:

#mysvg #myborder {
    stroke: orange;
}

You can manipulate the SVG directly, or define styles like normal. The easiest thing to do is to manipulate a wrapper div class. This is because manipulating HTML styles is easier than SVG and plays nicer with standard JS and JS libraries:

<div id="myshape">
    <svg id="mysvg" height="600" width="400">
        <path id="myborder" d="..." stroke="blue" stroke-width="5">
    </svg>
    <div id="content">Content</div>
</div>

Then you can have these classes:

#myshape #mysvg #myborder {
    stroke: blue;
}

#myshape.hilite #mysvg #myborder {
    stroke: orange;
}

Simply modifying the parent class will update your SVG. Add/remove class hilite to the parent div in this case to change the border color.

Example: http://jsfiddle.net/jtbowden/ssrker2h/2/

The JS is not necessary for the change, but I am using it to modify the class. This could just as easily be done with a hover attribute, etc.

CSS only example:

 #content { padding: 50px; position: absolute; top: 25px; left: 25px; font-size: 42px; font-family: Arial; font-weight: bold; } #myshape:hover #myborder { stroke: orange; } 
 <div id="myshape"> <svg id="shape" height="600" width="420"> <defs> <pattern id="mybackgnd" patternUnits="userSpaceOnUse" width="400" height="590"> <image xlink:href="http://placekitten.com/g/400/590" x="0" y="0" width="400" height="590" opacity="0.5" /> </pattern> </defs> <path id="myborder" d="M 20 60 l 40 -40 l 320 0 c 10 0 20 10 20 20 l 0 500 c 0 10 -10 20 -20 20 l -340 0 c -10 0 -20 -10 -20 -20 z" stroke="blue" stroke-width="5" fill="url(#mybackgnd)" />Sorry, your browser does not support inline SVG.</svg> <div id="content">Hover Me</div> </div> 

No javascript html/CSS only 在此输入图像描述

To make the shape you want you need to use polygon not rect:

I have tested this and the following works:

 .foo { position:relative; top:25px; left:215px; float:left; } 
  <hr>Just to prove adding content moves move svg an its content down<hr><hr> <div class="foo">my text and stuff <br><img src="http://blog.spoongraphics.co.uk/wp-content/uploads/2014/low-poly/tiger-poly-lg.jpg" height="100px"></div> <svg width="400" height="400"> <polygon points="50 250,400 250,400 7,108 4,53 62" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"> </polygon> Sorry, your browser does not support inline SVG. </svg> 

  1. If you link the SVG with CSS I think it's not possible to manipulate it's style with JS, but if you include the SVG in HTML you will be able to do so.

  2. It's possible to make the slanted corner using SVG <path> tag , it's really complex to make the desired shape by hand, so I suggest you to use a vector graphics editor tool , to create the shape and export as SVG. I recommend CorelDraw or Adobe Illustrator, if you have one of them or Inkscape, that is free

A css solution:

  1. draw div with rounded borders
  2. add :before to place border colored triangle over top corner
  3. add :after to place slightly smaller background colored triangle over :before triangle

 #card { height: 400px; width: 200px; border: 3px solid blue; border-radius: 10px; background-color: tan; position: relative; } #card:before { content:""; height:0; width: 0; position: absolute; top:-3px; left:-3px; border-top: 35px solid blue; border-right: 35px solid transparent; } #card:after { content: ""; height: 0; width: 0; position: absolute; top: -3px; left: -3px; border-top: 30px solid white; border-right: 30px solid transparent; } 
 <div id="card"></div> 

For an svg, you can draw the box using a path:

 <svg height="155" width="155"> <path style="opacity:0.5;stroke:#000000;stroke-width:5;fill:#ff0000;" d="M42.7,2.5,2.5,42.7,2.5,132c0,11.1,8.92,20,20,20h110c11.1,0,20-8.92,20-20v-110c0-11.1-8.92-20-20-20h-89.8z"/> </svg> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM