ge

The influence of active agent motility on SIRS epidemiological dynamics

Soft Matter, 2024, Advance Article
DOI: 10.1039/D4SM00864B, Paper
Open Access
R. Kailasham, Aditya S. Khair
Motility induced phase separation of active disks with SIRS epidemiological dynamics.
To cite this article before page numbers are assigned, use the DOI form of citation above.
The content of this RSS Feed (c) The Royal Society of Chemistry




ge

Self-consistent electrostatic formalism of bulk electrolytes based on the asymmetric treatment of the short- and long-range ion interactions

Soft Matter, 2024, Advance Article
DOI: 10.1039/D4SM01174K, Paper
Sahin Buyukdagli
Internal energy of monovalent electrolytes (left) and dimensionless screening parameter of multivalent electrolytes (right).
To cite this article before page numbers are assigned, use the DOI form of citation above.
The content of this RSS Feed (c) The Royal Society of Chemistry




ge

A generalized model for predicting different morphologies of bacterial swarming on a porous solid surface

Soft Matter, 2024, Accepted Manuscript
DOI: 10.1039/D4SM01072H, Paper
Uttam Kumar, Pushpavanam Subramaniam
In this study, we develop a comprehensive two-phase model to analyze the dynamics of bacterial swarming on porous substrates. The two distinct phases under consideration are the cell and aqueous...
The content of this RSS Feed (c) The Royal Society of Chemistry




ge

It’s Time to Get Personal

Laura Kalbag discusses the gift of personal data we give to Big Tech when we share information on its platforms, and how reviving ye olde personal website can be one way to stay in control of the content we share and the data we leak. Christmas is a time for giving, but know what you’re giving to whom.


Is it just me or does nobody have their own website anymore? OK, some people do. But a lot of these sites are outdated, or just a list of links to profiles on big tech platforms. Despite being people who build websites, who love to share on the web, we don’t share much on our own sites.

Of course there are good reasons people don’t have their own websites. For one, having your own site is something of a privilege. Understanding hosting packages, hooking up a domain name, and writing a basic HTML page are not considered the most difficult challenges for a web designer or developer – but they often require intimidating choices, and the ability to wield that knowledge with confidence tends to come with repeated experience.

Buying a domain and renting web hosting doesn’t cost much, but it does cost money, and not everyone can afford that as an ongoing commitment. Building and maintaining a site also takes time. Usually time nobody else is going to pay you for doing the work. Time you could be be spending making the money you need to pay the bills, or time you could be spending with your family and friends.

A personal website also creates personal pressure. Pressure to have things worth sharing. Pressure to be cool and interesting enough for a personal site. Pressure to have a flashy design, or a witty design, or the cleverest and cleanest code. Pressure to keep the site updated, not look like you lost interest, or stopped existing after your site was last updated in 2016.

We are sharing

Most of us share loads of expressive and personal stuff with each other: status updates, photos, videos, code snippets, articles and tutorials. Some people only do these things in social contexts, like those who live on Instagram. Some only in workplace contexts, like the performative professionalism of LinkedIn. And plenty of people mix the two together, like those of us who mix dog photos and tech news on Twitter.

Many of us find sharing what we learn, and learning from each other, to be one of the few joys of working in the web community. One of the reasons web design and development as practices are accessible to people regardless of their background is because of those who believe sharing back is a fundamental element of community. A lot of us taught ourselves how to design and code because of those who shared before us. Our work often depends on free and open frameworks and packages. Our practices evolve at a rapid rate because we share what we’ve learned, our successes and our failures, to benefit others who are working towards the same goals.

But we’re sharing on other people’s platforms

Big Tech has given us a load of social platforms, and the content we’ve shared on those platforms has made them valuable. These platforms are designed to make it easy and convenient to share our thoughts and feelings. And they don’t cost us any money. The social nature of the platforms also make us feel validated. One button press for a like, a love, a star, a share, and we feel appreciated and connected. And it’s all for free. Except it isn’t.

It’s not news anymore that the vast majority of the web is funded by extracting and monetising people’s personal information. Shoshana Zuboff coined the term “surveillance capitalism” to describe this model. Aral Balkan calls it “people farming.” Essentially it means when we are not paying for mainstream tech with money, we are paying for it with our privacy. And sometimes we can pay for tech with money and still have our privacy eroded. (I call this the “have-your-cake-and-eat-it-too model” or the “Spotify model”.)

Many—usually cis, white, heterosexual—people in the tech industry believe that this “privacy tradeoff” is worthwhile. While they have a financial incentive in the continuation of this model, and are not necessarily the worst harmed when their privacy is weakened, their privilege has made them short-sighted. There are many people who are harmed by a model that reinforces stereotypes, discriminates against race, gender and disability, and shares vulnerable people’s information with exploitative corporations and authoritarian governments.

We’re not just making decisions about our own privacy, either. By using a script that sends site visitor information back to somebody else’s server, we’re making our visitors vulnerable. By using an email provider that extracts personal information from our emails, we’re making our contacts vulnerable. By uploading photos of our friends and families to platforms that create facial recognition databases, we’re making our loved ones vulnerable.

Making technology that respects the rights of the people using it isn’t a fun responsibility to take on. It’s also a challenging exercise to weigh our convenience and privilege against exposing other people to harm when life feels difficult already. But we can’t sit back and expect other people/overseers/charities/ombudsmen/deities to fix our communities or industries for us. We’ve got to do some of the work, pay some of the costs, and take responsibility for ourselves. Especially if we are people who can afford it or have the time. We can’t keep prioritising our conveniences over the safety of other people.

