I am trying to build the following diagrams using CSS.
I have tried different methods, such as rotating borders, but everything I've tried does not lead to promising results.
What method can I use to build the following diagrams using CSS?
I'd say it would be easier for you to plot those diagrams using SVG (Scalar Vector Graphics). Here's an example of one of those diagrams I did for you to understand. You can put all of the SVG in a flexbox, CSS Grid, or table as you prefer.
<svg height="200" width="200">
<polyline points="20,20,60,60,20,100,60,60,120,60,160,20,120,60,160,100" style="fill:none;stroke:black;stroke-width:3" />
<text x="10" y="60" fill="gray">WBC</text>
<text x="80" y="50" fill="gray">HGB</text>
<text x="80" y="80" fill="gray">Hct</text>
<text x="140" y="60" fill="gray">Plt</text>
</svg>
What do the numbers mean?
The polyline provides with the functionality of drawing polygons by
making use of coordinates to move the cursor around with X and Y
co-ordinates while connecting the previous and the next coordinate.
The origin of a SVG diagram is by default at the top-left (x=0,y=0)
of your container. For this diagram, we took the initial position to
be (20,20) the first 2 coordinates in the polyline points
attribute. And then we move to (60,60) which connects the point
(20,20) to (60,60) making this:
<svg height="200" width="200">
<polyline points="20,20,60,60" style="fill:none;stroke:black;stroke-width:3" />
</svg>
Similarly, we move to (20,100) and remember to trace back, we use
(60,60) again as shown. Think of it as a pen point which can't be held
up and needs to move around while being on the sheet. The only
alternative is to trace back paths.
The style attribute style="fill:none;stroke:black;stroke-width:3"
let's you set the properties of the line which you are connecting. And
you can add text simply by using the text tag and mentioning the X
and Y coordinates` as demonstrated.
Try to tweak it around :) Hope,
it helps.
You can lookup and refer to more of this on here : https://www.w3schools.com/graphics/svg_intro.asp
Consider using HTML5 canvas to achieve this result.
Please see the following tutorial for a simple introduction: https://www.w3schools.com/html/html5_canvas.asp
The HTML5 canvas should allow you to display and manipulate both text and shapes, providing the tools needed to achieve the effect you're aiming for.
With pure CSS, you can create first-one using border and transform rotate on first and last elements and then rotate again span elements inside to return text to normal.
.el-1 {
display: flex;
}
.el-1 > div:first-child,
.el-1 > div:last-child {
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
transform: rotate(45deg);
}
.el-1 > div:first-child {
border-top: 1px solid black;
border-right: 1px solid black;
}
.el-1 > div:last-child {
border-bottom: 1px solid black;
border-left: 1px solid black;
}
.el-1 > div > span {
transform: rotate(-45deg);
display: block;
}
.inner {
width: 70px;
text-align: center;
line-height: 25px;
padding: 0 10px;
}
.inner > div:first-child {
border-bottom: 1px solid black;
}
<div class="el-1">
<div><span>A</span></div>
<div class="inner">
<div>B</div>
<div>C</div>
</div>
<div><span>D</span></div>
</div>
Related
I currently have a polygon with text inside shown below
.title {
clip-path: polygon(1% 0, 100% 15%, 96% 90%, 0 75%);
background-color: blue;
color: #FFF;
font-size: 1.7em;
line-height: 50px;
height: 60px;
width: 250px;
}
<h1 class="title"> WELCOME TO</h1>
I am looking for a more browser friendly version of this so I've been looking into using an SVG image. I'm struggling to nicely code this, as you see below I have the SVG shape, after a bit of testing, I quickly realised it doesn't scale well with the browser width. I would be happy if I could just keep it the same size all the time.
Then for the text after researching I learnt about the tag inside an tag, but even that I'm struggling to format the text.
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 7 9" version="1">
<polygon points=".1 0,5 .2,4.4 1.8,0 1.6" style="fill: #253234;" />
<text x="1" y="1" fill="white" style="font-family:arial; font-size:.4">WELCOME TO</text>
</svg>
Does anyone know of a better way of doing this, that works on major browsers and devices?
if i were you i would try to achieve the same effect with only css using rotation for the container, inverting the text rotation with the same amount, then using a pseudo element (:after) with absolute positioning to achieve the non rectangular shape effect.
run the snippet for an example that you can adjust to fit your needs.
.container {
transform:rotate(3deg);
display:inline-block;
position:relative;
top:50px;
padding:20px 30px 20px 20px;
background-color:blue;
}
.container:after {
content:'';
display:block;
background:white;
width:20px;
height:110%;
position:absolute;
top:0;
right:-10px;
transform:rotate(10deg);
}
.title {
color:#fff;
display:inline-block;
font-size:18pt;
text-transform:uppercase;
font-family:arial;
transform:rotate(-3deg)
}
<div class="container"><span class="title">Welcome to </span></div>
Since the first and second version you gave differ so much, I am not that sure what it is you want to achieve. I'm going mostly with the first one.
The main trick is with the way you use the viewBox attribute (and its accompaining preserveAspectRatio). Think of the viewBox as a rectangle that is fit into the area you define with width and height. (here, spelled out in CSS.) The preserveAspectRatio describes the fitting rule: choose the largest possible size for the rectangle that fits inside the element, and move it to the left and vertically to the middle.
Everything inside the <svg> now will remain fixed in position and proportion to that rectangle. If you raise the height of the element, the size of the text will grow; and if you lower its width, eventually it will shrink, but always together with the polygon.
I've positioned the text with text-anchor: middle, which is the equivalent of text-align: center for SVG. Using a font size of 0.4 as you did is not a good idea; browsers are prone to handle values below 1 incorrect.
Finally, if you are using this in place of a <h1> tag, you should either surround it with that to retain accessability, or set appropriate ARIA attributes as shown:
.title {
height: 60px;
width: 100%;
display: block; /* not needed if surrounded by <h1> */
}
.title polygon {
fill: blue;
}
.title text {
font-family: Arial;
font-size: 24px;
fill: #FFF;
text-anchor: middle;
}
<svg class="title" viewBox="0 0 250 60" preserveAspectRatio="xMinYMid meet"
aria-role="heading" aria-level="1">
<polygon points="2.5,0 250,9 240,54 0 45" />
<text x="125" y="36">WELCOME TO</text>
</svg>
Update
Thanks porneL for pointing out the relation between generated content and replaced elements.
I found this article which deals with this very topic:
Interestingly enough, a W3C document titled "CSS3 Generated and Replaced Content Module" (from 11 years ago!) defines the pseudo-element :outside, which could offer a solution to using generated content with replaced elements, by placing the generated content outside the replaced element, instead of trying to append it inside.
Original question
Is there a way to style an inline SVG element using the CSS :before and :after pseudo-elements?
Example: http://jsfiddle.net/wD56Q/
In this example, the styling defined with :before is not applied to the SVG (tested in Firefox 29 and Chrome 35).
Is it about the content property in :before? For what I read, it tries to insert a generated content in the element.. is it what fails with SVG?
Related documentation from MDN:
::before (:before)
::before creates a pseudo-element that is the first child of the
element matched. Often used to add cosmetic content to an element, by
using the content property. This element is inline by default.
content
The content CSS property is used with the ::before and ::after
pseudo-elements to generate content in an element. Objects inserted
using the content property are anonymous replaced elements.
The code in the example:
svg {
left: 50px;
position: absolute;
top: 50px;
}
svg circle {
fill: green;
}
svg:before {
border: 2px solid blue;
content: "";
height: 100px;
margin: -6px;
padding: 4px;
position: absolute;
width: 100px;
z-index: -1;
}
div {
background-color: green;
height: 100px;
left: 200px;
position: absolute;
top: 150px;
width: 100px;
}
div:before {
border: 2px solid blue;
content: "";
height: 100px;
margin: -6px;
padding: 4px;
position: absolute;
width: 100px;
z-index: -1;
}
<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" />
</svg>
<div></div>
No, inline SVG is treated as an image, and images are replaced elements which are not allowed to have generated content.
Strictly speaking, I think it's undefined. CSS 2.1 just talks about "images, embedded documents and applets" in general and The HTML standard defines it for images, but not SVG explicitly.
I have the following problem: I have to use an HTML->PDF conversion service to render a piece of HTML. However, this service is a bit limited in it's functionality, so I need a way to "work around" it.
I'm mainly just printing text, so it's not a big deal, but the only problem is that I have to print some "unticked" and some "ticked" check boxes, my converter is failing at this. In particular I've tried:
Using the unicode ☐ ("☐") and ☑ ("☑") characters, but the converter doesn't render them (probably the font it's using doesn't
have them)
Using the WingDing characters þ and ¨ but again, the wingding font is not recognized
The converter doesn't support images, so can't just use an image
I was thinking, at this point, to "simulate" a checkbox by using spans with borders, something like:
<span style="border: 1px solid black; height: 12px; width: 12px;"></span>
However, I can't make it look correct (no fault of the converter this time, even browsers show the above as just one vertival line.
Can anyone help me "draw" checkboxes using just "basic" html elements? What would be the cleanest way?
PS: checkboxes need to be inline with the text.
You're on the right track.
Using HTML and CSS:
/* The standalone checkbox square*/
.checkbox {
width:20px;
height:20px;
border: 1px solid #000;
display: inline-block;
}
/* This is what simulates a checkmark icon */
.checkbox.checked:after {
content: '';
display: block;
width: 4px;
height: 7px;
/* "Center" the checkmark */
position:relative;
top:4px;
left:7px;
border: solid #000;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
<div class="checkbox"></div> Unchecked<br><br>
<div class="checkbox checked"></div> Checked
The reason YOUR code didn't work was because you were using a span element, which is an inline element. You can use a span for this, but you'll need to add the style of display: block to the element (making it act as a block element instead of an inline element).
The div tag is a block, so no need for setting it's display style. If you would like the div to display inline, set the display: inline-block
Try this :
<div style="border: 1px solid black;
width: 10px;
height: 10px;
display: inline-block;
margin-right: 4px;">
</div>
https://jsfiddle.net/8rt4dqfc/
I've a trapezoid shapes in CSS, but the problem is that I also need the same kind of trapezoid turning the borders opposite, the first trapezoid css is something like this:
#trapezoid1 {
height: 0;
width: 350px;
border-bottom: 190px solid rgb(2, 145, 178);
border-left: 45px solid transparent;
border-right: 45px solid transparent;
padding: 0 8px 0 0;
display:block;
position:relative;
}
But I also need the second trapezoid turning the border-bottom to border-top, however in that case, the text is being flew away from the actual trapezoid.
I did border-top instead of border-bottom to turn the trapezoid opposite.
Here's the full display of the problem.. jsfiddle
Your best option is to use pseudo elements so you dont have to use absolute positioning on the text element.
Using both :before and :after will help create the desired shape. The borders are also transparent so you don't have to worry about background images being coloured over.
#trapezoid {
width: 260px;
height: 190px;
background: red;
margin-left: 45px;
position: relative;
}
#trapezoid:before {
content: '';
border-right: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
left: -45px;
top: 0;
}
#trapezoid:after {
content: '';
border-left: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
right: -45px;
top: 0;
}
<div id="trapezoid">
Text in here
</div>
You can also refer to one of my previews answers which give a good overview at all of the different possible ways of creating a CSS trapezoid.
Responsive CSS Trapezoid Shape
How about this:
HTML (add span tags around trap2 text)
<div id="trapezoid1">
Designing Something
</div>
<br/>
<div id="trapezoid2">
<span id="trap2-text">Designing Opposite</span><!-- NEW -->
<!-- I need the text in proper place which currently isn't -->
</div>
CSS (add one rule)
#trap2-text {
position: absolute;
top: -190px;
left: -25px;
}
DEMO
I generally like pure css shapes, but I thought SVG might make your life easier in this case so I started fiddling around with your fiddle. I'm not completely satisfied with the results but it gives some advantage like dynamic size.
Fiddle with comments: http://jsfiddle.net/bo5k36pa/8/
If you want to use this solution I highly recommend to encode your inline svgs in base64 to avoid compability and encoding problems. See this answer for details.
Explanation
The idea was to use an inline svg as background image, so it will stretch to containers of any size.
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 2" preserveAspectRatio="none"><path style="fill: rgb(2, 145, 178);" d="M 0.5 0 L 3.5 0 L 4 2 L 0 2 Z" /></svg>');
background-size: 100%;
The path that makes up the trapez could be modified, if different angles or shapes are required, it could even be generated dynamically using javascript. But the real bummer here is, we can't style inline svg background images. Meaning for example to change just the fill color we have to define the entire svg markup again.
Possible solutions to avoid multiple inline svgs
Use <use>. You can define <symbols> in an external svg file and reference them in an inline <svg> via their id attributes. And we can still style those symbols using CSS. However, it would require a fair amount of extra markup in every container. Something like this:
<svg viewBox="0 0 4 2" role="img" title="Trapez"><use xlink:href="path/to/images/shapes.svg#trapez"></use></svg>
Use CSS filters to change appearance. Example fiddle / Browser Support
Go back to CSS Shapes. I'd recommend to take advantage of :before and :after pseudo elements to keep such fancy appendages a bit separate from your content box.
I'm using Adobe Dreamweaver CS5 and I added a swap behavior to an image in an html document. Basically, the swap property is supposed to pop up at its original size and restore on mouse out. The problem I'm facing is that the image swapped fills the screen. I've tried adding width: px and height: px properties to the img src string but that didn't work either. Here's the snippet:
<div class="caption lft glow2" data-x="600" data-y="615" data-speed="600" data-start="200" data-easing="easeOutExpo"><img src="img/glow.png" onMouseOver="MM_swapImage('Image1','','img/intro-1.jpg',1)" width="131" height="124" onMouseOut="MM_swapImgRestore()"></div>
and here's the css:
.caption.glow2 {
position: absolute;
padding: 6px 10px;
margin: 0px;
border-width: 0px;
border-style: none;
background: transparent;
opacity: 5;
Please help
Solved! I made a rollover instead. Thank you!