J'ai un bloc, avec une certaine conception:

enter image description here

Et j'ai du code svg:

.box {
	position: relative;
	margin: .75em auto 0;
	max-width: 255px;
	min-height: 56px;
}

svg {
	position: absolute;
	width: 100%; height: 100%;
}
<div class='box'>
	<svg>
		<mask id='m' fill='#fff'>
			<rect id='r' width='256' height='56'/>
			<circle id='c' r='10' fill='#000'/>
			<use xlink:href='#c' x='100%'/>
			<use xlink:href='#c' y='100%'/>
			<use xlink:href='#c' x='100%' y='100%'/>
		</mask>
		
		<mask id='m2' fill='#fff'>
			<rect id='r2' width='248' height='50' x="4" y="4" />
			<circle id='c2' r='14' fill='#000' stroke='#000'/>
			<use xlink:href='#c2' x='100%' />
			<use xlink:href='#c2' y='100%'/>
			<use xlink:href='#c2' x='100%' y='100%'/>
		</mask>
		
		<use xlink:href='#r' fill='red' mask='url(#m)'/>
		<use xlink:href='#r2' fill='none' stroke="#000" mask='url(#m2)'/>
	</svg>
</div>

Question: comment faire l'intérieur d'un bloc avec les mêmes coins coupés arrondis, mais pas avec un remplissage et un contour pleins?

P.S: il devrait rester la possibilité de modifier le rayon des coins arrondis, les retraits vn. blocs. Peut-être qu'il existe une implémentation simple sur css (maximum cross-browser), conviendrait également.

2
HamSter 20 nov. 2018 à 15:09

3 réponses

Meilleure réponse

Que dis-tu de ça? Cela devrait fonctionner pour n'importe quelle taille en changeant simplement les dimensions de <div class="box">.

.box {
	position: relative;
	margin: .75em auto 0;
	width: 255px;
	height: 56px;
}

.box svg {
	position: absolute;
	width: 100%;
  height: 100%;
}

.size2 {
	width: 455px;
	height: 256px;
}
<div class="box">
  <svg width="100%" height="100%">
    <mask id="m" fill="#fff">
      <rect width="100%" height="100%"/>

      <rect width="100%" height="100%" fill="none" stroke="#000" stroke-width="12"/>
      <circle r="16" fill="#000"/>
      <circle cx="100%" r="16" fill="#000"/>
      <circle cy="100%" r="16" fill="#000"/>
      <circle cx="100%" cy="100%" r="16" fill="#000"/>

      <rect width="100%" height="100%" fill="none" stroke="#fff" stroke-width="8"/>
      <circle r="14" fill="#fff"/>
      <circle cx="100%" r="14" fill="#fff"/>
      <circle cy="100%" r="14" fill="#fff"/>
      <circle cx="100%" cy="100%" r="14" fill="#fff"/>

      <circle r="10" fill="#000"/>
      <circle cx="100%" r="10" fill="#000"/>
      <circle cy="100%" r="10" fill="#000"/>
      <circle cx="100%" cy="100%" r="10" fill="#000"/>
    </mask>
		
    <rect width="100%" height="100%" mask="url(#m)"/>
  </svg>
</div>
4
Paul LeBeau 20 nov. 2018 à 13:44

Voici ma réponse: j'utilise la taille de la zone de délimitation du texte pour que vous puissiez modifier le texte comme vous le souhaitez. Pour les coins découpés, j'utilise des arcs. Vous pouvez également modifier le «remplissage», c'est-à-dire la distance entre le texte et la bordure.

let bb = txt.getBBox();


function drawShape(path, padding){
let d = `M${bb.x},${bb.y - padding}
         L${bb.x + bb.width},${bb.y - padding}
A${padding}, ${padding} 0 0 0 ${bb.x + bb.width + padding},${bb.y}
         L${bb.x + bb.width + padding},${bb.y + bb.height}
A${padding}, ${padding} 0 0 0 ${bb.x + bb.width},${bb.y + bb.height + padding}
         L${bb.x},${bb.y + bb.height + padding}
A${padding}, ${padding} 0 0 0 ${bb.x  - padding},${bb.y + bb.height}
         L${bb.x  - padding},${bb.y}
A${padding}, ${padding} 0 0 0 ${bb.x},${bb.y - padding}z
`
path.setAttributeNS(null,"d",d)
}
drawShape(pth, 10);
drawShape(pth1, 10);
<svg viewBox="0 0 200 100">
  <path id="pth" fill="black" stroke="black" stroke-width="4" d="" />
  <path id="pth1" stroke="white" stroke-width="2" d="" />
  <text id="txt" fill="white" dominant-baseline="central" text-anchor="middle" x="100" y="50">
    some text inside
  </text>
  </svg>
2
enxaneta 20 nov. 2018 à 14:42

J'irais avec une solution CSS pure utilisant plusieurs arrière-plans. C'est un peu astucieux à manipuler, mais en utilisant une variable CSS, vous pouvez le rendre facile à ajuster:

.box {
  --th:2px; /*thickness of the transparent part*/
  --l:4px; /*height of border*/
  --r:25px; /*radius*/
  
  
  --rad:transparent calc(103% - var(--th) - var(--l) - 1px), 
         #000 calc(103% - var(--th) - var(--l))  
              calc(103% - var(--th) - 1px),
         transparent calc(103% - var(--th)) 103%,
         #000 103%;
  --rad-s:var(--r) var(--r);
  --border:#000 calc(var(--l)),transparent calc(var(--l)),transparent calc(var(--l) + var(--th));
  --w:calc(100% - 2*var(--r) + 2*var(--th));
  --h:calc(var(--l) + var(--th));
  margin:10px;
  display:inline-block;
  padding:40px 20px;
  background:
    /*The 4 borders*/
    linear-gradient(to bottom,var(--border)) top   /var(--w) var(--h),
    linear-gradient(to top   ,var(--border)) bottom/var(--w) var(--h),
    linear-gradient(to right ,var(--border)) left  /var(--h) var(--w),
    linear-gradient(to left  ,var(--border)) right /var(--h) var(--w),
    /*The 4 corners */
    radial-gradient(farthest-side at top    right,var(--rad)) top    right/var(--rad-s),
    radial-gradient(farthest-side at top    left ,var(--rad)) top    left /var(--rad-s),
    radial-gradient(farthest-side at bottom right,var(--rad)) bottom right/var(--rad-s),
    radial-gradient(farthest-side at bottom left ,var(--rad)) bottom left /var(--rad-s),
    /*The main background*/
    linear-gradient(#000,#000) center/calc(100% - 2*var(--r)) calc(100% - 2*var(--h)),
    linear-gradient(#000,#000) center/calc(100% - 2*var(--h)) calc(100% - 2*var(--r));
    
 background-repeat:no-repeat;
 
 color:#fff;
 text-align:center;
}

body {
 background:pink;
}
<div class="box">
  Some text inside
</div>

<div class="box" style="--th:3px;--r:20px">
  Some text inside
</div>

<div class="box" style="--th:4px;--r:40px;--l:8px">
  Some text inside
</div>

<div class="box" style="--th:5px;--r:30px">
  Some text inside
</div>

<div class="box" style="--th:1px;--r:15px;--l:3px">
  Some text inside
</div>

CSS transparent inner border

4
Temani Afif 13 avril 2020 à 08:17