One small way to get our independence and agency back from exploitative platforms is to build personal websites to share on instead. Of course, it’s a tiny tiny step. But it’s a step to taking back control, and building a web that neither relies upon, nor feeds, the harms of Big Tech.

Personal websites give us independence and agency

Personal doesn’t have to mean individualistic. Your website might be your own blog, portfolio or hobby project, but it could also be for your community, local team or cause. It could be all about a person, or anonymous. You could use it to showcase other people’s work that you appreciate, such as links to articles you’ve found valuable.

A website doesn’t have to be a fancy work of art that’ll be written up in a hundred publications, a website is just an HTML page. You can even add some CSS if you want to show off.

A home (or an office)

When people ask where to find you on the web, what do you tell them? Your personal website can be your home on the web. Or, if you don’t like to share your personal life in public, it can be more like your office. As with your home or your office, you can make it work for your own needs. Do you need a place that’s great for socialising, or somewhere to present your work? Without the constraints of somebody else’s platform, you get to choose what works for you.

Miriam Suzanne’s site is an example of bringing together a variety of work from different disciplines in one feed with loads of personality.

Your priorities

For a long time, I’ve been giving talks about being conscious of the impacts of our work. But when I talk about the principles of small technology or the ethical design manifesto, people often tell me how impossible it is take a stand against harmful practices at their job.

Personal sites give you the freedom to practice the design and development you care about, without the constraints of your boss’s bad business model or your manager’s questionable priorities. We can create accessible and inclusive sites that don’t exploit our visitors. We can experiment and play to work out what really matters to us. If we don’t like our personal site, we can start again from scratch, iterate, change, keep working to make it better.

I asked on Twitter for examples of great personal websites, and Mel Choyce recommended Susan Lin’s incredible site which demonstrates how a personal site can show personality and a stunning aesthetic while also covering the professional stuff.

Your choice of design

Your own personal website means you choose the design. Rather than sharing on a blogging platform like Medium, we can make our design reflect our content and our principles. We don’t need to have ads, paywalls or article limits imposed on us.

When people ask me for examples of beautiful accessible and inclusive websites, I often point them in the direction of Tatiana Mac’s site – a striking and unique design that couldn’t be further from the generic templates offered up by platforms.

No tracking

It does rather defeat the point of having a personal website, if you then hook it up to all the tracking mechanisms of Big Tech. Google Analytics? No thanks. Twitter follow button? I’d rather not. Facebook Like button? You must be joking. One of the benefits of having your own personal site is that you can make your personal site a tracking-free haven for your site’s visitors. All the personal websites I’ve shared here are tracking-free. Trust me, it’s not easy to find websites that value their visitors like this!

One brilliant example of this is Karolina Szczur’s (also gorgeous) site which even includes a little “No tracking” bit of copy in the footer where other sites would often include a privacy policy detailing all the tracking they do.

Staying connected

A personal website doesn’t mean an antisocial website. Charlie Owen’s site comprises a feed of her notes, checkins, likes, replies, reposts and quotes, along with her longer-form posts and talks.

If you want to go hardcore, you can even run your own social platform instance. I have my own Mastodon instance, where I can post and socialise with other people in the “fediverse,” all from the comfort and control of my own domain.

Freedom from the popularity contest (and much of the harassment)

There’s value to being sociable, but one of the perks of having your own personal site is freedom from follower counts, likes, claps, and other popularity contests that reduce your self-expressions into impressions. It’s nice to know when people like your work, or find it valuable, but the competition created from chasing impressive numbers results in unequal power structures, clickbait, and marginalised people having their work appropriated without credit. A personal site means your work can still be shared but is also more likely to stay in that location, at the same URL, for much longer. You also get the final say over who can comment on your work in your own space. Wave goodbye to the trolls, they can go mutter to themselves under their own bridges.

Your choice of code

As I mentioned earlier, your website doesn’t have to be anything more than an HTML page. (Just think how fast that would load!) With your own personal site, you get to choose what code you want to write (or not write) and which frameworks you want to use (or not use).

As an individual or a small group, you don’t need to worry about scale, or accommodating as many users as possible. You can choose what works for you, even what you find fun. So I thought I’d share with you the whats and whys of my own personal site setup.

Your choice of setup

I use iwantmyname to buy domain names and Greenhost for web hosting. (Greenhost kindly provides Small Technology Foundation with free hosting, as part of their Eclipsis hosting for “Internet freedom, liberation technology developers, administrators and digital rights activists.” You don’t get many benefits in this line of work, so I treasure Greenhost’s/Open Technology Fund’s kindness.)

My blog has ten years’ worth of posts, so I rely on a content management system (CMS) to keep me organised, and help me write new posts with as little fuss as possible. Two years ago, I moved from WordPress to Hugo, a static site generator. Hugo is fine. I wrote my own theme for Hugo because I can, and also because I value accessible HTML and CSS. The setup works well for a personal site.

Now my website is just a self-hosted static site, it’s noticeably faster. Importantly, I feel I have more ownership and control over my own site. The only third-party service my site needs is my web host. As it’s “serverless”, my site also doesn’t have the security risks associated with a server-side CMS/database.

Nowadays, static sites and JAMstack (JavaScript, APIs, Markup -stack) are ultra trendy. While static sites have the aforementioned benefits, I worry about the APIs bit in the JAMstack. With static site generators, we (can, if we want) take out a number of the privacy, security and performance concerns of serverside development, only to plug them all back in with APIs. Every time we use a third-party API for critical functionality, we become dependent on it. We add weakness in the deployment process because we rely on their uptime and performance, but we also become reliant on the organisations behind the API. Are they a big tech platform? What are we paying for their service? What do they get out of it? Does it compromise the privacy and security of our site’s visitors? Are we lending our loyalty to an organisation that causes harm, or provides infrastructure to entities that cause harm?

For all we speak of interoperability and standards, we know we’re unlikely to move away from a shady service, because it’s too deeply embedded in our organisational processes and/or developer conveniences. What if we don’t create that dependent relationship in the first place?

It’s why I use Site.js. Site.js is a small tech, free and open, alternative to web frameworks and tools of Big Tech. I use Site.js to run my own secure (Site.js provides automatic trusted TLS for localhost) development and production servers, and rapidly sync my site between them. It has no dependence on third-parties, no tracking, and comes as a single lightweight binary. It only took one line in the terminal to install it locally, and the same line to install it on my production server. I didn’t need to buy, bolt on or configure an SSL certificate. Site.js took care of it all.

In development, I use Site.js with Hugo to run my site on localhost. To test across devices, I run it on my hostname with ngrok (a tunnelling app) to expose my development machine.

My site running locally with Site.js and Hugo.

Site.js also provides me with ephemeral statistics, not analytics. I know what’s popular, what’s 404ing, and the referrer, but my site’s visitors are not tracked. The stats themselves are accessible from a cryptographically secure URL (no login required) so I could share this URL with whoever I wanted.

Stats for my site since my server was last restarted on the 27th of November. My site is most popular when people are requesting it via… RSS. I’m not sharing the URL with you because I’m embarrassed that I still haven’t sorted my web fonts out, or made an alias for the /feed URL. I’m not having you check up on me…

For those who want the dynamic functionality often afforded by third-party APIs, Site.js enables you to layer your own dynamic functionality on top of static functionality. We did this for Small Technology Foundation’s fund page. We wanted our patrons to be able to fund us without us relying on a big tech crowdfunding platform (and all the tracking that comes along with it). Aral integrated Stripe’s custom checkout functionality on top of our static site so we could have security for our patrons without relinquishing all our control over to a third party. You can even build a little chat app with Site.js.

Every decision has an impact

As designers and developers, it’s easy to accept the status quo. The big tech platforms already exist and are easy to use. There are so many decisions to be made as part of our work, we tend to just go with what’s popular and convenient. But those little decisions can have a big impact, especially on the people using what we build.

But all is not yet lost. We can still build alternatives and work towards technology that values human welfare over corporate profit. We’ve got to take control back bit by bit, and building our own personal websites is a start.

So go on, get going! Have you already got your own website already? Fabulous! Is there anything you can do to make it easier for those who don’t have their own sites yet? Could you help a person move their site away from a big platform? Could you write a tutorial or script that provides guidance and reassurance? Could you gift a person a domain name or hosting for a year?

Your own personal site might be a personal thing, but a community and culture of personal sites could make a significant difference.


About the author

Laura Kalbag is a British designer living in Ireland, and author of Accessibility For Everyone from A Book Apart. She’s one third of Small Technology Foundation, a tiny two-person-and-one-husky not-for-profit organisation. At Small Technology Foundation, Laura works on a web privacy tool called Better Blocker, and initiatives to advocate for and build small technology to protect personhood and democracy in the digital network age.

More articles by Laura




ge

Building a Dictaphone Using Media Recorder and getUserMedia

Chris Mills brushes up his shorthand and shows how the MediaStream Recording API in modern browsers can be used to capture audio directly from the user’s device. Inching ever closer to the capabilities of native software, it truly is an exciting time to be a web developer.


The MediaStream Recording API makes it easy to record audio and/or video streams. When used with MediaDevices.getUserMedia(), it provides an easy way to record media from the user’s input devices and instantly use the result in web apps. This article shows how to use these technologies to create a fun dictaphone app.

A sample application: Web Dictaphone

To demonstrate basic usage of the MediaRecorder API, we have built a web-based dictaphone. It allows you to record snippets of audio and then play them back. It even gives you a visualisation of your device’s sound input, using the Web Audio API. We’ll just concentrate on the recording and playback functionality in this article, for brevity’s sake.

You can see this demo running live, or grab the source code on GitHub. This has pretty good support on modern desktop browsers, but pretty patchy support on mobile browsers currently.

Basic app setup

To grab the media stream we want to capture, we use getUserMedia(). We then use the MediaRecorder API to record the stream, and output each recorded snippet into the source of a generated <audio> element so it can be played back.

We’ll first declare some variables for the record and stop buttons, and the <article> that will contain the generated audio players:

const record = document.querySelector('.record');
const stop = document.querySelector('.stop');
const soundClips = document.querySelector('.sound-clips');

Next, we set up the basic getUserMedia structure:

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
   console.log('getUserMedia supported.');
   navigator.mediaDevices.getUserMedia (
      // constraints - only audio needed for this app
      {
         audio: true
      })

      // Success callback
      .then(function(stream) {

      })

      // Error callback
      .catch(function(err) {
         console.log('The following `getUserMedia` error occured: ' + err);
      }
   );
} else {
   console.log('getUserMedia not supported on your browser!');
}

The whole thing is wrapped in a test that checks whether getUserMedia is supported before running anything else. Next, we call getUserMedia() and inside it define:

  • The constraints: Only audio is to be captured for our dictaphone.
  • The success callback: This code is run once the getUserMedia call has been completed successfully.
  • The error/failure callback: The code is run if the getUserMedia call fails for whatever reason.

Note: All of the code below is found inside the getUserMedia success callback in the finished version.

Capturing the media stream

Once getUserMedia has created a media stream successfully, you create a new Media Recorder instance with the MediaRecorder() constructor and pass it the stream directly. This is your entry point into using the MediaRecorder API — the stream is now ready to be captured into a <Blob>, in the default encoding format of your browser.

const mediaRecorder = new MediaRecorder(stream);

There are a series of methods available in the MediaRecorder interface that allow you to control recording of the media stream; in Web Dictaphone we just make use of two, and listen to some events. First of all, MediaRecorder.start() is used to start recording the stream once the record button is pressed:

record.onclick = function() {
  mediaRecorder.start();
  console.log(mediaRecorder.state);
  console.log("recorder started");
  record.style.background = "red";
  record.style.color = "black";
}

When the MediaRecorder is recording, the MediaRecorder.state property will return a value of “recording”.

As recording progresses, we need to collect the audio data. We register an event handler to do this using mediaRecorder.ondataavailable:

let chunks = [];

mediaRecorder.ondataavailable = function(e) {
  chunks.push(e.data);
}

Last, we use the MediaRecorder.stop() method to stop the recording when the stop button is pressed, and finalize the Blob ready for use somewhere else in our application.

stop.onclick = function() {
  mediaRecorder.stop();
  console.log(mediaRecorder.state);
  console.log("recorder stopped");
  record.style.background = "";
  record.style.color = "";
}

Note that the recording may also stop naturally if the media stream ends (e.g. if you were grabbing a song track and the track ended, or the user stopped sharing their microphone).

Grabbing and using the blob

When recording has stopped, the state property returns a value of “inactive”, and a stop event is fired. We register an event handler for this using mediaRecorder.onstop, and construct our blob there from all the chunks we have received:

mediaRecorder.onstop = function(e) {
  console.log("recorder stopped");

  const clipName = prompt('Enter a name for your sound clip');

  const clipContainer = document.createElement('article');
  const clipLabel = document.createElement('p');
  const audio = document.createElement('audio');
  const deleteButton = document.createElement('button');

  clipContainer.classList.add('clip');
  audio.setAttribute('controls', '');
  deleteButton.innerHTML = "Delete";
  clipLabel.innerHTML = clipName;

  clipContainer.appendChild(audio);
  clipContainer.appendChild(clipLabel);
  clipContainer.appendChild(deleteButton);
  soundClips.appendChild(clipContainer);

  const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
  chunks = [];
  const audioURL = window.URL.createObjectURL(blob);
  audio.src = audioURL;

  deleteButton.onclick = function(e) {
    let evtTgt = e.target;
    evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
  }
}

Let’s go through the above code and look at what’s happening.

First, we display a prompt asking the user to name their clip.

Next, we create an HTML structure like the following, inserting it into our clip container, which is an <article> element.

<article class="clip">
  <audio controls></audio>
  <p>_your clip name_</p>
  <button>Delete</button>
</article>

After that, we create a combined Blob out of the recorded audio chunks, and create an object URL pointing to it, using window.URL.createObjectURL(blob). We then set the value of the <audio> element’s src attribute to the object URL, so that when the play button is pressed on the audio player, it will play the Blob.

Finally, we set an onclick handler on the delete button to be a function that deletes the whole clip HTML structure.

So that’s basically it — we have a rough and ready dictaphone. Have fun recording those Christmas jingles! As a reminder, you can find the source code, and see it running live, on the MDN GitHub.


This article is based on Using the MediaStream Recording API by Mozilla Contributors, and is licensed under CC-BY-SA 2.5.


About the author

Chris Mills manages the MDN web docs writers’ team at Mozilla, which involves spreadsheets, meetings, writing docs and demos about open web technologies, and occasional tech talks at conferences and universities. He used to work for Opera and W3C, and enjoys playing heavy metal drums and drinking good beer.

More articles by Chris




ge

Flexible Captioned Slanted Images

Eric Meyer gift wraps the most awkwardly shaped of boxes using nothing but CSS, HTML and a little curl of ribbon. No matter how well you plan and how much paper you have at your disposal, sometimes you just need to slant the gift to the side.


We have a lot of new layout tools at our disposal these days—flexbox is finally stable and interoperable, and Grid very much the same, with both technologies having well over 90% support coverage. In that light, we might think there’s no place for old tricks like negative margins, but I recently discovered otherwise.

Over at An Event Apart, we’ve been updating some of our landing pages, and our designer thought it would be interesting to have slanted images of speakers at the tops of pages. The end result looks like this.

The interesting part is the images. I wanted to set up a structure like the following, so that it will be easy to change speakers from time to time while preserving accessible content structures:

<div id="page-top">
  <ul class="monoliths">
    <li>
      <a href="https://aneventapart.com/speakers/rachel-andrew"> 
        <img src="/img/rachel-andrew.jpg" alt=""> 
        <div> 
          <strong>Rachel Andrew</strong> CSS Grid 
        </div> 
      </a>
    </li>
    <li>
      <a href="https://aneventapart.com/speakers/derek-featherstone"> 
        <img src="/img/derek-featherstone.jpg" alt=""> 
        <div> 
          <strong>Derek Featherstone</strong> Accessibility 
        </div> 
      </a>
    </li>
    <li>
      …
    </li>
    <li>
      …
    </li>
  </ul>
</div>

The id value for the div is straightforward enough, and I called the ul element monoliths because it reminded me of the memorial monoliths at the entrance to EPCOT in Florida. I’m also taking advantage of the now-ubiquitous ability to wrap multiple elements, including block elements, in a hyperlink. That way I can shove the image and text structures in there, and make the entire image and text below it one link.

Structure is easy, though. Can we make that layout fully responsive? I wondered. Yes we can. Here’s the target layout, stripped of the navbar and promo copy.

So let’s start from the beginning. The div gets some color and text styling, and the monoliths list is set to flex. The images are in a single line, after all, and I want them to be flexible for responsive reasons, so flexbox is 100% the right tool for this particular job.

#page-top { 
  background: #000; 
  color: #FFF; 
  line-height: 1; 
} 
#page-top .monoliths { 
  display: flex; 
  padding-bottom: 1em; 
  overflow: hidden; 
}

I also figured, let’s give the images a simple basis for sizing, and set up the hyperlink while we’re at it.

#page-top .monoliths li { 
  width: 25%; 
} 
#page-top .monoliths a { 
  color: inherit; 
  text-decoration: inherit; 
  display: block; 
  padding: 1px; 
}

So now the list items are 25% wide—I can say that because I know there will be four of them—and the links pick up the foreground color from their parent element. They’re also set to generate a block box.

At this point, I could concentrate on the images. They need to be as wide as their parent element, but no wider, and also match height. While I was at it, I figured I’d create a little bit of space above and below the captioning text, and make the strong elements containing speakers’ names generate a block box.

#page-top .monoliths img { 
  display: block; 
  height: 33rem; 
  width: 100%; 
} 
#page-top .monoliths div { 
  padding: 0.5em 0; 
} 
#page-top .monoliths strong { 
  display: block; 
  font-weight: 900; 
}

It looks like the speakers were all cast into the Phantom Zone or something, so that needs to be fixed. I can’t physically crop the images to be the “correct” size, because there is no correct size: this needs to work across all screen widths. So rather than try to swap carefully-sized images in and out at various breakpoints, or complicate the structure with a wrapper element set to suppress overflow of resized images, I turned to object-fit.

#page-top .monoliths img { 
  display: block; 
  height: 33rem; 
  width: 100%; 
  object-fit: cover; 
  object-position: 50% 20%; 
}

If you’ve never used object-fit, it’s a bit like background-size. You can use it to resize image content within the image’s element box without creating distortions. Here, I set the fit sizing to cover, which means all of the img element’s element box will be covered by image content. In this case, it’s like zooming in on the image content. I also set a zooming origin with object-position, figuring that 50% across and 20% down would be in the vicinity of a speaker’s face, given the way pictures of people are usually taken.

This is fairly presentable as-is—a little basic, perhaps, but it would be fine to layer the navbar and promo copy back over it with Grid or whatever, and call it a day. But it’s too square and boxy. We must go further!

To make that happen, I’m going to take out the third and fourth images temporarily, so we can see more clearly how the next part works. That will leave us with Rachel and Derek.

The idea here is to clip the images to be slanted, and then pull them close to each other so they have just a little space between them. The first part is managed with clip-path, but we don’t want to pull the images together unless their shapes are being clipped. So we set up a feature query.

@supports (clip-path: polygon(0 0)) or (-webkit-clip-path: polygon(0 0)) { 
  #page-top .monoliths li { 
    width: 37.5%; 
  } 
}

I decided to test for both the un-prefixed and WebKit-prefixed versions of clip-path because Safari still requires the prefix, and I couldn’t think of a good reason to penalize Safari’s users for the slowness of its standards advancement. Then I made the images wider, taking them from 25% to 37.5%, which makes them half again as wide.

Thanks to object fitting, the images don’t distort when I change their parent’s width; they just get wider and scale up the contents to fit. And now, it is time for clipping!

@supports (clip-path: polygon(0 0)) or (-webkit-clip-path: polygon(0 0)) { 
  #page-top .monoliths li { 
    width: 37.5%; 
    -webkit-clip-path: polygon(25% 0, 100% 0, 75% 100%, 0 100%); 
    clip-path: polygon(25% 0, 100% 0, 75% 100%, 0 100%); 
  } 
}

Each coordinate pair in the polygon() is like the position pairs in background-position or object-position: the horizontal distance first, followed by the vertical distance. So the first point in the polygon is 25% 0, which is 25% of the way across the element box, and no distance down, so right at the top edge. 100% 0 is the top right corner. 75% 100% is on the bottom edge, three-quarters of the way across the element, and 0 100% is the bottom left corner. That creates a polygon that’s a strip three-quarters the full width of the element box, and runs from bottom left to top right.

Now we just have to pull them together, and this is where old tricks come back into play: all we need is a negative right margin to bring them closer together.

#page-top .monoliths li { 
  width: 37.5%; 
  margin-right: -7.5%; 
  -webkit-clip-path: polygon(25% 0, 100% 0, 75% 100%, 0 100%); 
  clip-path: polygon(25% 0, 100% 0, 75% 100%, 0 100%); 
}

The separation between them is a little wider than we were originally aiming for, but let’s see what happens when we add the other two images back in and let flexbox do its resizing magic.

Notice how the slants actually change shape as the screen gets narrower or wider. This is because they’re still three-quarters the width of the image element’s box, but the width of that box is changing as the screen width changes. That means at narrow widths, the slant is much steeper, whereas at wide widths, the slant is more shallow. But since the clipping path’s coordinates were all set with percentage distances, they all stay parallel to each other while being completely responsive to changes in screen size. An absolute measure like pixels would have failed.

But how did the images get closer together just by adding in two more? Because the list items’ basic sizing added up to more than 100%, and they’re all set to flex-shrink: 1. No, you didn’t miss a line in the CSS: 1 is the default value for flex-shrink. Flex items will shrink by default, which after all is what we should expect from a flexible element. If you want to know how much they shrunk, and why, here’s what Firefox’s flex inspector reports.

When there were only two list items, there was space enough for both to be at their base size, with no shrinkage. Once we went to four list items, there wasn’t enough space, so they all shrank down. At that point, having a negative right margin of -7.5% was just right to pull them together to act as a unit.

So, now they’re all nicely nestled together, and fully responsive! The captions need a little work, though. Notice how they’re clipped off a bit on the left edge, and can be very much clipped off on the right side at narrower screen widths? This happens because the li elements are being clipped, and that clipping applies to all their contents, images and text alike. And we can’t use overflow to alter this: clipped is clipped, not overflowed.

Fortunately, all we really need to do is push the text over a small amount. Inside the feature query, I added:

#page-top .monoliths div { 
  padding-left: 2%;
  padding-right: 26%; 
}

This shifts the text just a bit rightward, enough to clear the clip path. On the right side, I padded the div boxes so their contents wouldn’t fall outside the clipped area and appear to slide under the next caption. We could also use margins here, but I didn’t for reasons I’ll make clear at the end.

At the last minute, I decided to make the text at least appear to follow the slants of the images. For that, I just needed to shift the first line over a bit, which I did with a bit more padding.

#page-top .monoliths strong { 
  padding-left: 1%; 
}

That’s all to the good, but you may have noticed the captions still overlap at really narrow screen widths. There are a lot of options here, from stacking the images atop one another to reverting to normal flow, but I decided to just hide the captions if things got too narrow. It reduces clutter without sacrificing too much in the way of content, and by leaving them still technically visible, they seem to remain accessible.

@media (max-width: 35rem) { 
  #page-top .monoliths div { 
    opacity: 0.01 
  } 
}

And that, as they say, is that! Fully responsive slanted images with text, in an accessible markup structure. I dig it.

I did fiddle around with the separations a bit, and found that a nice thin separator occurred around margin-right: -8%, whereas beefier ones could be found above -7%. And if you crank the negative margin value to something beyond -8%, you’ll make the images overlap entirely, no visible separation—which can be a useful effect in its own right.

I promised to say why I used padding for the caption text div rather than margins. Here’s why.

#page-top .monoliths div { 
  padding-left: 3%; 
  padding-right: 26%; 
  border-top: 2px solid transparent; 
  background: linear-gradient(100deg,hsl(292deg,50%,50%) 50%, transparent 85%); 
  background-clip: padding-box; 
}

It required a wee bit more padding on the left to look decent, and an alteration to the background clipping box in order to keep the purple from filling the transparent border area, but the end result is pretty nifty, if I do say so myself. Alternatively, we could drop the background gradient on the captions and put one in the background, with a result like this.

I have no doubt this technique could be extended, made more powerful, and generally improved upon. I really wished for subgrid support in Chrome, so that I could put everything on a grid without having to tear the markup structure apart, and there are doubtless even more interesting clipping paths and layout patterns to try out.

I hope these few ideas spark some much better ideas in you, and that you’ll share them with us!


About the author

Eric A. Meyer (@meyerweb) has been a burger flipper, a college webmaster, an early blogger, one of the original CSS Samurai, a member of the CSS Working Group, a consultant and trainer, and a Standards Evangelist for Netscape. Among other things, Eric co-wrote Design For Real Life with Sara Wachter-Boettcher for A Book Apart and CSS: The Definitive Guide with Estelle Weyl for O’Reilly, created the first official W3C test suite, assisted in the creation of microformats, and co-founded An Event Apart with Jeffrey Zeldman. Eric lives with his family in Cleveland, Ohio, which is a much nicer city than you’ve probably heard. He enjoys a good meal whenever he can and considers almost every form of music to be worthwhile.

More articles by Eric




ge

Usability and Security; Better Together

Divya Sasidharan calls into question the trade-offs often made between security and usability. Does a secure interface by necessity need to be hard to use? Or is it the choice we make based on years of habit? Snow has fallen, snow on snow.


Security is often synonymous with poor usability. We assume that in order for something to be secure, it needs to by default appear impenetrable to disincentivize potential bad actors. While this premise is true in many instances like in the security of a bank, it relies on a fundamental assumption: that there is no room for choice.

With the option to choose, a user almost inevitably picks a more usable system or adapts how they interact with it regardless of how insecure it may be. In the context of the web, passwords are a prime example of such behavior. Though passwords were implemented as a way to drastically reduce the risk of attack, they proved to be marginally effective. In the name of convenience, complex, more secure passwords were shirked in favor of easy to remember ones, and passwords were liberally reused across accounts. This example clearly illustrates that usability and security are not mutually exclusive. Rather, security depends on usability, and it is imperative to get user buy-in in order to properly secure our applications.

Security and Usability; a tale of broken trust

At its core, security is about fostering trust. In addition to protecting user accounts from malicious attacks, security protocols provide users with the peace of mind that their accounts and personal information is safe. Ironically, that peace of mind is incumbent on users using the security protocols in the first place, which further relies on them accepting that security is needed. With the increased frequency of cyber security threats and data breaches over the last couple of years, users have grown to be less trusting of security experts and their measures. Security experts have equally become less trusting of users, and see them as the “the weakest link in the chain”. This has led to more cumbersome security practices such as mandatory 2FA and constant re-login flows which bottlenecks users from accomplishing essential tasks. Because of this break down in trust, there is a natural inclination to shortcut security altogether.

Build a culture of trust not fear

Building trust among users requires empowering them to believe that their individual actions have a larger impact on the security of the overall organization. If a user understands that their behavior can put critical resources of an organization at risk, they will more likely behave with security in mind. For this to work, nuance is key. Deeming that every resource needs a similarly high number of checks and balances diminishes how users perceive security and adds unnecessary bottlenecks to user workflows.

In order to lay the foundation for good security, it’s worth noting that risk analysis is the bedrock of security design. Instead of blindly implementing standard security measures recommended by the experts, a better approach is to tailor security protocols to meet specific use cases and adapt as much as possible to user workflows. Here are some examples of how to do just that:

Risk based authentication

Risk based authentication is a powerful way to perform a holistic assessment of the threats facing an organization. Risks occur at the intersection of vulnerability and threat. A high risk account is vulnerable and faces the very real threat of a potential breach. Generally, risk based authentication is about calculating a risk score associated with accounts and determining the proper approach to securing it. It takes into account a combination of the likelihood that that risk will materialize and the impact on the organization should the risk come to pass. With this system, an organization can easily adapt access to resources depending on how critical they are to the business; for instance, internal documentation may not warrant 2FA, while accessing business and financial records may.

Dynamically adaptive auth

Similar to risk based auth, dynamically adaptive auth adjusts to the current situation. Security can be strengthened and slackened as warranted, depending on how risky the access point is. A user accessing an account from a trusted device in a known location may be deemed low risk and therefore not in need of extra security layers. Likewise, a user exhibiting predictive patterns of use should be granted quick and easy access to resources. The ability to adapt authentication based on the most recent security profile of a user significantly improves the experience by reducing unnecessary friction.

Conclusion

Historically, security failed to take the user experience into account, putting the onus of securing accounts solely on users. Considering the fate of password security, we can neither rely on users nor stringent security mechanisms to keep our accounts safe. Instead, we should aim for security measures that give users the freedom to bypass them as needed while still protecting our accounts from attack. The fate of secure systems lies in the understanding that security is a process that must constantly adapt to face the shifting landscape of user behavior and potential threats.


About the author

Divya is a web developer who is passionate about open source and the web. She is currently a developer experience engineer at Netlify, and believes that there is a better workflow for building and deploying sites that doesn’t require a server—ask her about the JAMstack. You will most likely find her in the sunniest spot in the room with a cup of tea in hand.

More articles by Divya




ge

Fashion gets ready to pop up

Pop-up stores might offer the perfect retail therapy, fusing style and surprise, but we still have a lot of catching up to do with the West, curators tell us.




ge

Geneva Watch Days 2022: screening for ‘flippers’

At the third edition of the trade fair, top CEOs talk about discouraging speculators and getting their ‘in demand’ beauties on the wrists of real watch lovers



  • Life &amp; Style

ge

Sahodaran’s 2023 calendar highlights India’s textile heritage

It was the effort of four photographers, 14 models, and three stylists, and was shot at four locations



  • Life &amp; Style

ge

Mahila Praharis of the BSF Camel Contingent will make their Republic Day parade debut in uniform designed by Raghavendra Rathore

The designer also incorporated various skills from across the country and it took him three months to complete the uniform



  • Life &amp; Style

ge

On a world stage: Inside the Nita Mukesh Ambani Cultural Centre in Mumbai

A massive, multi-disciplinary cultural space is now open in Mumbai, with a global outlook and a vision to foster and promote Indian arts




ge

From techno-inspired rave bags to pants that depict neurons, this Chennai-based gender neutral fashion label’s creations are conversation starters

Brimming with cut outs, panels, thread piping and embroidery, Biskit’s new collection explores the human mind



  • Life &amp; Style

ge

Objectifying gender is not ‘jest’




ge

Why do I feel judged?




ge

Don’t forget your water bottle

Why staying hydrated in summer is important for every aspect of your health




ge

Get set go for health

It’s time to bring out those running shoes; Pinkathon is back again




ge

Gear up for that fitness routine

Sheela Nambiar stresses on the importance of exercise to change the course of your life.




ge

The summer shape-up challenge

Experts share cool tips for a hot weather workout.




ge

A surge in fest and feast

It is that time of the year when one binges on sweets and food. But, is that healthy? Read on and find out




ge

Ready... get set... run

If you want to be fit without investing much in terms of equipments or gear, then give running a shot




ge

Editorial. Gold users must get a transparent Re-based price

There is a need to provide consumers with a transparently derived domestic reference rate which is under regulatory supervision




ge

Editorial. Rail Budget’s capex boost welcome, but concerns remain

The Railways must attract higher freight volumes, even as it positions itself as a high end passenger travel option




ge

Editorial. MPC could have changed stance to neutral

A change in stance now would have made it possible for a rate cut later this calendar year, if the growth impulse turned weak




ge

Editorial. E-commerce bogey, again

Clarity on regulatory, policy environment needed




ge

Editorial. Incentives for vehicle scrappage need to be better

The 2021 scheme spoke of a 5 per cent discount by OEMs which has now been cut sharply, with caveats that it would be applicable only on select models, and for one or two years




ge

Editorial. Generation gap

Vatsalya should not replicate all NPS features




ge

Editorial. Agri Stack can be transformative, but implementation will be a challenge

Land records remain contested, despite over 90 per cent digitisation. Concerns over data theft and cyber fraud cannot be disregarded




ge

Editorial. Advantage consumer

Quick commerce is hardly anti-competitive




ge

Yes Bank Q2 Results: Net profit surges 145% year-on-year to ₹553 crore, with NII rising 14%

Yes Bank’s standalone net profit more than doubled to ₹5.53 billion for the financial second quarter from ₹2.25 billion in the same period a year earlier



  • Money &amp; Banking

ge

Cholamandalam MS General Insurance H1 Results: PBT jumps 60% to ₹350 crore

Chola MS reports an 11.6% Y-o-Y rise in GWP to ₹4,136 crore in H1 FY25; MD V Suryanarayanan says focus on profitable growth continues to drive performance



  • Money &amp; Banking

ge

Indian Bank posts 36% rise in Q2 net at ₹2,707 crore on the back of reduced slippages

For the first half of the fiscal, the bank’s net profit exceeded ₹5,000 crore, totalling ₹5,110 crore, up from ₹3,697 crore



  • Money &amp; Banking

ge

Bank unions push back against government ‘micromanagement’ in employee performance reviews

More than 1 lakh bank employees likely to be affected by DFS instruction to banks, says AIBEA General Secretary Venkatachalam



  • Money &amp; Banking

ge

SBI appoints Debasish Mishra as Chief General Manager of its New Delhi Circle

Debasish Mishra has experience across Credit, Operations, Forex, IT, HR, and MSME sectors, both in India and overseas



  • Money &amp; Banking

ge

For new players, existing expense of management regulations are a challenge: Zuno General Insurance CEO

Zuno General Insurance continued to grow faster than the industry in the second quarter of this fiscal, says Shanai Ghosh, MD & CEO of the company



  • Money &amp; Banking

ge

Banks’ NIM falls in Q2 as RBI penal charge diktat takes effect, deposit cost rises

Bankers expect pressure on NIM to continue in Q3



  • Money &amp; Banking

ge

JC Flowers ARC seeks bids to sell ₹2,613 crore of bad loans via Swiss challenge mode

The NPAs on block were part of YES Bank’s legacy bad loan portfolio.



  • Money &amp; Banking

ge

Bandhan Group enters IT services with the acquisition of Genisys Group

Genisys Group’s service spans digital application lifecycle management, cloud native solutions, data management, digital media operations and business process outsourcing



  • Money &amp; Banking

ge

Shriram General Insurance posts 17% rise in Q2 net at ₹140 cr

Shriram General’s Gross Written Premium rose by 15% to ₹861 crore during the same period.



  • Money &amp; Banking

ge

Change in stance doesn’t mean that the next step is a rate cut in the very next meeting: RBI Guv Das

RBI Governor Das explains change in stance, emphasizes balanced growth-inflation approach



  • Money &amp; Banking

ge

Large MFIs see sharp rise in NPAs, lower profit in Q2

Bankers are expecting another muted earnings quarter in Q3, and better business performance from Q4 onwards



  • Money &amp; Banking

ge

Ashes of Doom / directed by: Grant Munro, Don Arioli ; produced by: Robert Verrall, Wolf Koenig ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2008




ge

The Circle / directed by: Mort Ransen ; produced by: John Kemeny ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2020




ge

Monkey on the Back / directed by: Julian Biggs ; produced by: Grant McLean ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2016




ge

Eye Witness No. 74 / directed by: Jack Long, William Davidson ; produced by: Jack Olsen, Nicholas Balla ; production agency: National Film Board of Canada (Ottawa)

Montreal : National Film Board of Canada, 2024




ge

Beyond Kicks / directed by: Gary Toole ; produced by: Michael McKennirey, George Pearson ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2021




ge

Still Longshots / directed by: David Finch, Maureen Marovitch ; produced by: Dan Emery, David Finch, Germaine Ying Gee Wong, Sally Bochner, Ravida Din ; production agencies: Picture This Productions (Montreal), National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2018




ge

Bevel Up - Drugs, Users and Outreach Nursing / directed by: Nettie Wild ; produced by: Fiona Gold, Juanita Maginley, Betsy Carson, Nettie Wild, Svend-Erik Eriksen, Rina Fraticelli ; production agencies: National Film Board of Canada (Montreal), British Co

Montreal : National Film Board of Canada, 2016




ge

The Moccasin Game / directed by: Frank Corcoran ; produced by: Dennis Sawyer ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2019




ge

Turnaround : A Story of Recovery / directed by: Moira Simpson ; produced by: Jennifer Torrance, Moira Simpson, John Taylor, Kathleen Shannon ; production agency: National Film Board of Canada (Montreal)

Montreal : National Film Board of Canada, 2017